[newlib-cygwin] Cygwin: docs: revamp docs explaining symlinks

Corinna Vinschen corinna@sourceware.org
Fri Apr 3 19:45:11 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=44fe41a766b1f4dbb6d2f16523aea3507d10b6ef

commit 44fe41a766b1f4dbb6d2f16523aea3507d10b6ef
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Fri Apr 3 21:44:00 2020 +0200

    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>

Diff:
---
 winsup/doc/faq-api.xml      | 131 ++++++++++++++++++++++++++++++++++----------
 winsup/doc/faq-using.xml    |  14 +++--
 winsup/doc/pathnames.xml    |  75 ++++++++++++-------------
 winsup/doc/specialnames.xml |   3 +-
 4 files changed, 146 insertions(+), 77 deletions(-)

diff --git a/winsup/doc/faq-api.xml b/winsup/doc/faq-api.xml
index a95dbdd31..313f15d37 100644
--- a/winsup/doc/faq-api.xml
+++ b/winsup/doc/faq-api.xml
@@ -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>
-
-<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.
-</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>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>
+
+<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>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">
diff --git a/winsup/doc/faq-using.xml b/winsup/doc/faq-using.xml
index 4fca00525..4c6d8c76d 100644
--- a/winsup/doc/faq-using.xml
+++ b/winsup/doc/faq-using.xml
@@ -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>
 
diff --git a/winsup/doc/pathnames.xml b/winsup/doc/pathnames.xml
index 6f9fefa24..2966bdabf 100644
--- a/winsup/doc/pathnames.xml
+++ b/winsup/doc/pathnames.xml
@@ -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>
-
-<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>).
+<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>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>
diff --git a/winsup/doc/specialnames.xml b/winsup/doc/specialnames.xml
index 1120f86b1..a1f7401e1 100644
--- a/winsup/doc/specialnames.xml
+++ b/winsup/doc/specialnames.xml
@@ -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,


More information about the Cygwin-cvs mailing list