native symlink

Corinna Vinschen
Wed Apr 3 15:29:00 GMT 2013

On Apr  3 00:33, Jeffrey Altman wrote:
> I tried representing AFS Symlinks using a Microsoft assigned Reparse
> Point Tag.  The downside of following that approach was that Cygwin does
> not properly handle Reparse Point Tags that it does not recognize.  By
> discarding the RP attribute and preserving the other reparse point stat
> information (timestamps, attributes, size, etc) it introduces data
> corrupting behaviors into Cygwin applications.

You never explained why this happens and at which point in the code.  So
far it was the right thing to do, and I'm pretty sure you know why.  I
don't change that, unless you can show me where and when this leads to
wrong behaviour.  I asked for these details but you didn't offer an
explanation besides the fact itself so far.  And it would have been
no problem to add a special handling for AFS in the cases where it went
wrong.  I guess this is kind of a moot point, now that you converted
to native symlinks, but this had to be said.

> However, there is a very clear test that can be applied to determine
> when Microsoft Symlinks should be generated in preference to Cygwin
> symlinks:
> [...]
> There are probably additional approaches but none of them are clean and
> transparent.  The second two involved significantly more complexity then
> maintaining support within Cygwin's and could potentially
> introduce incompatibilities with future Cygwin changes.

No test could be sufficient to switch on native symlinks automatically.

We were all very excited when it became clear that Microsoft introduced
native symlinks on NTFS with Vista, and I was early on playing around
with them and to try integrating them into Cygwin.  My local testcase
uses DeviceIoControl to workaround any restrictions imposed by
CreateSymbolicLink.  And I'm still playing around with them every now
and then, thinking that we could use them, but the restrictions are
disappointing me each time anew.

There are some downsides to native symlinks which make them hard to
justify, if not downright useless in a POSIX environment.

- The inability of normal users to create symlinks by default.

    This can be worked around by changing the policy, but it's still a
    PITA.  Normal users don't know about the policy, some of them don't
    even have the "Local Security Policy" MMC snap in.  Even in a
    corporate environment it requires to change the policy settings and
    we all know how admins don't like to *soften* a policy.  But let's
    say we can help along with a FAQ entry.

- Native symlinks are marked as file or directory.

    This has been added clearly for the benefit of Windows Explorer.
    But it's a PITA as well because it destroys interoperability.  It's
    common that POSIX symlinks are created before the target exists.
    How on earth should the symlink(2) function know if the target is
    supposed to be a dir or a file.  But Explorer as well as CMD will do
    the wrong thing if the symlink is using a non-matching dir/file

- Only Windows paths are stored.

    In a POSIX env a symlink created by POSIX tools should point to a
    POSIX path.  For instance, mount points change the fact where a
    symlink actually points to and the symlink should not still
    magically work afterwards.

    But, hey, native symlinks store the path twice, the SubstituteName
    and the PrintName.  Shouldn't it be possible to store the Windows
    path in one of them and the POSIX path in the other?  Yes and no.
    It's possible to write into these members whatever you like, but for
    some weird reason, both members have to be Windows paths to work for
    native Windows tools.

    But we could store the POSIX path with backslashes, thus working
    around the issue, no?  No.  An absolute path starting with a
    backslash is possible, but the Windows tools will evaluate it as
    root-relative to the current drive.  cd to another drive in cmd,
    and interop is broken again.

- Remote and local symlinks may behave different in different environments.

    Apart from the security policy, symlinks are also affected by an
    fsutil setting.  The admins can decide if symlinks work at all, or
    if symlinks don't work depending on their own location and the
    location of the target they are pointing to (local->local, local->remote,
    remote->local, remote->remote)

    So it's possible that local->local symlinks can be resolved while
    opening local->remote symlinks simply fail with ugly status codes.
    How on earth do you integrate that reliably into an environment in
    which a symlink is a plain and simple thing, readable and writable
    by everyone, whereever located, just apart from parent dir permissions.

> As I see it, as flawed as Microsoft Symlinks are they are the common
> interface that enables mixed applications to communicate with one
> another.  As such, where they can be used, they should be used.  What is
> the point of cross-platform support if mixed platform applications
> cannot transparently share the data?

Cygwin is a POSIX environment in the first place.  Interop is fine,
but if it collides with POSIX, we're clearly favoring POSIX.

Having said that.

Chris and I had a private discussion (not the first one on the subject!)
and we're willing to revisit the use of native symlinks in Cygwin but
it will be a while before that happens.  A change to the path handling
code like this is not something that we'd consider for 1.7.18 which is
long overdue anyway.

What I will do is to add a new CYGWIN environment variable option, along
the lines of the winsymlinks option(*), or, which is very likely the
more elgant solution, a mount option, which will result in trying to
create native symlinks first, and a Cygwin symlink only if creating
a native symlink failed.  That should help you along.


(*) In your blog you were musing why Cygwin supports lnk files but
not native symlinks.  Here's the answer:  lnk files support using 
POSIX paths.

Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

More information about the Cygwin-developers mailing list