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

[BUG] cdpath=(.) breaks cd from / on Cygwin



Hi, zsh workers,

This is my first time sending to this list. Sorry if I've got any of the conventions wrong.

I think I've found a bug in zsh's handling of path normalization on Cygwin when there's an explicit '.' in $cdpath. When $cdpath contains ., and your pwd is /, doing a cd using a relative path to an immediate subdir like `cd bin` or `cd tmp` errors out, and slowly.

Reproduction
====================

In zsh on Cygwin, do this:

cd /
cdpath=(.)
cd bin
cd lib
cdpath=()
cd bin

Symptoms
====================

On my system (Windows 7, zsh 5.0.6 (x86_64-unknown-cygwin), running inside MinTTY, inside a vmware VM on Mac OS X 10.9 on a MacBook Pro), if I have '.' in $cdpath and try to do a cd from / to an immediate subdir, the command sits there for up to several seconds and then errors out with a "no such dir" error.

Here's an example run. This is with an empty ~/.zshrc file so I'd have a default zsh configuration. gwydion is my win7 machine's hostname.

gwydion% cd /
gwydion% cdpath=(.)
gwydion% cd bin
cd: no such file or directory: bin
gwydion% cd lib
cd: no such file or directory: lib
gwydion% pwd
/
gwydion% cdpath=()
gwydion% cd bin
gwydion% pwd
/bin
gwydion%

I would expect the behavior with `cdpath=(.)` to be identical to the behavior with `cdpath=()`, and to have all these cd commands succeed.


Analysis
===================

On OS X 10.9 and Debian Linux 7, doing a cd from / with cdpath=(.) works fine for me, so I think this is Cygwin-specific.

In Src/builtin.c, function cd_try_chdir(), lines 1080-1093, there's some special case handling for Cygwin and the prefix '/'. But when the prefix is '.', it goes down a different code path. It constructs the path starting from pwd (which is '/' in this case), and then goes through the path normalization which elides '.' segments. But it doesn't have a special case check for Cygwin to check for leading '/' again. And I think the elision of the first '.' segment will result in a computed path starting with '//' but not further escaped.

I think what's happening is in this case, the path is ending up with '//' at the beginning and it's treating it as a UNC path and ends up looking for a machine named 'bin' or 'lib' or whatever.

I'm not good enough with C and path normalization to try my hand at making a patch for this.

References
===================

I found this while working with oh-my-zsh, where another Cygwin user ran in to this behavior. https://github.com/robbyrussell/oh-my-zsh/issues/3550

(When I tested this, I had oh-my-zsh disabled, and an empty .zshrc, so I don't think oh-my-zsh interaction is relevant.)

Cheers,
Andrew Janke



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