summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-07-03 02:30:34 -0700
committerEdward Thomson <ethomson@edwardthomson.com>2018-10-20 05:51:46 -0700
commit204cce66bdd856d4be990cc27101a74131c72ec4 (patch)
tree6c9450f66c977b7a1f765415077c4aa15148d0bc /src
parente4ac40002865b3b8114ef434a97bcaedaafd324a (diff)
downloadlibgit2-204cce66bdd856d4be990cc27101a74131c72ec4.tar.gz
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).
Diffstat (limited to 'src')
-rw-r--r--src/win32/posix_w32.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 1b7b9392f..e0dd3a326 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 {