zsh-workers
 help / color / mirror / code / Atom feed
* Re: 3.1.6-test-1: strange cd behaviour
@ 1999-07-14  6:56 Sven Wischnowsky
  0 siblings, 0 replies; 6+ messages in thread
From: Sven Wischnowsky @ 1999-07-14  6:56 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> (/tools/src  is in cdpath)
> 
> bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> builtin cd zsh-3.1.6-test-1/..
> bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> echo $?
> 0
> bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> /bin/pwd
> /tools/src/zsh-3.1.6-test-1
> 
> That is, cd does not change directory and returns success. I have some scripts
> that do "cd /some/dir && rm -r ..." ahem ...

That's a bit tricky... you have either no `.' in your `cdpath', or it is 
before /tools/src, right?

The problem is that cd_do_chdir() calls cd_try_chdir() with all
elements from `cdpath' -- if cdpath contains no `.', it first calls
cd_try_chdir() for the current directory (always plus the argument
given to `cd'). Well, cd_try_chdir() builds the full path (directory
from `cdpath' or current directory and the argument) and then calls
fixdir() -- which reduces /foo/bar/baz/.. to /foo/bar. So if `.' is
tested first and you try to `cd' to `dir/..', `cd' will always decide to
go to the current directory -- i.e. do nothing.

So the workaround for now is to put a `.' at the end of `cdpath'.

Hm, should we just document this or change it -- and how?

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* Re: 3.1.6-test-1: strange cd behaviour
  1999-07-15 12:23           ` Peter Stephenson
@ 1999-07-15 17:27             ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 1999-07-15 17:27 UTC (permalink / raw)
  To: ZSH workers mailing list

On Jul 14, 11:15am, Peter Stephenson wrote:
} Subject: Re: 3.1.6-test-1: strange cd behaviour
}
} > It worked (and still works) in 3.0.  What changed?
} 
} 3.0 relative paths are handled differently from absolute ones, while in 3.1
} the existing pwd is tacked on the front and all are handled together.  In
} 3.0, to make this work, ..'s behave differently if they are going up
} further than the start of the current pwd.  In the case of `cd dummy/..',
} it didn't and instead performed a chdir() on the whole thing, so that was
} tested properly.  On the other hand, cd .. works by examining and
} modifiying the current pwd, so you could cd from a non-existent directory.

Even with chaselinks set?  That would seem to me to be a bug.  And indeed
(in raw 3.0.5, but 3.0.6-pre-5 and 3.1.6-test-1 are the same):

zagzig[24] mkdir /tmp/bar /tmp/foo
zagzig[25] mkdir /tmp/bar/subdir
zagzig[26] cd /tmp/foo
zagzig[27] ln -s /tmp/bar/subdir .
zagzig[28] cd subdir
zagzig[29] setopt chaselinks
zagzig[30] cd ..
zagzig[31] pwd
/tmp/foo

} 3.1 is more integrated: it takes a complete path and operates on that.
} This has the effects previously reported.  Without restoring the 3.0
} behaviour, the fix would be
} 
} - If $PWD is a prefix, rationalize away any immediately following ..'s
}   (and .'s, to be on the safe side) before doing any testing.

So my first suggestion is that no rationalization should happen when
chaselinks is set.

} - At that point, even if $PWD is a prefix, look at the path and see if it
}   contains any /../ or finishes with /.. . If so, stat() it and check
}   that it exists.  If not, return and let the chdir code handle errors.

When chaselinks is NOT set, this approach mail fail due to permissions on
intermediate path elements when in fact it would succeed if the path were
rationalized first.  On the other hand, I suppose that if you want it to
fail because of nonexistent directories you probably want it to fail for
permissions as well.

However, it's also that case that you can't test the entire path once
and then assume it's OK to rationalize it, because stat() will follow
intermediate symlinks whereas rationalization will not.  (You pointed
this out yourself in the message excerpted below.)

As a third point, the correct way to test every component would in at
least some case be to actually chdir() there, not to stat() it.

} - If everything's OK so far (i.e. no ..'s, or the directory exists)
}   rationalize the rest of the path.

