Cygwin: docs: revamp docs explaining symlinks

The descriptions of symlink handling are a bit dated, so
revamp them and add the new WSL symlink type.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2020-04-03 21:44:00 +02:00
parent 44da5e4b8c
commit 44fe41a766
4 changed files with 142 additions and 73 deletions

View File

@ -180,37 +180,108 @@ expect.
<question><para>How do symbolic links work?</para></question>
<answer>
<para>Cygwin knows of two ways to create symlinks.
</para>
<para>The default method generates link files with a magic header. When you
open a file or directory that is a link to somewhere else, it opens the file
or directory listed in the magic header. Because we don't want to have to
open every referenced file to check symlink status, Cygwin marks symlinks
with the system attribute. Files without the system attribute are not
checked. Because remote samba filesystems do not enable the system
attribute by default, symlinks do not work on network drives unless you
explicitly enable this attribute or use the second method to create symlinks.
<para>Cygwin knows of five ways to create symlinks. This is really
complicated stuff since we started out way back when Windows didn't
know symlinks at all. The rest is history...
</para>
<para>The second method is enabled if `winsymlinks' is set in the environment
variable CYGWIN.
Using this method, Cygwin generates symlinks by creating Windows shortcuts.
Cygwin created shortcuts have a special header (which is in that way never
created by Explorer) and the R/O attribute set. A DOS path is stored in
the shortcut as usual and the description entry is used to store the POSIX
path. While the POSIX path is stored as is, the DOS path has perhaps to be
rearranged to result in a valid path. This may result in a divergence
between the DOS and the POSIX path when symlinks are moved crossing mount
points. When a user changes the shortcut, this will be detected by Cygwin
and it will only use the DOS path then. While Cygwin shortcuts are shown
without the ".lnk" suffix in `ls' output, non-Cygwin shortcuts are shown
with the suffix. However, both are treated as symlinks.
<itemizedlist spacing="compact">
<listitem><para>
Starting with Cygwin 3.1.5 in 2020, symlinks are created by default as a
special reparse point type known as "WSL symlinks". These have been
introduced on Windows 10 with the advent of WSL, "Windows Subsystem for
Linux". WSL symlinks created by Cygwin are understood by WSL and vice
versa. They contain a normal POSIX path as used in the Cygwin and WSL
environments. Windows itself recognizes them as arbitrary reparse
points (CMD's "dir" command shows them as "[JUNCTION]") but it doesn't
know how to follow them to the target. Older Windows versions handle
these symlinks exactly the same way, so there's no point using different
symlink types on older Windows. These symlinks only work on filesystems
supporting reparse points, but fortunately there's another symlink type
Cygwin creates, right the next bullet point...
</para></listitem>
<listitem><para>
The original default method creating symlinks in Cygwin since pre-2000
generates symlinks as simple files with a magic header and the DOS
SYSTEM attribute set. When you open a file or directory through such a
symlink, Cygwin opens the file, checks the magic header, and if it's
correct, reads the target of the symlink from the remainder of the file.
Because we don't want having to open every referenced file to check
symlink status, Cygwin only opens files with DOS SYSTEM attribute set to
inspect them for being a Cygwin symlink. These symlinks also work
on filesystems not supporting reparse points, i. e., FAT/FAT32/ExFAT.
</para></listitem>
<listitem><para>
A very special case are NFS filesystems, supported by Cygwin since 2008
via the Microsoft NFS driver, unfortunately only available in Enterprise
versions of Windows. Filesystems shared via NFS usually support symlinks
all by themselves, and the Microsoft driver has special functionality to
support them. Cygwin utilizes this interface to create "real" symlinks
on filesystems mounted via NFS.
</para></listitem>
<listitem><para>
Starting 2013, Cygwin also supports NTFS symlinks, introduced with
Windows Vista. These symlinks are reparse points containing a Windows
path. Creating them is enabled by setting 'winsymlinks:native' or
'winsymlinks:nativestrict' in the environment variable CYGWIN. The
upside of this symlink type is that the path is stored as Windows path
so they are understood by non-Cygwin Windows tools as well. The downsides
are:
<itemizedlist spacing="compact">
<listitem><para>
The path is stored as Windows path, so the path has perhaps to be rearranged
to result in a valid path. This may result in a divergence from the original
POSIX path the user intended.
</para></listitem>
<listitem><para>
Creating NTFS symlinks require administrative privileges by default. You
have to make certain settings in the OS (depending on the Windows version)
to allow creating them as a non-privileged user.
</para></listitem>
<listitem><para>
NTFS symlinks have a type. They are either a "file" or a "directory",
depending on the target file type. This information is utilized especially
by Windows Explorer to show the correct file or directory icon in file
listings without having to check on the target file and to know what
actions are provided by clicking on the symlink. However, if a NTFS
symlink points to a file "foo", and "foo" is deleted and replaced by
a directory "foo", the symlink type of an NTFS symlink pointing to "foo"
is unchanged and subsequently Windows Explorer will misbehave.
Consequentially, creating dangling NTFS symlinks is a nuisance, since
the library does not know what type the still-to-be-created symlink
target will be. Cygwin will not create dangling NTFS symlinks, but
fallback to creating the default symlink type (winsymlinks:native) or
just fail (winsymlinks:nativestrict).
</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>
Another method, available since 2001, is enabled if `winsymlinks' or
'winsymlinks:lnk' is set in the environment variable CYGWIN. Using this
method, Cygwin generates symlinks by creating Windows shortcuts .
Cygwin created shortcuts have a special header (which is never created
by Explorer that way) and the DOS READONLY attribute set. A Windows
path is stored in the shortcut as usual and the POSIX path is stored in
the remainder of the file. While the POSIX path is stored as is, the
Windows path has perhaps to be rearranged to result in a valid path.
This may result in a divergence between the Windows and the POSIX path
when symlinks are moved crossing mount points. When a user changes the
shortcut, this will be detected by Cygwin and it will only use the
Windows path then. While Cygwin shortcuts are shown without the ".lnk"
suffix in `ls' output, non-Cygwin shortcuts are shown with the suffix.
</para>
<para>Both, types of symlinks can live peacefully together since Cygwin
treats both as symlinks regardless of the setting of `(no)winsymlinks' in
the environment variable CYGWIN.
</para>
<para>For enabling this or the preceeding symlink type, see
<ulink url="https://cygwin.com/cygwin-ug-net/using-cygwinenv.html"/>
</para></listitem>
</itemizedlist>
</answer></qandaentry>
<qandaentry id="faq.api.executables">

View File

@ -853,7 +853,7 @@ because they do not always work on Samba drives. Also, mounts are
faster to process because no disk access is required to resolve them.
</para>
<para>Note that non-cygwin applications will not observe Cygwin mounts (or
symlinks for that matter). For example, if you use WinZip to unpack the
most symlinks for that matter). For example, if you use WinZip to unpack the
tar distribution of a Cygwin package, it may not get installed to the
correct Cygwin path. <emphasis>So don't do this!</emphasis>
</para>
@ -967,10 +967,10 @@ set you're using in future.</para>
<question><para>Why don't symlinks work on Samba-mounted filesystems?</para></question>
<answer>
<para>Symlinks are marked with "system" file attribute. Samba does not
enable this attribute by default. To enable it, consult your Samba
documentation and then add these lines to your samba configuration
file:
<para>Default symlinks on Samba are marked with DOS SYSTEM file
attribute. Samba does not enable this attribute by default. To enable
it, consult your Samba documentation and then add these lines to your
samba configuration file:
</para>
<screen>
map system = yes
@ -980,8 +980,10 @@ file:
<para>Note that the 0775 can be anything as long as the 0010 bit is set.
</para>
<para>Alternatively, use Windows shortcuts as symlinks. See the CYGWIN
environment variable option "winsymlinks"
environment variable option "winsymlinks:lnk"
<ulink url="https://cygwin.com/cygwin-ug-net/using-cygwinenv.html"/>
Note that Samba does not support reparse points so some methods to
create symlinks are just not available.
</para>
</answer></qandaentry>

View File

@ -377,51 +377,41 @@ like this:</para>
<sect2 id="pathnames-symlinks"><title>Symbolic links</title>
<para>Symbolic links are not present and supported on Windows until Windows
Vista/Server 2008, and then only on some filesystems. Since POSIX applications
are rightfully expecting to use symlinks and the
<literal>symlink(2)</literal> system call, Cygwin had to find a
workaround for this Windows flaw.</para>
<para>Symbolic links are supported by Windows only on NTFS and have
a lot of quirks making them (almost) unusable in a POSIX context.
POSIX applications are rightfully expecting to use symlinks and the
<literal>symlink(2)</literal> system call, so Cygwin has worked around
the Windows shortcomings.</para>
<para>Cygwin creates symbolic links potentially in multiple different
ways:</para>
ways.</para>
<itemizedlist mark="bullet">
<listitem>
<para>The default symlinks are plain files containing a magic cookie
followed by the path to which the link points. They are marked with the
DOS SYSTEM attribute so that only files with that attribute have to be
read to determine whether or not the file is a symbolic link.</para>
<para>The default symlinks created by Cygwin are either special reparse
points shared with WSL on Windows 10, or plain files containing a magic
cookie followed by the path to which the link points. The reparse point
is used on NTFS, the plain file on almost any other filesystem.</para>
<note><para>Cygwin symbolic links are using UTF-16 to encode the filename of
the target file, to better support internationalization. Symlinks created by
old Cygwin releases can be read just fine. However, you could run into
problems with them if you're now using another character set than the one you
used when creating these symlinks
(see <xref linkend="setup-locale-problems"></xref>).
<note><para>Symlinks created by really old Cygwin releases (prior to
Cygwin 1.7.0) are usually readable. However, you could run into problems
if you're now using another character set than the one you used when
creating these symlinks (see <xref linkend="setup-locale-problems"></xref>).
</para></note>
</listitem>
<listitem>
<para>The shortcut style symlinks are Windows <literal>.lnk</literal>
shortcut files with a special header and the DOS READONLY attribute set.
This symlink type is created if the environment variable
<literal>CYGWIN</literal> (see <xref linkend="using-cygwinenv"></xref>)
is set to contain the string <literal>winsymlinks</literal> or
<literal>winsymlinks:lnk</literal>. On the MVFS filesystem, which does
not support the DOS SYSTEM attribute, this is the one and only supported
symlink type, independently from the <literal>winsymlinks</literal>
setting.</para>
<para>On filesystems mounted via Microsoft's NFS client, Cygwin always
creates real NFS symlinks.</para>
</listitem>
<listitem>
<para>Native Windows symlinks are only created on Windows Vista/2008 and later,
and only on filesystems supporting reparse points. Due to to their weird
restrictions and behaviour, they are only created if the user
explicitely requests creating them. This is done by setting the
environment variable <literal>CYGWIN</literal> to contain the string
<literal>winsymlinks:native</literal> or
<para>Native Windows symlinks are only created on filesystems supporting
reparse points. Due to their weird restrictions and behaviour, they are
only created if the user explicitely requests creating them. This is done
by setting the environment variable <literal>CYGWIN</literal> to contain
the string <literal>winsymlinks:native</literal> or
<literal>winsymlinks:nativestrict</literal>. For the difference between
these two settings, see <xref linkend="using-cygwinenv"></xref>.
On AFS, native symlinks are the only supported type of symlink due to
@ -433,21 +423,28 @@ symlinks that lie in the target path.</para>
</listitem>
<listitem>
<para>On the NFS filesystem, Cygwin always creates real NFS symlinks.</para>
<para>Shortcut style symlinks are Windows <literal>.lnk</literal>
shortcut files with a special header and the DOS READONLY attribute set.
This symlink type is created if the environment variable
<literal>CYGWIN</literal> (see <xref linkend="using-cygwinenv"></xref>)
is set to contain the string <literal>winsymlinks</literal> or
<literal>winsymlinks:lnk</literal>. On the MVFS filesystem, which does
not support the DOS SYSTEM attribute, this is the one and only supported
symlink type, independently from the <literal>winsymlinks</literal>
setting.</para>
</listitem>
</itemizedlist>
<para>All of the above four symlink types are recognized and used as symlinks
<para>All of the above symlink types are recognized and used as symlinks
under all circumstances. However, if the default plain file symlink type
is lacking its DOS SYSTEM bit, or if the shortcut file is lacking the DOS
READONLY attribute, they are not recognized as symlink.</para>
<para>Apart from these four types, there's also a fifth type, which is
recognized as symlink but never generated by Cygwin, directory
junctions. This is an older reparse point type, supported by Windows
since Windows 2000. Filesystem junctions on the other hand are not
handled as symlinks, since otherwise they would not be recognized as
<para>Apart from these types, there's also a Windows native type,
so called directory junctions. They are recognized as symlink but
never generated by Cygwin. Filesystem junctions on the other hand
are not handled as symlinks, otherwise they would not be recognized as
filesystem borders by commands like <command>find -xdev</command>.</para>
</sect2>

View File

@ -37,8 +37,7 @@ is allowed to be a Cygwin symlink either.</para>
<para>However, native NTFS symlinks and reparse points are transparent
when accessing the above files so all these files as well as
<filename>/etc</filename> itself may be NTFS symlinks or reparse
points.</para>
<filename>/etc</filename> itself may be NTFS symlinks.</para>
<para>Last but not least, make sure that these files are world-readable.
Every process of any user account has to read these files potentially,