aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/mingw.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index 41dba9857..a6362333d 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1063,6 +1063,41 @@ int link(const char *oldpath, const char *newpath)
1063 return 0; 1063 return 0;
1064} 1064}
1065 1065
1066#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
1067# define SYMBOLIC_LINK_FLAG_DIRECTORY (0x1)
1068#endif
1069#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
1070# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2)
1071#endif
1072
1073int symlink(const char *target, const char *linkpath)
1074{
1075 DWORD flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
1076 struct stat st;
1077 DECLARE_PROC_ADDR(BOOL, CreateSymbolicLinkA, LPCSTR, LPCSTR, DWORD);
1078
1079 if (!INIT_PROC_ADDR(kernel32.dll, CreateSymbolicLinkA)) {
1080 return -1;
1081 }
1082
1083 if (stat(target, &st) != -1 && S_ISDIR(st.st_mode))
1084 flag |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1085
1086 retry:
1087 if (!CreateSymbolicLinkA(linkpath, target, flag)) {
1088 /* Old Windows versions see 'UNPRIVILEGED_CREATE' as an invalid
1089 * parameter. Retry without it. */
1090 if ((flag & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) &&
1091 GetLastError() == ERROR_INVALID_PARAMETER) {
1092 flag &= ~SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
1093 goto retry;
1094 }
1095 errno = err_win_to_posix();
1096 return -1;
1097 }
1098 return 0;
1099}
1100
1066static char *normalize_ntpathA(char *buf) 1101static char *normalize_ntpathA(char *buf)
1067{ 1102{
1068 /* fix absolute path prefixes */ 1103 /* fix absolute path prefixes */