public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Corinna Vinschen <corinna-cygwin@cygwin.com>
To: cygwin@cygwin.com
Subject: Re: Cygwin tool to differ junctions from soft links?
Date: Fri, 17 Nov 2023 13:06:42 +0100	[thread overview]
Message-ID: <ZVdXUoh/2xnqQCse@calimero.vinschen.de> (raw)
In-Reply-To: <39d6c013-f929-49c1-948a-810383959a1b@towo.net>

On Nov 17 06:54, Thomas Wolff via Cygwin wrote:
> 
> 
> Am 16.11.2023 um 21:30 schrieb Brian Inglis via Cygwin:
> > On 2023-11-16 11:55, matthew patton via Cygwin wrote:
> > > On Thursday, November 16, 2023 at 03:50:24 AM EST, Andrey Repin wrote:
> > > > > Does Cygwin have a command line tool (Scriptable!) which can
> > > > > be used to
> > > > > differ between soft links and Windows junctions?
> > 
> > Distinguishing between types of Windows reparse points is not a POSIX or
> > emulation function, so not of interest to Cygwin developers.
> > 
> > I thought about it when support was added, but then realized there was
> > no nice place to add it within the platform, without going the
> > non-portable Windows specific utility route, as in lsattr.
> > 
> > You could in a function or script by running lsattr -d which seems to
> > fail on reparse points, then ls -dl which shows a Symbolic Link with a
> > relative path, and a Junction with an absolute path, although it could
> > just be a Symbolic Link with an absolute path.
> lsattr has an explicit flag:
>              'r', 'Reparse':       file or directory that has a reparse
> point
> I don't know whether it's the same as a junction, otherwise a 'j' flag could
> be added.

lsattr is basically a frontend for the ioctl(FS_IOC_GETFLAGS) call.
It centers around showing file attributes.  DOS attributes as per
https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
know about reparse points, but only as a flag.

Just as its Linux counterpart showing ext[234] attributes, lsattr only
works on regular files and directories.  If you try to run it on
a file Cygwin handles as a symbolic link, you get an error:

  $ mkdir foo
  $ ln -s foo bar
  $ lsattr -d foo bar
  ------------ foo
  lsattr: Not supported on bar

  $ cmd /c mklink /j baz foo
  Junction created for baz <<===>> foo
  $ ls -l
  total 0
  lrwxrwxrwx 1 corinna vinschen  3 Nov 17 11:28 bar -> foo
  lrwxrwxrwx 1 corinna vinschen 23 Nov 17 11:29 baz -> /home/corinna/tmp/x/foo
  drwxr-xr-x 1 corinna vinschen  0 Nov 17 11:28 foo
  $ lsattr -d foo bar baz
  ------------ foo
  lsattr: Not supported on bar
  lsattr: Not supported on baz

Actually, even if you run lsattr on a reparse point NOT handled as a
symlink, you probably won't see the Reparse attribute at all.

The reason is that the open(2) call doesn't expose a way to POSIX apps
to open a reparse point as reparse point.  There's just no POSIX flag
for that, given the entire concept of reparse points is alien.

As a result, the underlying Windows kernel NtCreateFile call will try to
reparse.  If the reparse point is one known to the OS, or a reparse point
which is handled by some driver, you'll see the attributes of the reparse
target.  Volume mount points are a known variety not handled as symlink
by Cygwin.  Open the volume mount point with open(2), and you actually
opened the root directory of the mounted filesystem.

Funny enough, same goes for Windows attrib.exe tool...

Having said that, I don't see an easy way to provide the required
information from inside Cygwin by providing an API for stuff like that.

If you want to see this kind of information, there are ways.  For
instance, a tool can do something like that:

  lstat("foo");
  if (S_ISLNK("foo"))
    {
      HANDLE h = CreateFile("foo", ..., FILE_FLAG_OPEN_REPARSE_POINT, ...);
      if (h != INVALID_HANDLE_VALUE)
	{
	  FILE_ATTRIBUTE_TAG_INFO at;
	  if (GetFileInformationByHandleEx (h, FileAttributeTagInfo,
					    &at, sizeof at))
	    {
	      if (at.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
	        {
		  /* Check at.ReparseTag:
		  IO_REPARSE_TAG_LX_SYMLINK: WSL symlink
		  IO_REPARSE_TAG_SYMLINK: Windows symlink
		  IO_REPARSE_TAG_MOUNT_POINT: Volume mount point
					      or directory junction
		  IO_REPARSE_TAG_APPEXECLINK: App execution alias
		  Anything else: *shrug*
		}
	    }
	}
    }



Corinna

  reply	other threads:[~2023-11-17 12:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-01  9:14 Martin Wege
2023-11-16  7:29 ` Martin Wege
2023-11-17  1:59   ` Doug Henderson
2023-11-16  8:47 ` Andrey Repin
2023-11-16 18:55   ` matthew patton
2023-11-16 20:30     ` Brian Inglis
2023-11-17  5:54       ` Thomas Wolff
2023-11-17 12:06         ` Corinna Vinschen [this message]
2023-11-17 14:56         ` Brian Inglis
2023-11-17 18:44           ` matthew patton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZVdXUoh/2xnqQCse@calimero.vinschen.de \
    --to=corinna-cygwin@cygwin.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).