Skip to content

Commit 6668c8a

Browse files
kbleesGit for Windows Build Agent
authored andcommitted
Win32: implement basic symlink() functionality (file symlinks only)
Implement symlink() that always creates file symlinks. Fails with ENOSYS if symlinks are disabled or unsupported. Note: CreateSymbolicLinkW() was introduced with symlink support in Windows Vista. For compatibility with Windows XP, we need to load it dynamically and fail gracefully if it isnt's available. Signed-off-by: Karsten Blees <[email protected]>
1 parent b171157 commit 6668c8a

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

compat/mingw/compat-util.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2994,6 +2994,34 @@ int link(const char *oldpath, const char *newpath)
29942994
return 0;
29952995
}
29962996

2997+
int symlink(const char *target, const char *link)
2998+
{
2999+
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
3000+
int len;
3001+
3002+
/* fail if symlinks are disabled or API is not supported (WinXP) */
3003+
if (!has_symlinks) {
3004+
errno = ENOSYS;
3005+
return -1;
3006+
}
3007+
3008+
if ((len = xutftowcs_long_path(wtarget, target)) < 0
3009+
|| xutftowcs_long_path(wlink, link) < 0)
3010+
return -1;
3011+
3012+
/* convert target dir separators to backslashes */
3013+
while (len--)
3014+
if (wtarget[len] == '/')
3015+
wtarget[len] = '\\';
3016+
3017+
/* create file symlink */
3018+
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
3019+
errno = err_win_to_posix(GetLastError());
3020+
return -1;
3021+
}
3022+
return 0;
3023+
}
3024+
29973025
#ifndef _WINNT_H
29983026
/*
29993027
* The REPARSE_DATA_BUFFER structure is defined in the Windows DDK (in

compat/mingw/posix.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ struct utsname {
120120
* trivial stubs
121121
*/
122122

123-
static inline int symlink(const char *oldpath UNUSED, const char *newpath UNUSED)
124-
{ errno = ENOSYS; return -1; }
125123
static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED)
126124
{ errno = ENOSYS; return -1; }
127125
#ifndef __MINGW64_VERSION_MAJOR
@@ -194,6 +192,7 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
194192
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
195193
int link(const char *oldpath, const char *newpath);
196194
int uname(struct utsname *buf);
195+
int symlink(const char *target, const char *link);
197196
int readlink(const char *path, char *buf, size_t bufsiz);
198197

199198
/*

0 commit comments

Comments
 (0)