This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unusual new look to symlinks to executables

> This seems to have happened with today's upgrade to coreutils and
> possibly with the recent upgrade to tetex. I am not certain whether
> anything is broken, but I am certain that things are different.

It was not today's upgrade to coreutils (on a machine still running
coreutils-5.3.0-3, the /bin directory still contains a mix of both flavors of link
contents, and I did not touch ln(1) when building the -4 release).  But it may be
related to an unintended difference in coreutils-5.2.1 and coreutils-5.3.0 in
general.  Also, did you upgrade to cygwin 1.5.14 at the same time?  It might be
a change in the cygwin path handling.  But you are also right that it is
harmless, since cygwin link resolution will append the .exe when needed.

> Some links to executables now show the executable name without the .exe
> extension, as in
> > ls /bin | grep csh
> csh -> tcsh*
> tcsh.exe*

Could you please also include the output of `which ls' if you are running tcsh,
or `type ls' if you are running bash, so I can figure out what alias you are using
for ls?  By default, ls does not display just a filename and its link contents.

> There are now very many instances of this under /bin and possibly
> elsewhere (try ls -al /bin | grep diff or ls -al /bin | grep naim). I
> can see that in Cygwin an executable will run whether the instruction to
> run it is given as execname.exe or just execname, so in that sense
> possibly nothing is broken that once was not. However, the "many
> instances" just referred to were made evident by a simple link-checking
> script that I have been running for my own purposes within Cygwin for
> two years or more, and in the entire Cygwin provision over that time
> interval, this is the first time that the phenomenon described has
> occurred. So perhaps it is accidental, and should not have happened?

It certainly was not intentional.  It is tricky to get both ln(1) and ls(1) to handle
implicit .exe magic correctly, and I may need to release a new coreutils that
makes it more consistent in the future.  But you are correct that no harm is
done whether the .exe is in the link or not.  Part of the problem is the
difference between hard links and symlinks - for a hard link, the target file must
exist, so it makes sense to have the link have the same extension as the
source.  But for symlinks, POSIX requires the source to be treated as just a
string with no filename validation, so in `ln -s a b', ln is not even allowed to
check if a, a.exe, both, or neither exist, to decide what the string contents of b
should be - as written, the contents of b must be `a'.  From there, it is the path
resolution code that decides a symlink to a can resolve to a.exe.  Some of the
difference on whether the symlinks contain the .exe ending depends on how
the various packages were created, whether the packager used `ln -s a.exe b'
or `ln -s a b'.  Also affected are other programs that can create symlinks, such
as tar, that don't necessarily follow the same rules as ln(1).  I'm not even sure
whether the cygwin implementation of symlink(2) strictly follows POSIX or if it
does some filename validation when creating the symlink.  By the way, you can
also use readlink(1) to read the contents of a symlink, to verify if it is `a' or

Below is the table of how I think ln(1) ought to behave (I'm open to
suggestions if others think differently).  Where ln(1) does not actually behave
this way, I am open to help in patching coreutils to provide the desired
functionality.  Hopefully my webmail interface didn't screw up this table too

       existing:	a	a.exe	both	neither
ln    a     b		1	4	4	0
ln    a.exe b		0	2	2	0
ln    a     b.exe	3	4	4	0
ln    a.exe b.exe	0	4	4	0
ln -s a     b		5	6	5	7
ln -s a.exe b		9	8	8	9
ln -s a     b.exe	10	11	10	12
ln -s a.exe b.exe	14	13	13	14

0.  error
1.  b is hardlink to a
2.  b is hardlink to a.exe
3.  b.exe is hardlink to a
4.  b.exe is hardlink to a.exe
5.  b is symlink, readlink b gives a, resolves to a
6.  b is symlink, readlink b gives a, resolves to a.exe
7.  b is symlink, readlink b gives a, dangling link
8.  b is symlink, readlink b gives a.exe, resolves to a.exe
9.  b is symlink, readlink b gives a.exe, dangling link
10. b.exe is symlink, readlink b.exe gives a, resolves to a
11. b.exe is symlink, readlink b.exe gives a, resolves to a.exe
12. b.exe is symlink, readlink b.exe gives a, dangling link
13. b.exe is symlink, readlink b.exe gives a.exe, resolves to a.exe
14. b.exe is symlink, readlink b.exe gives a.exe, dangling link

I guess one final question is whether cygwin's readlink(2) should be allowed to
append .exe if that's what the symlink currently resolves to, or if it should
always return exactly what is contained in the link.  My table above assumes
that readlink(2) does not auto-append .exe when resolving a symlink.

Eric Blake
(coreutils maintainer)

Unsubscribe info:
Problem reports:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]