aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/environ.cc19
-rw-r--r--winsup/cygwin/globals.cc1
-rw-r--r--winsup/cygwin/path.cc27
-rw-r--r--winsup/cygwin/shared_info.h3
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);