diff -BurN newlib-cygwin/winsup/cygwin/environ.cc newlib-cygwin.new/winsup/cygwin/environ.cc --- newlib-cygwin/winsup/cygwin/environ.cc 2016-10-05 10:52:41.219364200 +0800 +++ newlib-cygwin.new/winsup/cygwin/environ.cc 2016-10-05 10:45:36.515617700 +0800 @@ -83,8 +83,14 @@ allow_winsymlinks = WSYM_lnk; /* Make sure to try native symlinks only on systems supporting them. */ else if (ascii_strncasematch (buf, "native", 6)) - allow_winsymlinks = ascii_strcasematch (buf + 6, "strict") - ? WSYM_nativestrict : WSYM_native; + { + if (ascii_strcasematch (buf + 6, "strict")) + allow_winsymlinks = WSYM_nativestrict; + else if (ascii_strcasematch (buf + 6, "nocheck")) + allow_winsymlinks = WSYM_nativenocheck; + else + allow_winsymlinks = WSYM_native; + } } /* The structure below is used to set up an array which is used to diff -BurN newlib-cygwin/winsup/cygwin/globals.cc newlib-cygwin.new/winsup/cygwin/globals.cc --- newlib-cygwin/winsup/cygwin/globals.cc 2016-08-31 20:26:12.000000000 +0800 +++ newlib-cygwin.new/winsup/cygwin/globals.cc 2016-10-05 10:45:36.092064000 +0800 @@ -55,6 +55,7 @@ WSYM_lnk, WSYM_native, WSYM_nativestrict, + WSYM_nativenocheck, WSYM_nfs }; diff -BurN newlib-cygwin/winsup/cygwin/path.cc newlib-cygwin.new/winsup/cygwin/path.cc --- newlib-cygwin/winsup/cygwin/path.cc 2016-10-05 10:52:47.321209000 +0800 +++ newlib-cygwin.new/winsup/cygwin/path.cc 2016-10-05 10:45:36.181133500 +0800 @@ -1649,7 +1649,7 @@ } static int -symlink_native (const char *oldpath, path_conv &win32_newpath) +symlink_native (const char *oldpath, path_conv &win32_newpath, int checkflag) { tmp_pathbuf tp; path_conv win32_oldpath; @@ -1719,7 +1719,7 @@ 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 ()) + if (!win32_oldpath.exists () && !win32_oldpath.fs_is_afs () && checkflag == 1) { SetLastError (ERROR_FILE_NOT_FOUND); return -1; @@ -1752,9 +1752,17 @@ final_oldpath->Buffer[1] = L'\\'; } /* Try to create native symlink. */ - if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer, - win32_oldpath.isdir () - ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0)) + /* For non-exist target, treat path with slash in the end as directory */ + int isdirflag =0; + if (win32_oldpath.isdir ()) + isdirflag=SYMBOLIC_LINK_FLAG_DIRECTORY; + else if (!win32_oldpath.exists () && checkflag == 0) + { + char *lastslash=strrchr(oldpath,'/'); + if(lastslash && strlen(oldpath) - (lastslash-oldpath) == 1) + isdirflag=SYMBOLIC_LINK_FLAG_DIRECTORY; + } + if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer,isdirflag)) { /* Repair native newpath, we still need it. */ final_newpath->Buffer[1] = L'?'; @@ -1819,7 +1827,8 @@ else if (win32_newpath.fs_is_afs ()) wsym_type = WSYM_nativestrict; /* Don't try native symlinks on FSes not supporting reparse points. */ - else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict) + else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict + || wsym_type == WSYM_nativenocheck) && !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS)) wsym_type = WSYM_sysfile; @@ -1861,7 +1870,7 @@ __leave; case WSYM_native: case WSYM_nativestrict: - res = symlink_native (oldpath, win32_newpath); + res = symlink_native (oldpath, win32_newpath,1); if (!res) __leave; /* Strictly native? Too bad, unless the target is a Cygwin @@ -1874,6 +1883,16 @@ /* Otherwise, fall back to default symlink type. */ wsym_type = WSYM_sysfile; break; + case WSYM_nativenocheck: + res = symlink_native (oldpath, win32_newpath,0); + if (!res) + __leave; + else if (res == -1) + { + __seterrno (); + __leave; + } + break; default: break; }