Mail Archives: cygwin/2005/06/23/14:12:15
> $ ln -s /bin/sh foo
> $ mv foo bar
> mv: cannot stat `foo.exe': No such file or directory
I'm not sure if this was the issue that appeared on the list last month, but
it is one of the issues I was already aware of and trying to fix for
coreutils-5.3.0-7.
The underlying problem is that there is currently NO EFFICIENT WAY in
cygwin to determine if .exe magic is taking place. Most of the coreutils
cygwin patches use access() to see if the short name resolves, then open()
to see if the short name was the correct spelling. Unfortunately, with your
symlink, access(foo) succeeds (so I know there is either a foo or foo.exe),
but the open fails (since your symlink points to plain /bin/sh, rather than
the truly existing /bin/sh.exe, it is technically dangling since open doesn't
perform .exe magic), and the failure is ENOENT. I interpreted ENOENT as
meaning foo doesn't exist, so the access must have succeeded on foo.exe,
which is where I went wrong. (Cygwin is a bit inconsistent here - the
exec() family on this half-dangling symlink recognizes that /bin/sh doesn't
exist, so it exec's /bin/sh.exe instead rather than erroring out with
ENOENT). So there is a problem with the access/open check alone in
deciding if the spelling was correct; perhaps I can solve it by throwing in
a readlink (but as was just pointed out this week, readlink currently fails if
the link points to . or ..).
It would be really nice if there were a new flag to access() that supressed
.exe expansion, and succeeded only if the exact spelling matched. Then
my test to see if .exe should be appended would be as simple as
access("foo", F_OK) == 0 && access("foo", F_OK | __NO_EXE_MAGIC) == -1.
Furthermore, access() seems like it may be more efficient than open() in
terms of the underlying work that must be done to implement it.
Maybe I should also patch ln so that symbolic links have some .exe magic.
Normally, POSIX requires that creating a symlink does not inspect whether
its target exists, but perhaps `ln -s foo /bin/sh' should behave as `ln -s
foo /bin/sh.exe' if /bin/sh does not exist and /bin/sh.exe does exist. The
drawback to this is that ln would no longer create symlinks with the exact
spellings the user specifies, and for cases where the dangling symlink is
created first before the executable, ln would have no way to know that the
intended target will eventually have a .exe suffix. On the other hand, maybe
I should make ln always use the user's spelling, but emit a warning if the
link is to foo when only foo.exe exists (and be silent if foo exists or if neither
exists), but then you have the issue of whether the exit status should be 0
or 1 if the warning was printed.
--
Eric Blake
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -