Skip to content

Commit 4bcc8a5

Browse files
kbleesdscho
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 16c8396 commit 4bcc8a5

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

compat/mingw.c

+28
Original file line numberDiff line numberDiff line change
@@ -2983,6 +2983,34 @@ int link(const char *oldpath, const char *newpath)
29832983
return 0;
29842984
}
29852985

2986+
int symlink(const char *target, const char *link)
2987+
{
2988+
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
2989+
int len;
2990+
2991+
/* fail if symlinks are disabled or API is not supported (WinXP) */
2992+
if (!has_symlinks) {
2993+
errno = ENOSYS;
2994+
return -1;
2995+
}
2996+
2997+
if ((len = xutftowcs_long_path(wtarget, target)) < 0
2998+
|| xutftowcs_long_path(wlink, link) < 0)
2999+
return -1;
3000+
3001+
/* convert target dir separators to backslashes */
3002+
while (len--)
3003+
if (wtarget[len] == '/')
3004+
wtarget[len] = '\\';
3005+
3006+
/* create file symlink */
3007+
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
3008+
errno = err_win_to_posix(GetLastError());
3009+
return -1;
3010+
}
3011+
return 0;
3012+
}
3013+
29863014
#ifndef _WINNT_H
29873015
/*
29883016
* The REPARSE_DATA_BUFFER structure is defined in the Windows DDK (in

compat/mingw.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ struct utsname {
125125
* trivial stubs
126126
*/
127127

128-
static inline int symlink(const char *oldpath UNUSED, const char *newpath UNUSED)
129-
{ errno = ENOSYS; return -1; }
130128
static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED)
131129
{ errno = ENOSYS; return -1; }
132130
#ifndef __MINGW64_VERSION_MAJOR
@@ -220,6 +218,7 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
220218
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
221219
int link(const char *oldpath, const char *newpath);
222220
int uname(struct utsname *buf);
221+
int symlink(const char *target, const char *link);
223222
int readlink(const char *path, char *buf, size_t bufsiz);
224223

225224
/*

0 commit comments

Comments
 (0)