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 <blees@dcon.de>
This commit is contained in:
Karsten Blees 2015-05-24 01:32:03 +02:00 коммит произвёл Johannes Schindelin
Родитель 1fb286e37e
Коммит ecb00785cc
2 изменённых файлов: 29 добавлений и 2 удалений

Просмотреть файл

@ -2709,6 +2709,34 @@ int link(const char *oldpath, const char *newpath)
return 0;
}
int symlink(const char *target, const char *link)
{
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
int len;
/* fail if symlinks are disabled or API is not supported (WinXP) */
if (!has_symlinks) {
errno = ENOSYS;
return -1;
}
if ((len = xutftowcs_long_path(wtarget, target)) < 0
|| xutftowcs_long_path(wlink, link) < 0)
return -1;
/* convert target dir separators to backslashes */
while (len--)
if (wtarget[len] == '/')
wtarget[len] = '\\';
/* create file symlink */
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
errno = err_win_to_posix(GetLastError());
return -1;
}
return 0;
}
#ifndef _WINNT_H
/*
* The REPARSE_DATA_BUFFER structure is defined in the Windows DDK (in

Просмотреть файл

@ -125,8 +125,6 @@ struct utsname {
* trivial stubs
*/
static inline int symlink(const char *oldpath, const char *newpath)
{ errno = ENOSYS; return -1; }
static inline int fchmod(int fildes, mode_t mode)
{ errno = ENOSYS; return -1; }
#ifndef __MINGW64_VERSION_MAJOR
@ -217,6 +215,7 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
int link(const char *oldpath, const char *newpath);
int uname(struct utsname *buf);
int symlink(const char *target, const char *link);
int readlink(const char *path, char *buf, size_t bufsiz);
/*