Index: cygwin/environ.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/environ.cc,v retrieving revision 1.196 diff -u -p -r1.196 environ.cc --- cygwin/environ.cc 21 Aug 2011 18:45:07 -0000 1.196 +++ cygwin/environ.cc 4 Dec 2011 06:17:15 -0000 @@ -35,6 +35,7 @@ details. */ extern bool dos_file_warning; extern bool ignore_case_with_glob; extern bool allow_winsymlinks; +extern bool allow_nativesymlinks; bool reset_com = false; static char **lastenviron; @@ -124,6 +125,7 @@ static struct parse_thing {"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}}, {"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}}, {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}}, + {"nativesymlinks", {&allow_nativesymlinks}, justset, NULL, {{false}, {true}}}, {NULL, {0}, justset, 0, {{0}, {0}}} }; Index: cygwin/path.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/path.cc,v retrieving revision 1.640 diff -u -p -r1.640 path.cc --- cygwin/path.cc 3 Dec 2011 21:43:26 -0000 1.640 +++ cygwin/path.cc 4 Dec 2011 06:17:15 -0000 @@ -1413,16 +1413,17 @@ conv_path_list (const char *src, char *d /* If TRUE create symlinks as Windows shortcuts, if false create symlinks as normal files with magic number and system bit set. */ bool allow_winsymlinks = false; +bool allow_nativesymlinks = false; extern "C" int symlink (const char *oldpath, const char *newpath) { - return symlink_worker (oldpath, newpath, allow_winsymlinks, false); + return symlink_worker (oldpath, newpath, allow_winsymlinks, allow_nativesymlinks, false); } int symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, - bool isdevice) + bool use_nativesym, bool isdevice) { int res = -1; size_t len; @@ -1436,7 +1437,8 @@ symlink_worker (const char *oldpath, con ULONG access = DELETE | FILE_GENERIC_WRITE; tmp_pathbuf tp; unsigned check_opt; - bool mk_winsym = use_winsym; + bool mk_winsym = use_winsym && !use_nativesym; + bool mk_nativesym = use_nativesym; bool has_trailing_dirsep = false; /* POSIX says that empty 'newpath' is invalid input while empty @@ -1471,8 +1473,12 @@ symlink_worker (const char *oldpath, con win32_newpath.check (newpath, check_opt, stat_suffixes); /* MVFS doesn't handle the SYSTEM DOS attribute, but it handles the R/O attribute. Therefore we create symlinks on MVFS always as shortcuts. */ - mk_winsym |= win32_newpath.fs_is_mvfs (); - + if (win32_newpath.fs_is_mvfs ()) + { + mk_winsym = true; + mk_nativesym = false; + } + if (mk_winsym && !win32_newpath.exists () && (isdevice || !win32_newpath.fs_is_nfs ())) { @@ -1530,6 +1536,27 @@ symlink_worker (const char *oldpath, con goto done; } + if (mk_nativesym) + { + win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes); + DWORD dwFlags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; + if (isabspath (oldpath)) + { + res = CreateSymbolicLink (win32_newpath.get_win32 (), win32_oldpath.get_win32 (), dwFlags) ? 0 : -1; + } + else + { + char *oldpath_trans = strdup (oldpath); + // Transform path separators + for (char *p = oldpath_trans; (p = strchr (p, '/')); p++) + *p = '\\'; + + res = CreateSymbolicLink (win32_newpath.get_win32 (), oldpath_trans, dwFlags) ? 0 : -1; + free (oldpath_trans); + } + goto done; + } + if (mk_winsym) { ITEMIDLIST *pidl = NULL; Index: cygwin/syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.604 diff -u -p -r1.604 syscalls.cc --- cygwin/syscalls.cc 3 Dec 2011 23:55:21 -0000 1.604 +++ cygwin/syscalls.cc 4 Dec 2011 06:17:15 -0000 @@ -2923,7 +2923,7 @@ mknod_worker (const char *path, mode_t t char buf[sizeof (":\\00000000:00000000:00000000") + PATH_MAX]; sprintf (buf, ":\\%x:%x:%x", major, minor, type | (mode & (S_IRWXU | S_IRWXG | S_IRWXO))); - return symlink_worker (buf, path, true, true); + return symlink_worker (buf, path, true, false, true); } extern "C" int Index: cygwin/winsup.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/winsup.h,v retrieving revision 1.240 diff -u -p -r1.240 winsup.h --- cygwin/winsup.h 14 Nov 2011 01:29:49 -0000 1.240 +++ cygwin/winsup.h 4 Dec 2011 06:17:15 -0000 @@ -248,7 +248,7 @@ extern "C" void vklog (int priority, con extern "C" void klog (int priority, const char *message, ...); bool child_copy (HANDLE, bool, ...); -int symlink_worker (const char *, const char *, bool, bool) +int symlink_worker (const char *, const char *, bool, bool, bool) __attribute__ ((regparm (3))); class path_conv;