* environ.cc (set_winsymlinks): Handle "winsymlinks:nativestrict"

option.  On pre-Vista warn the user if the "winsymlinks:native*" option
	is set.
	* globals.cc (enum winsym_t): Add WSYM_nativestrict.
	* path.cc (symlink_native): Don't create native symlink if target
	does not exist.  Explain why.  Improve comments.
	(symlink_worker): Change AFS symlink handling to WSYM_nativestrict.
	Handle WSYM_nativestrict throughout.  Change condition for bail out
	to wsym_type == WSYM_nativestrict.  Add comment.  Fix formatting.
	* shared_info.h (CURR_USER_MAGIC): Change to reflect change in
	class user_info.
	(class user_info): Add member warned_nonativesyms.
This commit is contained in:
Corinna Vinschen 2013-05-23 14:23:01 +00:00
parent 08fd0f6438
commit 33cb946e7e
5 changed files with 55 additions and 10 deletions

View File

@ -1,3 +1,18 @@
2013-05-23 Corinna Vinschen <corinna@vinschen.de>
* environ.cc (set_winsymlinks): Handle "winsymlinks:nativestrict"
option. On pre-Vista warn the user if the "winsymlinks:native*" option
is set.
* globals.cc (enum winsym_t): Add WSYM_nativestrict.
* path.cc (symlink_native): Don't create native symlink if target
does not exist. Explain why. Improve comments.
(symlink_worker): Change AFS symlink handling to WSYM_nativestrict.
Handle WSYM_nativestrict throughout. Change condition for bail out
to wsym_type == WSYM_nativestrict. Add comment. Fix formatting.
* shared_info.h (CURR_USER_MAGIC): Change to reflect change in
class user_info.
(class user_info): Add member warned_nonativesyms.
2013-05-22 Corinna Vinschen <corinna@vinschen.de>
* spinlock.h (ULONG): Replace LONG operator with ULONG to accommodate

View File

@ -97,9 +97,22 @@ set_winsymlinks (const char *buf)
else if (ascii_strncasematch (buf, "lnk", 3))
allow_winsymlinks = WSYM_lnk;
/* Make sure to try native symlinks only on systems supporting them. */
else if (ascii_strncasematch (buf, "native", 6)
&& wincap.max_sys_priv () >= SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
allow_winsymlinks = WSYM_native;
else if (ascii_strncasematch (buf, "native", 6))
{
if (wincap.max_sys_priv () < SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
{
if (!user_shared->warned_nonativesyms)
{
small_printf ("\"winsymlinks:%s\" option detected in CYGWIN environment variable.\n"
"Native symlinks are not supported on Windows versions prior to\n"
"Windows Vista/Server 2008. This option will be ignored.\n", buf);
user_shared->warned_nonativesyms = 1;
}
}
else
allow_winsymlinks = ascii_strcasematch (buf + 6, "strict")
? WSYM_nativestrict : WSYM_native;
}
}
/* The structure below is used to set up an array which is used to

View File

@ -56,6 +56,7 @@ enum winsym_t
WSYM_sysfile = 0,
WSYM_lnk,
WSYM_native,
WSYM_nativestrict,
WSYM_nfs
};

View File

@ -1542,9 +1542,19 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
final_oldpath = win32_oldpath.get_nt_native_path ();
final_oldpath->Buffer += dirpath.Length / sizeof (WCHAR);
}
/* If the symlink target doesn't exist, don't create native symlink.
Otherwise the directory flag in the symlink is potentially wrong
when the target comes into existence, and native tools will fail.
This is so screwball. This is no problem on AFS, fortunately. */
if (!win32_oldpath.exists () && !win32_oldpath.fs_is_afs ())
{
SetLastError (ERROR_FILE_NOT_FOUND);
return -1;
}
/* Convert native path to DOS UNC path. */
final_newpath = win32_newpath.get_nt_native_path ();
/* Convert native to DOS UNC path. */
final_newpath->Buffer[1] = L'\\';
/* Try to create native symlink. */
if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer,
win32_oldpath.isdir ()
? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))
@ -1618,10 +1628,10 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
set_errno (EPERM);
goto done;
}
wsym_type = WSYM_native;
wsym_type = WSYM_nativestrict;
}
/* Don't try native symlinks on filesystems not supporting reparse points. */
else if (wsym_type == WSYM_native
else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict)
&& !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS))
wsym_type = WSYM_sysfile;
@ -1662,13 +1672,17 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
res = symlink_nfs (oldpath, win32_newpath);
goto done;
case WSYM_native:
case WSYM_nativestrict:
res = symlink_native (oldpath, win32_newpath);
/* AFS? Too bad. Otherwise, just try the default symlink type. */
if (win32_newpath.fs_is_afs ())
if (!res)
goto done;
/* Strictly native? Too bad. */
if (wsym_type == WSYM_nativestrict)
{
__seterrno ();
goto done;
}
/* Otherwise, fall back to default symlink type. */
wsym_type = WSYM_sysfile;
break;
default:
@ -1853,7 +1867,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
so for now we don't request WRITE_DAC on remote drives. */
access |= READ_CONTROL | WRITE_DAC;
status = NtCreateFile (&fh, access, win32_newpath.get_object_attr (attr, sec_none_nih),
status = NtCreateFile (&fh, access,
win32_newpath.get_object_attr (attr, sec_none_nih),
&io, NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_VALID_FLAGS,
isdevice ? FILE_OVERWRITE_IF : FILE_CREATE,

View File

@ -15,7 +15,7 @@ details. */
#include "limits.h"
#include "mount.h"
#define CURR_USER_MAGIC 0x6467403bU
#define CURR_USER_MAGIC 0xab1fcce8U
class user_info
{
@ -25,6 +25,7 @@ public:
DWORD cb;
bool warned_msdos;
bool warned_notty;
bool warned_nonativesyms;
mount_info mountinfo;
friend void dll_crt0_1 (void *);
static void create (bool);