On Jul 15,  2:23pm, Peter Stephenson wrote:
} Subject: Re: PATCH: 3.1.6-test-1: strange cd behaviour
}
} "Andrej Borsenkow" wrote:
} > Yes. Completely remove this. If current dir no more exists, the
} > error message here is more of a feature - it indicates, that
} > somethig went wrong.
} 
} Actually, that's not completely removing it, that's including about half
} the code, just not the stuff that allows the PWD to be backtracked
} automatically.  (Unless you are suggesting going back to not testing for a
} non-existent directory at all?  But then you don't get the error message
} with `cd ..'.)

Here's what I propose, in more detail:

(1) When chaselinks is set, don't rationalize, simply attempt the cd and
either get the new directory if it succeeds or issue an error if it fails.
I'm going to peer at 3.0.6-pre; hopefully it isn't too hard to add this
one bit.

(2) When chaselinks is not set, either:
(2a) keep the pre-7139 behavior, or
(2b) add a "chasedots" option or some such that means zsh should act as
though chaselinks is set iff the path contains ".." anywhere.

} Furthermore, whether PWD is a prefix of the *physical* current directory is
} a different issue entirely, depending on the option CHASELINKS.  Without
} that set, zsh will always try to turn $PWD/.. into ${PWD:h}, wherever that
} lands you up.

I just tried this in pre-7139 3.1.6-test-1, and found that zsh *always*
turns $PWD/.. into $PWD:h, completely independent of chaselinks.

zagzig% pwd       
/tmp/foo/subdir
zagzig% setopt chaselinks
zagzig% echo $PWD
/tmp/foo/subdir
zagzig% pwd
/tmp/bar/subdir
zagzig% echo $PWD
/tmp/foo/subdir
zagzig% cd $PWD/..
zagzig% pwd
/tmp/foo

} Which opens another kettle of fish: if the .. is not at the end, then
} /foo/bar/../rod might not be the same physical path as /foo/rod.

Yes, that's the same point I made above about stat().

} (Although with AUTOCD `../rod' on its own already fails,
} because it tests for a physical directory, since cancd() doesn't call
} fixdir() --- anyone want that fixed?)

Only if you add the "chasedots" option.

} Maybe this is already going too far when CHASELINKS is unset.  (I could
} change it to stat every occurrence of <dir>/.. , which was my first
} thought, and which should get round this.)

This is definitely going too far.

} I would be perfectly happy to back off the patch altogether, too.

That plus (1) above would make me comfortable.

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


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

* Re: 3.1.6-test-1: strange cd behaviour
  1999-07-14  8:47   ` Bart Schaefer
@ 1999-07-14  9:15     ` Peter Stephenson
  1999-07-14 12:32       ` PATCH: " Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 1999-07-14  9:15 UTC (permalink / raw)
  To: ZSH workers mailing list

"Bart Schaefer" wrote:
> } Currently that works fine:  since tmp exists, it changes directory there.
> } However, if you insist on the initial directory being valid, then
> } (for example) statting ~/tmp/d1/.. will fail, and the cd won't work.
> } Furthermore, you can't even stat the relative path "..", since that's gone
> } too.  So I don't see a way of reconciling the two things.
> 
> It worked (and still works) in 3.0.  What changed?

This is a story of horror.  In both versions the directory path code
(c.f. xsymlinks()) is as clear as mud mixed with more mud in mud sauce (in
fact, I remember Zefram saying something similar).  What changed is that in
3.0 relative paths are handled differently from absolute ones, while in 3.1
the existing pwd is tacked on the front and all are handled together.  In
3.0, to make this work, ..'s behave differently if they are going up
further than the start of the current pwd.  In the case of `cd dummy/..',
it didn't and instead performed a chdir() on the whole thing, so that was
tested properly.  On the other hand, cd .. works by examining and
modifiying the current pwd, so you could cd from a non-existent directory.
However, if you have .. in your cdpath, then `cd dummy/..' will try the
path `../dummy/..', realises it's going up beyond pwd and hence allow the
dummy/.. to be rationalized away, and this works perfectly, taking you,
somewhat unexpectedly, to the parent of your current directory.

3.1 is more integrated: it takes a complete path and operates on that.
This has the effects previously reported.  Without restoring the 3.0
behaviour, the fix would be to do something clever when pwd is a prefix of
the path --- i.e., $PWD/.. is automatically turned into $PWD:h, whether the
directory exists or not, but $PWD/../dummy/.. becomes
${PWD:h}/dummy/.. which is weighed in the balance and found wanting.  This
would get all the advantages and none of the disadvantages of the 3.0
method (I hope).  The rule would be something like

- If $PWD is a prefix, rationalize away any immediately following ..'s
  (and .'s, to be on the safe side) before doing any testing.
- At that point, even if $PWD is a prefix, look at the path and see if it
  contains any /../ or finishes with /.. . If so, stat() it and check
  that it exists.  If not, return and let the chdir code handle errors.
- If everything's OK so far (i.e. no ..'s, or the directory exists)
  rationalize the rest of the path.

I may or may not get round to this myself.

-- 
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] 6+ messages in thread

* Re: 3.1.6-test-1: strange cd behaviour
  1999-07-14  8:06 ` Peter Stephenson
@ 1999-07-14  8:47   ` Bart Schaefer
  1999-07-14  9:15     ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 1999-07-14  8:47 UTC (permalink / raw)
  To: Peter Stephenson, ZSH workers mailing list

