From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 4B4083858C66; Fri, 17 Nov 2023 12:06:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B4083858C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com; s=default; t=1700222804; bh=2MxJWFgjR3NwI59LafNauvI6jUpg9nrFSlQi/OqpGOU=; h=Date:From:To:Subject:Reply-To:References:In-Reply-To:From; b=gc1J3/hUX2gUXndNWdxHk05GfCo/1GSfFMwLB+1eIS/UpT3BVXXVcibIjTroHGQ8R 8jvnFGKz7nUekO54RIoXGKuRpo+Ak3Yu1w39/zdZknxSrSOd0ZNMx+GSamY81nVe0v RmjKPBZS9dBP86RbYmiMU6QKKcNzDQAu3O7h543g= Received: by calimero.vinschen.de (Postfix, from userid 500) id 6DC9EA80BE0; Fri, 17 Nov 2023 13:06:42 +0100 (CET) Date: Fri, 17 Nov 2023 13:06:42 +0100 From: Corinna Vinschen To: cygwin@cygwin.com Subject: Re: Cygwin tool to differ junctions from soft links? Message-ID: Reply-To: cygwin@cygwin.com Mail-Followup-To: cygwin@cygwin.com References: <48998319.20231116114707@yandex.ru> <1439487749.2493319.1700160923985@mail.yahoo.com> <6752f3b0-0fbf-4709-976c-12030285e0bb@Shaw.ca> <39d6c013-f929-49c1-948a-810383959a1b@towo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <39d6c013-f929-49c1-948a-810383959a1b@towo.net> List-Id: 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