Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: cd, pwd and symlinks



"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 <pws@xxxxxxxxxxxxxxxxx>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy



Messages sorted by: Reverse Date, Date, Thread, Author