On Jul 14, 10:06am, Peter Stephenson wrote:
} Subject: Re: 3.1.6-test-1: strange cd behaviour
}
} I take it what you're really complaining about is that there is no
} subdirectory zsh-3.1.6-test-1 at that point, i.e. 
}   cd anyolddirectorynameatallatall/..
} always succeeds and leaves you in `.'?
} 
} Consider:
} 
} % mkdir ~/tmp/d1
} % cd ~/tmp/d1
} % rm -rf ~/tmp/d1
} % cd ..
} 
} Currently that works fine:  since tmp exists, it changes directory there.
} However, if you insist on the initial directory being valid, then
} (for example) statting ~/tmp/d1/.. will fail, and the cd won't work.
} Furthermore, you can't even stat the relative path "..", since that's gone
} too.  So I don't see a way of reconciling the two things.

It worked (and still works) in 3.0.  What changed?

zagzig% echo $ZSH_VERSION
3.0.6-pre-5
zagzig% cd dummy/..
cd: no such file or directory: dummy/..
zagzig% cd /tmp/foo
zagzig% mkdir fred
zagzig% cd fred
zagzig% rmdir /tmp/foo/fred
zagzig% cd ..
zagzig% pwd
/tmp/foo
zagzig% cd fred/..
cd: no such file or directory: fred/..

zagzig% echo $ZSH_VERSION
3.1.6-test-1
zagzig% pwd
/usr/src/local/zsh/zsh-3.1.5-build
zagzig% cd dummy/..
zagzig% pwd
/usr/src/local/zsh/zsh-3.1.5-build
zagzig% cd /tmp/foo
zagzig% cd fred/..
zagzig% pwd
/tmp/foo
zagzig% mkdir fred
zagzig% cd fred
zagzig% rmdir /tmp/foo/fred
zagzig% cd ..
zagzig% pwd
/tmp/foo
zagzig% cd fred/..
zagzig% pwd
/tmp/foo


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


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

* Re: 3.1.6-test-1: strange cd behaviour
  1999-07-13 15:29 Andrej Borsenkow
@ 1999-07-14  8:06 ` Peter Stephenson
  1999-07-14  8:47   ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 1999-07-14  8:06 UTC (permalink / raw)
  To: ZSH workers mailing list

"Andrej Borsenkow" wrote:
> (/tools/src  is in cdpath)
> 
> bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> builtin cd zsh-3.1.6-test-1/..
> bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> echo $?
> 0
> 
> That is, cd does not change directory and returns success.

I take it what you're really complaining about is that there is no
subdirectory zsh-3.1.6-test-1 at that point, i.e. 
  cd anyolddirectorynameatallatall/..
always succeeds and leaves you in `.'?

It certainly looks like a bug to me, because the unspoken assumption is
that cd will fail unless the path you've given it is valid as it stands ---
and it isn't, chdir() would fail if given the raw path.  However, I ought
to point out that bash and some versions of ksh (but not sh, which is too
dumb to massage paths, and not csh or tcsh either, and not some other
versions of ksh) silently accept this.

I wrote a patch for this, but unfortunately there's a real problem.
Consider:

% mkdir ~/tmp/d1
% cd ~/tmp/d1
% rm -rf ~/tmp/d1
% cd ..

Currently that works fine:  since tmp exists, it changes directory there.
However, if you insist on the initial directory being valid, then
(for example) statting ~/tmp/d1/.. will fail, and the cd won't work.
Furthermore, you can't even stat the relative path "..", since that's gone
too.  So I don't see a way of reconciling the two things.

-- 
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] 6+ messages in thread

* 3.1.6-test-1: strange cd behaviour
@ 1999-07-13 15:29 Andrej Borsenkow
  1999-07-14  8:06 ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Andrej Borsenkow @ 1999-07-13 15:29 UTC (permalink / raw)
  To: ZSH workers mailing list

(/tools/src  is in cdpath)

bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> builtin cd zsh-3.1.6-test-1/..
bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> echo $?
0
bor@itsrm2:/tools/src/zsh-3.1.6-test-1%> /bin/pwd
/tools/src/zsh-3.1.6-test-1

That is, cd does not change directory and returns success. I have some scripts
that do "cd /some/dir && rm -r ..." ahem ...

/andrej


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

end of thread, other threads:[~1999-07-15 17:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-14  6:56 3.1.6-test-1: strange cd behaviour Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
1999-07-13 15:29 Andrej Borsenkow
1999-07-14  8:06 ` Peter Stephenson
1999-07-14  8:47   ` Bart Schaefer
1999-07-14  9:15     ` Peter Stephenson
1999-07-14 12:32       ` PATCH: " Peter Stephenson
1999-07-15 11:57         ` Andrej Borsenkow
1999-07-15 12:23           ` Peter Stephenson
1999-07-15 17:27             ` Bart Schaefer

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