Skip to content

Commit 2786050

Browse files
kbleesGit for Windows Build Agent
authored and
Git for Windows Build Agent
committed
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 04561aa commit 2786050

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

compat/mingw.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,6 +2960,34 @@ int link(const char *oldpath, const char *newpath)
29602960
return 0;
29612961
}
29622962

2963+
int symlink(const char *target, const char *link)
2964+
{
2965+
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
2966+
int len;
2967+
2968+
/* fail if symlinks are disabled or API is not supported (WinXP) */
2969+
if (!has_symlinks) {
2970+
errno = ENOSYS;
2971+
return -1;
2972+
}
2973+
2974+
if ((len = xutftowcs_long_path(wtarget, target)) < 0
2975+
|| xutftowcs_long_path(wlink, link) < 0)
2976+
return -1;
2977+
2978+
/* convert target dir separators to backslashes */
2979+
while (len--)
2980+
if (wtarget[len] == '/')
2981+
wtarget[len] = '\\';
2982+
2983+
/* create file symlink */
2984+
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
2985+
errno = err_win_to_posix(GetLastError());
2986+
return -1;
2987+
}
2988+
return 0;
2989+
}
2990+
29632991
#ifndef _WINNT_H
29642992
/*
29652993
* The REPARSE_DATA_BUFFER structure is defined in the Windows DDK (in

0 commit comments

Comments
 (0)