> $ 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/