win32: add symbolic link support Enable `p_symlink` to actually create symbolic links, not just create a fake link (a text file containing the link target). This now means that `core.symlinks=true` works on Windows platforms where symbolic links are enabled (likely due to running in Developer Mode).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 1b7b939..e0dd3a3 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -29,6 +29,10 @@
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
+#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x02
+#endif
+
/* Allowable mode bits on Win32. Using mode bits that are not supported on
* Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it
* so we simply remove them.
@@ -390,12 +394,20 @@ int p_readlink(const char *path, char *buf, size_t bufsiz)
return (int)bufsiz;
}
-int p_symlink(const char *old, const char *new)
+int p_symlink(const char *target, const char *path)
{
- /* Real symlinks on NTFS require admin privileges. Until this changes,
- * libgit2 just creates a text file with the link target in the contents.
- */
- return git_futils_fake_symlink(old, new);
+ git_win32_path target_w, path_w;
+ wchar_t *target_p;
+
+ if (git_win32_path_from_utf8(path_w, path) < 0 ||
+ git__utf8_to_16(target_w, MAX_PATH, target) < 0)
+ return -1;
+
+ if (!CreateSymbolicLinkW(path_w, target_w,
+ SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
+ return -1;
+
+ return 0;
}
struct open_opts {