So would you be for specific methods to check if a given path is a junction?
On 11/7/22, Charles Machalow <csm10495@gmail.com> wrote:
>
> Junctions are contextually similar to symlinks on Windows.
Junctions (i.e. IO_REPARSE_TAG_MOUNT_POINT) are implemented to behave
as mount points for local volumes, so there are a couple of important
differences.
In a remote path, a junction gets resolved on the server side, which
is always possible because the target of a junction must be a local
volume (i.e. local to the server). Thus a junction that targets
"C:\spam" resolves to the "C:" drive on the remote system. If you're
resolving a junction manually via `os.readlink()`, take care to never
resolve a remote junction target as a local path such as "C:\spam".
That would not only be wrong but also potentially harmful if client
files get mistakenly modified, replaced, or deleted. On the other
hand, a remote symlink that targets "C:\spam" gets resolved by the
client and thus always resolves to the local "C:" drive of the client.
This depends on the client system allowing remote-to-local (R2L)
symlinks, which is disabled by default for good reason. When resolving
a symlink manually, at worst you'll be in violation of the system's
L2L, L2R, R2L, or R2R symlink policy.
Secondly, the target of a junction does not replace the previously
traversed path when the system parses a path. This affects how a
relative symlink gets resolved, in which case traversed junctions
behave like Unix bind mount points. Say that "E:\eggs\spamlink" is a
relative symlink that targets "..\spam". When accessed directly, this
symbolic link resolves to "E:\spam". Say that "C:\mount\junction"
targets "E:\eggs". Then "C:\mount\junction\spamlink" resolves to
"C:\mount\spam", a different file in this case. In contrast, the
target of a symlink always replaces the traversed path when the system
parse a path. Say that "C:\mount\symlink" targets "E:\eggs". Then
"C:\mount\symlink\spamlink" resolves to "E:\spam", the same as if
"E:\eggs\spamlink" had been opened directly.
> Currently is_symlink/islink return False for junctions.
Some API contexts, libraries, and applications only support
IO_REPARSE_POINT_SYMLINK reparse points as symlinks. For general
compatibility that's the only type of reparse point that reliably
counts as a "symlink".
Also, part of the rationale for this division is that currently we
cannot copy a junction via os.readlink() and os.symlink(). If we were
to copy a junction as a symlink, in general this could change how the
target path is resolved or how the link behaves in the context of
relative symlinks.
It would be less of an issue if os.readlink() returned an object type
that allowed duplicating any name-surrogate reparse point via
os.symlink(). Instead of calling WinAPI CreateSymbolicLinkW() in such
cases, os.symlink() would create the target file/directory and
directly set the reparse point via FSCTL_SET_REPARSE_POINT.