From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9788 invoked from network); 28 Sep 1999 10:42:55 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 28 Sep 1999 10:42:55 -0000 Received: (qmail 4401 invoked by alias); 28 Sep 1999 10:42:33 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 8084 Received: (qmail 4394 invoked from network); 28 Sep 1999 10:42:32 -0000 Message-Id: <9909281007.AA22813@ibmth.df.unipi.it> To: zsh-workers@sunsite.auc.dk Subject: Re: cd, pwd and symlinks In-Reply-To: ""Stefan Monnier""'s message of "27 Sep 1999 19:05:02 DFT." <5lemfkez1d.fsf@tequila.cs.yale.edu> Date: Tue, 28 Sep 1999 12:07:01 +0200 From: Peter Stephenson "Stefan Monnier" wrote: >>> I must say I don't like the names and defaults. The names give the >>> impression that chasing links is a very unusual feature while it's the >>> normal unix behavior. >> It's not, however, the normal zsh behavior, and has not been for a very long >> time. It may even date back to a specific personal preference of Falstad's; >> I don't recall for certain now. > >That's indeed what I'm complaining about. The default behavior is very >non-unixish which is surprising for a unix-only tool. In that case, ksh is non-UNIXish too, since it has this logical path feature on by default. (Plus it's still able to change up from a no-longer-existent directory, which zsh isn't after the last round of cd changes, but we had this discussion at length some months ago.) > But apart from that, I'm more often annoyed by `pwd' not checking the > value it returns: > > ~/tmp-0% mkdir foo > ~/tmp-0% cd foo > tmp/foo-0% mv ../foo ../bar > tmp/foo-0% pwd > /home/monnier/tmp/foo > tmp/foo-0% > ... > But how hard would it be to have `pwd' do a stat("$PWD") and stat(".") > and compare the inode to make sure the current $PWD is still valid ? It does seem that this could be improved. Since the existing pwd string is used when changing directories relatively, the current behaviour means you could easily be stuck because the first part of the path is wrong --- e.g. try changing into a subdirectory after the mv above and it will fail. The change you suggest isn't all that expensive, two stat's per pwd where (with chaselinks or -r or -P) the full zgetcwd() is much more expensive anyway. This isn't perfect, since unless you run pwd, the shell doesn't know if the path to the current directory became invalid and a cd can still fail, but at least it gives you a natural way of fixing it. Arguably we could do this check if a cd fails, making the cd code even more complicated, which I didn't think was impossible. There's some reason why the code was changed to do all changes with absolute path --- maybe to simplify it, hur hur. I'm sure other people will have completely different ideas, they always do with directories. --- Doc/Zsh/builtins.yo.pwd Tue Sep 21 11:25:32 1999 +++ Doc/Zsh/builtins.yo Tue Sep 28 11:51:12 1999 @@ -682,7 +682,12 @@ Print the absolute pathname of the current working directory. If the tt(-r) or the tt(-P) flag is specified, or the tt(CHASE_LINKS) option is set and the tt(-L) flag is not given, the printed path will not -contain symbolic links. +contain symbolic links. Otherwise, the shell will print the stored +directory, i.e. the value to which tt($PWD) was last set. In this case, it +will check that the current tt($PWD) is still valid; if it is, or if it is +unable to find a valid path because the current directory no longer exists, +it will print that, and if it is not, it will print the full path without +symbolic links and update tt($PWD) accordingly. ) alias(r)(fc -e -) findex(read) --- Src/builtin.c.pwd Tue Sep 21 11:25:31 1999 +++ Src/builtin.c Tue Sep 28 11:45:53 1999 @@ -572,8 +572,28 @@ if (ops['r'] || ops['P'] || (isset(CHASELINKS) && !ops['L'])) printf("%s\n", zgetcwd()); else { - zputs(pwd, stdout); - putchar('\n'); + struct stat stdot, stpwd; + char *tmppwd; + /* + * We could print nothing and return status 1 if we can't + * stat ., but that's incompatible with both ksh and what + * we used to do. + */ + if (stat(".", &stdot) < 0 || + stat(pwd, &stpwd) >= 0 && stpwd.st_ino == stdot.st_ino) { + zputs(pwd, stdout); + putchar('\n'); + } else { + /* + * The directory has changed without us noticing it. We + * need to change pwd, since directory changing commands + * are liable to fail otherwise. + */ + zsfree(pwd); + printf("%s\n", tmppwd = zgetcwd()); + pwd = metafy(tmppwd, -1, META_DUP); + set_pwd_env(); + } } return 0; } -- Peter Stephenson Tel: +39 050 844536 WWW: http://www.ifh.de/~pws/ Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy