Cygwin: path_conv: add PC_SYM_NOFOLLOW_DIR flag
Usually a trailing slash requires to follow an existing symlink, even with PC_SYM_NOFOLLOW. The reason is that "foo/" is equivalent to "foo/." so the symlink is in fact not the last path component, "." is. This is default for almost all scenarios. PC_SYM_NOFOLLOW_DIR now allows the caller to request not to follow the symlink even if a trailing slash is given. This can be used in callers to perform certain functions Linux-compatible. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
6d9cfcc578
commit
61f3dd6d2d
|
@ -1022,20 +1022,33 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
these operations again on the newly derived path. */
|
these operations again on the newly derived path. */
|
||||||
else if (symlen > 0)
|
else if (symlen > 0)
|
||||||
{
|
{
|
||||||
if (component == 0 && !need_directory
|
if (component == 0
|
||||||
&& (!(opt & PC_SYM_FOLLOW)
|
&& (!(opt & PC_SYM_FOLLOW)
|
||||||
|| (is_known_reparse_point ()
|
|| (is_known_reparse_point ()
|
||||||
&& (opt & PC_SYM_NOFOLLOW_REP))))
|
&& (opt & PC_SYM_NOFOLLOW_REP))))
|
||||||
{
|
{
|
||||||
/* last component of path is a symlink. */
|
/* Usually a trailing slash requires to follow a symlink,
|
||||||
set_symlink (symlen);
|
even with PC_SYM_NOFOLLOW. The reason is that "foo/"
|
||||||
if (opt & PC_SYM_CONTENTS)
|
is equivalent to "foo/." so the symlink is in fact not
|
||||||
|
the last path component.
|
||||||
|
|
||||||
|
PC_SYM_NOFOLLOW_DIR is used to indicate that the
|
||||||
|
last path component is the target symlink and the
|
||||||
|
trailing slash is supposed to be ignored. */
|
||||||
|
if (!need_directory || (opt & PC_SYM_NOFOLLOW_DIR))
|
||||||
{
|
{
|
||||||
strcpy (THIS_path, sym.contents);
|
/* last component of path is a symlink. */
|
||||||
|
set_symlink (symlen);
|
||||||
|
/* make sure not to set errno to ENOTDIR. */
|
||||||
|
need_directory = 0;
|
||||||
|
if (opt & PC_SYM_CONTENTS)
|
||||||
|
{
|
||||||
|
strcpy (THIS_path, sym.contents);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
add_ext = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
add_ext = true;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
/* Following a symlink we can't trust the collected
|
/* Following a symlink we can't trust the collected
|
||||||
filesystem information any longer. */
|
filesystem information any longer. */
|
||||||
|
|
|
@ -59,6 +59,7 @@ enum pathconv_arg
|
||||||
PC_SYM_NOFOLLOW_PROCFD = _BIT (11), /* allow /proc/PID/fd redirection */
|
PC_SYM_NOFOLLOW_PROCFD = _BIT (11), /* allow /proc/PID/fd redirection */
|
||||||
PC_KEEP_HANDLE = _BIT (12), /* keep handle for later stat calls */
|
PC_KEEP_HANDLE = _BIT (12), /* keep handle for later stat calls */
|
||||||
PC_NO_ACCESS_CHECK = _BIT (13), /* helper flag for error check */
|
PC_NO_ACCESS_CHECK = _BIT (13), /* helper flag for error check */
|
||||||
|
PC_SYM_NOFOLLOW_DIR = _BIT (14), /* don't follow a trailing slash */
|
||||||
PC_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
PC_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue