zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh-workers <zsh-workers@sunsite.dk>
Subject: Re: cd -s symlink hangs (sometimes?)
Date: Fri, 20 Mar 2009 22:48:56 +0000	[thread overview]
Message-ID: <20090320224856.73dae001@pws-pc> (raw)
In-Reply-To: <237967ef0903201412h2a7b99c9ya5101509a3972313@mail.gmail.com>

On Fri, 20 Mar 2009 22:12:30 +0100
Mikael Magnusson <mikachu@gmail.com> wrote:
> zsh -f
> % mkdir a
> % ln -s a b
> % cd -s b
> cd: not a directory: b
> % cd -s b
> # kill -9 in another terminal
> zsh: killed     zsh -f

The following is reproducible (note I didn't actually create the
directory a):

% zsh -f
% cd ~
% pwd
/home/pws
% rm -f a b
% ln -s a b
% cd -s b
cd: not a directory: b
% /bin/pwd
/

The -s does seem to be the crucial factor---which figures, since cd is
very heavily used so this would otherwise have turned up long ago.  This
is related to the lchdir() / zgetdir() code I was looking at the other
day and thinking was rather hairy (but the bug goes back to the 4.2 line
and presumably much further).

I can't be sure the fix below doesn't introduce another subtle problem,
though I think the test "d->dirfd < 0" should protect us from the most
likely side effects.  The underlying problem here is that the code for
HAVE_FCHDIR appears to have been kludged in without fixing the code
structure to do it properly.  I really don't like that complicated
expression I've moved down to fix the problem: in case we couldn't open
the current directory, investigate what directory it is, check it's not
absolute and if so open the parent directory instead... what is that
palaver supposed to do?

Still, I suspect it's better with rather than without the change.

Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.215
diff -u -r1.215 utils.c
--- Src/utils.c	20 Mar 2009 20:52:13 -0000	1.215
+++ Src/utils.c	20 Mar 2009 22:41:43 -0000
@@ -5388,11 +5388,7 @@
     if (*path == '/') {
 #endif
 	level = -1;
-#ifdef HAVE_FCHDIR
-	if (d->dirfd < 0 && (d->dirfd = open(".", O_RDONLY | O_NOCTTY)) < 0 &&
-	    zgetdir(d) && *d->dirname != '/')
-	    d->dirfd = open("..", O_RDONLY | O_NOCTTY);
-#else
+#ifndef HAVE_FCHDIR
 	if (!d->dirname)
 	    zgetdir(d);
 #endif
@@ -5404,6 +5400,11 @@
 	    d->ino = st1.st_ino;
 	}
     }
+#ifdef HAVE_FCHDIR
+    if (d->dirfd < 0 && (d->dirfd = open(".", O_RDONLY | O_NOCTTY)) < 0 &&
+	zgetdir(d) && *d->dirname != '/')
+	d->dirfd = open("..", O_RDONLY | O_NOCTTY);
+#endif
 
 #ifdef HAVE_LSTAT
     if (!hard)
Index: Test/B01cd.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/B01cd.ztst,v
retrieving revision 1.3
diff -u -r1.3 B01cd.ztst
--- Test/B01cd.ztst	5 Aug 2002 13:10:02 -0000	1.3
+++ Test/B01cd.ztst	20 Mar 2009 22:41:43 -0000
@@ -109,6 +109,14 @@
 >$mydir/cdtst.tmp/real
 >$mydir/cdtst.tmp/real
 
+ ln -s nonexistent link_to_nonexistent
+ pwd1=$(pwd -P)
+ cd -s link_to_nonexistent
+ pwd2=$(pwd -P)
+ [[ $pwd1 = $pwd2 ]] || print "Ooops, changed to directory '$pwd2'"
+0:
+?(eval):cd:3: not a directory: link_to_nonexistent
+
 %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


-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


  reply	other threads:[~2009-03-20 22:49 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-20 21:12 Mikael Magnusson
2009-03-20 22:48 ` Peter Stephenson [this message]
2009-03-20 23:15   ` Mikael Magnusson
2009-03-22 12:54     ` Peter Stephenson
2009-03-22 23:05       ` Mikael Magnusson
2009-03-23 10:49         ` Peter Stephenson
2009-03-23 11:46           ` Mikael Magnusson
2009-03-23 12:27             ` Peter Stephenson
2009-03-24 12:46               ` Peter Stephenson
2009-03-24 15:15                 ` Bart Schaefer
2009-03-24 16:02                   ` Peter Stephenson
2009-04-06 11:07                 ` Mikael Magnusson
2009-04-06 11:13                   ` Peter Stephenson
2009-03-23 15:18       ` Bart Schaefer
2009-03-23 15:39         ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090320224856.73dae001@pws-pc \
    --to=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).