mirror of
https://github.com/git/git.git
synced 2026-01-19 15:09:01 +00:00
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:
committed by
Jameson Miller
parent
82a90c569c
commit
1f1cffa5ab
@@ -270,6 +270,8 @@ int mingw_core_config(const char *var, const char *value, void *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_PROC_ADDR(kernel32.dll, BOOLEAN, CreateSymbolicLinkW, LPCWSTR, LPCWSTR, DWORD);
|
||||
|
||||
/* Normalizes NT paths as returned by some low-level APIs. */
|
||||
static wchar_t *normalize_ntpath(wchar_t *wbuf)
|
||||
{
|
||||
@@ -2172,6 +2174,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 || !INIT_PROC_ADDR(CreateSymbolicLinkW)) {
|
||||
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
|
||||
|
||||
@@ -123,8 +123,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
|
||||
@@ -216,6 +214,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);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user