diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index 6be260070..bb51a2bfd 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -1204,3 +1204,36 @@ cleanup: free(resolved_utf16); return ret; } + +int +fileio_link(const char *oldpath, const char *newpath) +{ + if (oldpath == NULL || newpath == NULL) { + errno = EFAULT; + return -1; + } + + DWORD ret = 0; + wchar_t *oldpath_utf16 = utf8_to_utf16(resolved_path(oldpath)); + wchar_t *newpath_utf16 = utf8_to_utf16(resolved_path(newpath)); + if (oldpath_utf16 == NULL || newpath_utf16 == NULL) { + errno = ENOMEM; + ret = -1; + goto cleanup; + } + + if (CreateHardLinkW(newpath_utf16, oldpath_utf16, NULL) == 0) { + errno = errno_from_Win32LastError(); + ret = -1; + goto cleanup; + } + +cleanup: + + if (oldpath_utf16) + free(oldpath_utf16); + if (newpath_utf16) + free(newpath_utf16); + + return ret; +} \ No newline at end of file diff --git a/contrib/win32/win32compat/inc/unistd.h b/contrib/win32/win32compat/inc/unistd.h index d37188924..25f594ad3 100644 --- a/contrib/win32/win32compat/inc/unistd.h +++ b/contrib/win32/win32compat/inc/unistd.h @@ -76,11 +76,14 @@ int w32_chdir(const char *dirname); char *w32_getcwd(char *buffer, int maxlen); #define getcwd w32_getcwd +int w32_readlink(const char *path, char *link, int linklen); +#define readlink w32_readlink + +int w32_link(const char *oldpath, const char *newpath); +#define link w32_link + int daemon(int nochdir, int noclose); char *crypt(const char *key, const char *salt); -int link(const char *oldpath, const char *newpath); -int readlink(const char *path, char *link, int linklen); - int chroot(const char *path); /* diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 976267698..1e572af7d 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -661,11 +661,9 @@ w32_symlink(const char *target, const char *linkpath) } int -link(const char *oldpath, const char *newpath) +w32_link(const char *oldpath, const char *newpath) { - /* Not supported in windows */ - errno = EOPNOTSUPP; - return -1; + return fileio_link(oldpath, newpath); } int @@ -831,7 +829,7 @@ w32_lstat(const char *input_path, struct w32_stat *buf) /* if file is symbolic link, copy its link into "link" */ int -readlink(const char *path, char *link, int linklen) +w32_readlink(const char *path, char *link, int linklen) { return fileio_readlink(resolved_path(path), link, linklen); } diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h index 9a5158945..67e5c3dac 100644 --- a/contrib/win32/win32compat/w32fd.h +++ b/contrib/win32/win32compat/w32fd.h @@ -165,4 +165,5 @@ int fileio_lstat(const char *path, struct _stat64 *buf); long fileio_lseek(struct w32_io* pio, unsigned __int64 offset, int origin); FILE* fileio_fdopen(struct w32_io* pio, const char *mode); ssize_t fileio_readlink(const char *path, char *buf, size_t bufsiz); -int fileio_symlink(const char *target, const char *linkpath); \ No newline at end of file +int fileio_symlink(const char *target, const char *linkpath); +int fileio_link(const char *oldpath, const char *newpath); \ No newline at end of file