diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Src/builtin.c | 35 | ||||
-rw-r--r-- | Test/B01cd.ztst | 19 |
3 files changed, 40 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog index b76d1988e..fa1c74563 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2020-07-03 Matthew Martin <phy1729@gmail.com> + + * 46168: Src/builtin.c, Test/B01cd.ztst: Update $PWD and call + chpwd hook after normalizing path. + 2020-07-03 Daniel Shahaf <d.s@daniel.shahaf.name> * unposted (cf. users/24972, users/24978): Doc/Zsh/expn.yo: diff --git a/Src/builtin.c b/Src/builtin.c index 770930579..ff84ce936 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -841,7 +841,6 @@ int bin_cd(char *nam, char **argv, Options ops, int func) { LinkNode dir; - struct stat st1, st2; if (isset(RESTRICTED)) { zwarnnam(nam, "restricted"); @@ -860,23 +859,6 @@ bin_cd(char *nam, char **argv, Options ops, int func) } cd_new_pwd(func, dir, OPT_ISSET(ops, 'q')); - if (stat(unmeta(pwd), &st1) < 0) { - setjobpwd(); - zsfree(pwd); - pwd = NULL; - pwd = metafy(zgetcwd(), -1, META_DUP); - } else if (stat(".", &st2) < 0) { - if (chdir(unmeta(pwd)) < 0) - zwarn("unable to chdir(%s): %e", pwd, errno); - } else if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) { - if (chasinglinks) { - setjobpwd(); - zsfree(pwd); - pwd = NULL; - pwd = metafy(zgetcwd(), -1, META_DUP); - } else if (chdir(unmeta(pwd)) < 0) - zwarn("unable to chdir(%s): %e", pwd, errno); - } unqueue_signals(); return 0; } @@ -1210,6 +1192,7 @@ static void cd_new_pwd(int func, LinkNode dir, int quiet) { char *new_pwd, *s; + struct stat st1, st2; int dirstacksize; if (func == BIN_PUSHD) @@ -1239,6 +1222,22 @@ cd_new_pwd(int func, LinkNode dir, int quiet) } } + if (stat(unmeta(new_pwd), &st1) < 0) { + zsfree(new_pwd); + new_pwd = NULL; + new_pwd = metafy(zgetcwd(), -1, META_DUP); + } else if (stat(".", &st2) < 0) { + if (chdir(unmeta(new_pwd)) < 0) + zwarn("unable to chdir(%s): %e", new_pwd, errno); + } else if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) { + if (chasinglinks) { + zsfree(new_pwd); + new_pwd = NULL; + new_pwd = metafy(zgetcwd(), -1, META_DUP); + } else if (chdir(unmeta(new_pwd)) < 0) + zwarn("unable to chdir(%s): %e", new_pwd, errno); + } + /* shift around the pwd variables, to make oldpwd and pwd relate to the current (i.e. new) pwd */ zsfree(oldpwd); diff --git a/Test/B01cd.ztst b/Test/B01cd.ztst index 21e751dcb..bc6757549 100644 --- a/Test/B01cd.ztst +++ b/Test/B01cd.ztst @@ -33,7 +33,7 @@ # # Tests should use subdirectories ending in `.tmp'. These will be # removed with all the contents even if the test is aborted. - mkdir cdtst.tmp cdtst.tmp/real cdtst.tmp/sub + mkdir cdtst.tmp cdtst.tmp/foo cdtst.tmp/real cdtst.tmp/sub ln -s ../real cdtst.tmp/sub/fake @@ -149,6 +149,23 @@ F:something is broken. But you already knew that. -f:(workers/45367) cd -P squashes multiple leading slashes >/dev + chpwd_hook() { hook_pwd=$PWD; } + chpwd_functions=(chpwd_hook) + cd $mydir/cdtst.tmp/foo && + (cd $mydir && mv $mydir/cdtst.tmp/{foo,bar}) && + print $PWD && + print $hook_pwd && + cd . && + print $PWD && + print $hook_pwd + chpwd_functions=() + unfunction chpwd_hook +0q:cd . with moved PWD +>$mydir/cdtst.tmp/foo +>$mydir/cdtst.tmp/foo +>$mydir/cdtst.tmp/bar +>$mydir/cdtst.tmp/bar + %clean # This optional section cleans up after the test, if necessary, # e.g. killing processes etc. This is in addition to the removal of *.tmp |