* cd does not update $PWD in a timely fashion. @ 2020-06-26 17:24 Han Boetes 2020-06-26 17:32 ` Matthew Martin 0 siblings, 1 reply; 5+ messages in thread From: Han Boetes @ 2020-06-26 17:24 UTC (permalink / raw) To: zsh-workers [-- Attachment #1: Type: text/plain, Size: 823 bytes --] I had this program changing the name of the current working directory and noticed cd .; echo $PWD didn't pick up the changes. The following code replicates the problem. % set -x;mkdir foo; cd foo; mv ~/foo ~/bar; echo $PWD;pwd; readlink -f .; cd .; echo $PWD ;pwd; readlink -f .; cd .; echo $PWD ;pwd; readlink -f . +/bin/zsh:8> mkdir foo +/bin/zsh:8> cd foo +/bin/zsh:8> mv -i /home/han/foo /home/han/bar +/bin/zsh:8> echo /home/han/foo /home/han/foo +/bin/zsh:8> pwd /home/han/foo +/bin/zsh:8> readlink -f . /home/han/bar +/bin/zsh:8> cd . +/bin/zsh:8> echo /home/han/foo /home/han/foo +/bin/zsh:8> pwd /home/han/bar +/bin/zsh:8> readlink -f . /home/han/bar +/bin/zsh:8> cd . +/bin/zsh:8> echo /home/han/bar /home/han/bar +/bin/zsh:8> pwd /home/han/bar +/bin/zsh:8> readlink -f . /home/han/bar With kind regards, Han ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: cd does not update $PWD in a timely fashion. 2020-06-26 17:24 cd does not update $PWD in a timely fashion Han Boetes @ 2020-06-26 17:32 ` Matthew Martin 2020-06-27 7:25 ` Matthew Martin 0 siblings, 1 reply; 5+ messages in thread From: Matthew Martin @ 2020-06-26 17:32 UTC (permalink / raw) To: zsh-workers On Fri, Jun 26, 2020 at 07:24:21PM +0200, Han Boetes wrote: > I had this program changing the name of the current working directory and > noticed cd .; echo $PWD didn't pick up the changes. Was first discussed in IRC, so I had a head start on the patch. bin_cd may update pwd after calling cd_new_pwd which calls set_pwd_env. Since bin_cd is the only caller of cd_new_pwd, I think it's safe to move that code into cd_new_pwd prior to the oldpwd, pwd, new_pwd shift. This should also call the chpwd hook with the right value. Seems to fix the issue locally. I know Daniel will rightfully ask for a new test, so I'll work on that tonight. 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); ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: cd does not update $PWD in a timely fashion. 2020-06-26 17:32 ` Matthew Martin @ 2020-06-27 7:25 ` Matthew Martin 2020-06-27 20:42 ` Daniel Shahaf 0 siblings, 1 reply; 5+ messages in thread From: Matthew Martin @ 2020-06-27 7:25 UTC (permalink / raw) To: zsh-workers On Fri, Jun 26, 2020 at 12:32:51PM -0500, Matthew Martin wrote: > On Fri, Jun 26, 2020 at 07:24:21PM +0200, Han Boetes wrote: > > I had this program changing the name of the current working directory and > > noticed cd .; echo $PWD didn't pick up the changes. > > Was first discussed in IRC, so I had a head start on the patch. > > bin_cd may update pwd after calling cd_new_pwd which calls set_pwd_env. > Since bin_cd is the only caller of cd_new_pwd, I think it's safe to move > that code into cd_new_pwd prior to the oldpwd, pwd, new_pwd shift. This > should also call the chpwd hook with the right value. > > Seems to fix the issue locally. I know Daniel will rightfully ask for > a new test, so I'll work on that tonight. And with the test 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..cd0b79fb2 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,21 @@ 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 && +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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: cd does not update $PWD in a timely fashion. 2020-06-27 7:25 ` Matthew Martin @ 2020-06-27 20:42 ` Daniel Shahaf 2020-07-01 4:41 ` Matthew Martin 0 siblings, 1 reply; 5+ messages in thread From: Daniel Shahaf @ 2020-06-27 20:42 UTC (permalink / raw) To: Matthew Martin; +Cc: zsh-workers Matthew Martin wrote on Sat, 27 Jun 2020 02:25 -0500: > +++ b/Test/B01cd.ztst > @@ -149,6 +149,21 @@ F:something is broken. But you already knew that. > + 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 Is the lack of «&&» on this line intentional? > + print $hook_pwd && Run «unset chpwd_functions» here so as not to affect subsequent tests (once they're added)? Compare 46067. > +0q:cd . with moved PWD Cheers, Daniel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: cd does not update $PWD in a timely fashion. 2020-06-27 20:42 ` Daniel Shahaf @ 2020-07-01 4:41 ` Matthew Martin 0 siblings, 0 replies; 5+ messages in thread From: Matthew Martin @ 2020-07-01 4:41 UTC (permalink / raw) To: zsh-workers On Sat, Jun 27, 2020 at 08:42:08PM +0000, Daniel Shahaf wrote: > Matthew Martin wrote on Sat, 27 Jun 2020 02:25 -0500: > > + print $PWD > > Is the lack of «&&» on this line intentional? > > > + print $hook_pwd && > > Run «unset chpwd_functions» here so as not to affect subsequent tests > (once they're added)? Compare 46067. It wasn't and thanks for the pointer. 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-07-01 4:42 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-06-26 17:24 cd does not update $PWD in a timely fashion Han Boetes 2020-06-26 17:32 ` Matthew Martin 2020-06-27 7:25 ` Matthew Martin 2020-06-27 20:42 ` Daniel Shahaf 2020-07-01 4:41 ` Matthew Martin
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).