zsh-workers
 help / color / mirror / code / Atom feed
* Re: cd, pwd and symlinks
       [not found] <5lemfkez1d.fsf@tequila.cs.yale.edu>
@ 1999-09-28 10:07 ` Peter Stephenson
  1999-09-28 16:42   ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 1999-09-28 10:07 UTC (permalink / raw)
  To: zsh-workers

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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cd, pwd and symlinks
  1999-09-28 10:07 ` cd, pwd and symlinks Peter Stephenson
@ 1999-09-28 16:42   ` Bart Schaefer
  1999-09-28 17:42     ` Zefram
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 1999-09-28 16:42 UTC (permalink / raw)
  To: zsh-workers

On Sep 28, 12:07pm, Peter Stephenson wrote:
} Subject: Re: cd, pwd and symlinks
}
} "Stefan Monnier" wrote:
} >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.)

Hm.  I thought "cd .." was only supposed to fail if chasedots was set.
"cd ." or "cd ../$PWD:t" are supposed to fail if the destination doesn't
exist.  But this is a side-effect of "cd .." turning into "cd $PWD/.."
plus the rule that "cd /some/missing/directory/.." is supposed to fail,
isn't it.  Argh.
 
} > 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.

I can't decide whether I object to this ... but perhaps it should at least
not happen when ksh emulation is in effect?

} 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.

A bit confusing, though, isn't it?

zsh% cd /tmp/test
zsh% cd subdir
zsh: No such file or directory: subdir
zsh% pwd
/tmp/renamed
zsh% cd subdir
zsh% 

If there were much elapsed time at all between the first two cd's, the
poor user might not remember where he was before the pwd, and would have
no idea what was going on.

And finally, `dirs` still outputs the previous value of PWD.

} There's some reason why the code was changed
} to do all changes with absolute path --- maybe to simplify it, hur hur.

As far as I can tell, this is something Zefram changed between 3.1.2 and
3.1.3, for which no patch was ever posted.

} I'm sure other people will have completely different ideas, they always do
} with directories.

Indeed.  I may have a look at this later today if I get a chance.  I'm
thinking that (a) pwd should do something more like cd_new_pwd() (but not
including calling chpwd) if it can't stat(pwd), and (b) cd should try
harder, perhaps implicitly behaving as if chasedots, if it can't stat(pwd).

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cd, pwd and symlinks
  1999-09-28 16:42   ` Bart Schaefer
@ 1999-09-28 17:42     ` Zefram
  1999-09-29  3:29       ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Zefram @ 1999-09-28 17:42 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

Bart Schaefer wrote:
>On Sep 28, 12:07pm, Peter Stephenson wrote:
>} There's some reason why the code was changed
>} to do all changes with absolute path --- maybe to simplify it, hur hur.
>
>As far as I can tell, this is something Zefram changed between 3.1.2 and
>3.1.3, for which no patch was ever posted.

I'm pretty sure it's not.  That's one of the areas of the shell that I
studiously avoided changing.

If I'd designed the shell from scratch, it would match the underlying OS
behaviour, and consequently $PWD wouldn't exist, or at least not in the
form we have it.  $PWD is really an abomination, giving the impression of
an absolute directory structure, which in fact doesn't exist.  Given that
we have to support it, there are basically two sensible ways for it
to work:

1. cd maps directly onto chdir(), doing everything the way the
   filesystem says.  $PWD has no direct effect -- it is equivalent to
   $(pwd), recalculated every time it is referenced.  It always searches
   for a valid absolute pathname referring to the current directory.
   The user must accept that it will sometimes fail (yielding "."),
   and that the pathname returned will not necessarily remain valid,
   but it will always be valid at the moment it is evaluated.

2. $PWD is the shell's canonical idea of its current directory.  cd with
   a relative pathname does text substitution using $PWD, and then does
   a chdir() to the resulting absolute pathname.  pwd just gives $PWD,
   and has an option to do a /bin/pwd-style search instead.  The user
   must accept that the current directory may not be accessible under
   the name in $PWD, and that relative filenames in a cd command have
   completely different semantics from relative filenames everywhere else.

