diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 15 | ||||
-rw-r--r-- | winsup/cygwin/environ.cc | 19 | ||||
-rw-r--r-- | winsup/cygwin/globals.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 27 | ||||
-rw-r--r-- | winsup/cygwin/shared_info.h | 3 |
5 files changed, 55 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ff3a31f..e91432d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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 diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 175c516..f73c232 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -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 diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 9462c7a..da732a4 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -56,6 +56,7 @@ enum winsym_t WSYM_sysfile = 0, WSYM_lnk, WSYM_native, + WSYM_nativestrict, WSYM_nfs }; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 0567a91..16571b1 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -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, diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index f3605e4..6733b36 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -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); |