summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/params.c2
-rw-r--r--Src/subst.c13
-rw-r--r--Src/utils.c14
3 files changed, 22 insertions, 7 deletions
diff --git a/Src/params.c b/Src/params.c
index 0eda7848f..842b2f0d1 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -4336,7 +4336,7 @@ void
homesetfn(UNUSED(Param pm), char *x)
{
zsfree(home);
- if (x && isset(CHASELINKS) && (home = xsymlink(x)))
+ if (x && isset(CHASELINKS) && (home = xsymlink(x, 0)))
zsfree(x);
else
home = x ? x : ztrdup("");
diff --git a/Src/subst.c b/Src/subst.c
index c61551bf6..15eb59b64 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -4081,6 +4081,7 @@ modify(char **str, char **ptr)
case 'u':
case 'q':
case 'Q':
+ case 'P':
c = **ptr;
break;
@@ -4287,6 +4288,12 @@ modify(char **str, char **ptr)
untokenize(copy);
}
break;
+ case 'P':
+ if (*copy != '/') {
+ copy = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", copy);
+ }
+ copy = xsymlink(copy, 1);
+ break;
}
tc = *tt;
*tt = '\0';
@@ -4363,6 +4370,12 @@ modify(char **str, char **ptr)
untokenize(*str);
}
break;
+ case 'P':
+ if (**str != '/') {
+ *str = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", *str);
+ }
+ *str = xsymlink(*str, 1);
+ break;
}
}
if (rec < 0) {
diff --git a/Src/utils.c b/Src/utils.c
index 0a5954f65..45fd19286 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -801,9 +801,9 @@ findpwd(char *s)
char *t;
if (*s == '/')
- return xsymlink(s);
+ return xsymlink(s, 0);
s = tricat((pwd[1]) ? pwd : "", "/", s);
- t = xsymlink(s);
+ t = xsymlink(s, 0);
zsfree(s);
return t;
}
@@ -969,11 +969,13 @@ xsymlinks(char *s, int full)
/*
* expand symlinks in s, and remove other weird things:
* note that this always expands symlinks.
+ *
+ * 'heap' indicates whether to malloc() or allocate on the heap.
*/
/**/
char *
-xsymlink(char *s)
+xsymlink(char *s, int heap)
{
if (*s != '/')
return NULL;
@@ -981,8 +983,8 @@ xsymlink(char *s)
if (xsymlinks(s + 1, 1) < 0)
zwarn("path expansion failed, using root directory");
if (!*xbuf)
- return ztrdup("/");
- return ztrdup(xbuf);
+ return heap ? dupstring("/") : ztrdup("/");
+ return heap ? dupstring(xbuf) : ztrdup(xbuf);
}
/**/
@@ -1260,7 +1262,7 @@ getnameddir(char *name)
/* Retrieve an entry from the password table/database for this user. */
struct passwd *pw;
if ((pw = getpwnam(name))) {
- char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir)
+ char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir, 0)
: ztrdup(pw->pw_dir);
if (dir) {
adduserdir(name, dir, ND_USERNAME, 1);