Until 3.1.6, we had a pretty consistent 2.  Now we have a mixture of the
two styles, which isn't working, and making it more complicated isn't
going to help.  Let's just have the two ways of working, with an option
to switch between them.

-zefram


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cd, pwd and symlinks
  1999-09-28 17:42     ` Zefram
@ 1999-09-29  3:29       ` Bart Schaefer
  1999-09-29  9:33         ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 1999-09-29  3:29 UTC (permalink / raw)
  To: zsh-workers

On Sep 28,  6:42pm, Zefram wrote:
} Subject: Re: cd, pwd and symlinks
}
} Bart Schaefer wrote:
} >On Sep 28, 12:07pm, Peter Stephenson wrote:
} >} There's some reason why the code was changed
} >} to do all changes with absolute path --- maybe to simplify it, hur hur.
} >
} >As far as I can tell, this is something Zefram changed between 3.1.2 and
} >3.1.3, for which no patch was ever posted.
} 
} I'm pretty sure it's not.  That's one of the areas of the shell that I
} studiously avoided changing.

Ah.  Further investigation reveals that this was already changed in 3.1.0;
I've checked the RCS files from that version that are on the FTP site.  So
the next best guess is that Zoltan changed this; see the ChangeLog entry 
for Thu Dec  5 03:59:45 1996, "Lots of other stuff."

} Given that we have to support [PWD], there are basically two sensible
} ways for it to work:
} 
} 1. cd maps directly onto chdir(), doing everything the way the
}    filesystem says.
} 
} 2. $PWD is the shell's canonical idea of its current directory.  cd with
}    a relative pathname does text substitution using $PWD, and then does
}    a chdir() to the resulting absolute pathname.

I generally agree with this viewpoint, but:

} Until 3.1.6, we had a pretty consistent 2.

I don't really agree with that last, the problem being that other parts
of the shell (particularly completion) didn't pay attention to the same
rules, which could lead to all sorts of odd stuff.  I'm not sure we've
completely (ahem) fixed that, even yet.

Certainly there should be at least ONE mode in which "cd .." simply does
chdir(".."), and right now NO mode does so (even after PWS's patch).  I
don't believe any of 3.1.<0-5> did this correctly either.

} Now we have a mixture of the two styles, which isn't working, and
} making it more complicated isn't going to help. Let's just have the
} two ways of working, with an option to switch between them.

This is essentially my feeling too, except that I think we can do better
in the failure cases.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cd, pwd and symlinks
  1999-09-29  3:29       ` Bart Schaefer
@ 1999-09-29  9:33         ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 1999-09-29  9:33 UTC (permalink / raw)
  To: zsh-workers

"Bart Schaefer" wrote:
> Certainly there should be at least ONE mode in which "cd .." simply does
> chdir(".."), and right now NO mode does so (even after PWS's patch).  I
> don't believe any of 3.1.<0-5> did this correctly either.

Aha.  You mean if I rename a parent directory, then even with chaselinks
set it gets confused.  This does seem to be the case.  That's annoying,
because pwd prints the right value.  It would certainly be nice to think
that chaselinks is always going to do the right thing, no funny business
(i.e. no turning .. into $PWD/..).

> } Now we have a mixture of the two styles, which isn't working, and
> } making it more complicated isn't going to help. Let's just have the
> } two ways of working, with an option to switch between them.
> 
> This is essentially my feeling too, except that I think we can do better
> in the failure cases.

With some clearer documentation on the subject, this could work ---
chaselinks does Zefram's 1, nochaselinks does logical directories, and if
you want the shell to be careful about non-existent directories you have to
move over to Hotel Chaselinks.  (I don't think most users want either/or
behaviour, they want the shell to do the right thing all the time, without
them having to tell it what that is, which is largely how the cd code
arose, and why it's a mess.)  But somebody's going to have to write this,
and it's unlikely to be me this time.

I'll leave out 8084 for now.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1999-09-29 10:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5lemfkez1d.fsf@tequila.cs.yale.edu>
1999-09-28 10:07 ` cd, pwd and symlinks Peter Stephenson
1999-09-28 16:42   ` Bart Schaefer
1999-09-28 17:42     ` Zefram
1999-09-29  3:29       ` Bart Schaefer
1999-09-29  9:33         ` Peter Stephenson

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).