summaryrefslogtreecommitdiff
path: root/test_utils
diff options
context:
space:
mode:
authorMartin Matuska <martin@matuska.org>2019-03-27 16:22:41 +0100
committerMartin Matuska <martin@matuska.org>2019-03-27 16:33:16 +0100
commitbc8efdef3e1030976617b8710ff0f71762d078d3 (patch)
tree24c9b7645dbe6e794105ba57118546c877a7e2ba /test_utils
parent5fe1dadb88c499e8dff71f2e9d9366cb99acda91 (diff)
downloadlibarchive-bc8efdef3e1030976617b8710ff0f71762d078d3.tar.gz
Add support for directory symlinks on Windows
Symlinks with the targets ".", ".." or with an ending slash in the target are treated as directory symlinks on Windows.
Diffstat (limited to 'test_utils')
-rw-r--r--test_utils/test_main.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index d14e70fc..6f4dd3a1 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -214,6 +214,7 @@ static int
my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
{
static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD);
+ DWORD attrs;
static int set;
int ret, tmpflags;
char *tgt, *p;
@@ -243,14 +244,40 @@ my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
*p = '\0';
/*
- * Windows can't overwrite existing links
+ * If the target equals ".", ".." or ends with a slash, it always
+ * points to a directory. In this case we can set the directory flag.
*/
- _unlink(linkname);
+ if (strcmp(tgt, ".") == 0 || strcmp(tgt, "..") == 0 ||
+ *(p - 1) == '\\') {
+#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+#else
+ flags |= 0x1;
+#endif
+ /* Now we remove trailing backslashes */
+ p--;
+ while(*p == '\\') {
+ *p = '\0';
+ p--;
+ }
+ }
+
#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
tmpflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
#else
tmpflags = flags | 0x2;
#endif
+ /*
+ * Windows won't overwrite existing links
+ */
+ attrs = GetFileAttributesA(linkname);
+ if (attrs != INVALID_FILE_ATTRIBUTES) {
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY)
+ RemoveDirectoryA(linkname);
+ else
+ DeleteFileA(linkname);
+ }
+
ret = (*f)(linkname, tgt, tmpflags);
/*
* Prior to Windows 10 the SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE