From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 3092 invoked from network); 27 Jun 2020 07:26:43 -0000 Received: from ns1.primenet.com.au (HELO primenet.com.au) (203.24.36.2) by inbox.vuxu.org with ESMTPUTF8; 27 Jun 2020 07:26:43 -0000 Received: (qmail 4365 invoked by alias); 27 Jun 2020 07:26:35 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: Sender: zsh-workers@zsh.org X-Seq: 46144 Received: (qmail 3869 invoked by uid 1010); 27 Jun 2020 07:26:35 -0000 X-Qmail-Scanner-Diagnostics: from mail-oi1-f196.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.3/25850. spamassassin: 3.4.4. Clear:RC:0(209.85.167.196):SA:0(-1.8/5.0):. Processed in 1.620961 secs); 27 Jun 2020 07:26:35 -0000 X-Envelope-From: phy1729@gmail.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _netblocks.google.com designates 209.85.167.196 as permitted sender) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mail-followup-to :references:mime-version:content-disposition:in-reply-to; bh=G+X+7hgyMjQxN6ZYj3rdfoJgL6EoVsLEl0gElXg5iaY=; b=d6Gz+EcEy1w7vHCkEKet0ipMFUbiibRqLJK8EvAqXvU7QT7HDFglgYKEbjso2cHHvP 31yRZFfLPHLzh5i6jhzF2TatfEbPNQI6XvlLF/Z0qh6bZVt0wxR9w27LT/+dHAsH3bX9 Sl7BEweR1f9bHW0lIaAnPuULXvTObRYaPLjxqss0qTqrqtKmfUYo6CPuBEeq0Kqk8Vrd J3Lebq+sNkIBbQF48x7wVVlK13PfjB4jy8ZQ7sFtYADrPCh0B1r9VgiEUqOyLKrr1aKr DjSpeF4CIGoVp2llTtvA0tGH1gI6B1gzQyt/JqrOPwmDnVT6OsGJgu3tSwUN43ituzez KPqg== X-Gm-Message-State: AOAM533vM+4pH5Lr99OrBEANsiHeIY1n8rxF1y7DOCHRIsMoVsnORSR9 G1zW+yADtfrLPU6LdJ9A0o1ghpK292k= X-Google-Smtp-Source: ABdhPJzfm4wh5dWvw3nWOTCHyX44GGMDDcRQHlvmhvA9Bn8U0xXlkgI3fLiaHwljNKzuuFPnxLzOSQ== X-Received: by 2002:aca:58c3:: with SMTP id m186mr5329611oib.5.1593242759757; Sat, 27 Jun 2020 00:25:59 -0700 (PDT) Date: Sat, 27 Jun 2020 02:25:57 -0500 From: Matthew Martin To: zsh-workers@zsh.org Subject: Re: cd does not update $PWD in a timely fashion. Message-ID: <20200627072557.GA48532@CptOrmolo.darkstar> Mail-Followup-To: zsh-workers@zsh.org References: <20200626173248.GA31933@CptOrmolo.darkstar> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200626173248.GA31933@CptOrmolo.darkstar> 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