Add Windows support for symlink of directories

This commit is contained in:
Andrea Mazzoleni 2026-05-08 09:05:47 +02:00
parent c5b3fdc615
commit 38f78154f9
2 changed files with 19 additions and 3 deletions

View file

@ -1802,7 +1802,7 @@ int windows_link(const char* existing, const char* file)
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
#endif
int windows_symlink(const char* existing, const char* file)
static int windows_symlink_flags(const char* existing, const char* file, DWORD flags)
{
wchar_t conv_buf_file[CONV_MAX];
wchar_t conv_buf_existing[CONV_MAX];
@ -1814,7 +1814,7 @@ int windows_symlink(const char* existing, const char* file)
* user symlinks different than they were before
*/
if (!CreateSymbolicLinkW(convert(conv_buf_file, file), convert_if_required(conv_buf_existing, existing),
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
) {
DWORD error = GetLastError();
if (GetLastError() != ERROR_INVALID_PARAMETER) {
@ -1823,7 +1823,7 @@ int windows_symlink(const char* existing, const char* file)
}
/* retry without the new flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE */
if (!CreateSymbolicLinkW(convert(conv_buf_file, file), convert_if_required(conv_buf_existing, existing), 0)) {
if (!CreateSymbolicLinkW(convert(conv_buf_file, file), convert_if_required(conv_buf_existing, existing), flags)) {
windows_errno(GetLastError());
return -1;
}
@ -1832,6 +1832,16 @@ int windows_symlink(const char* existing, const char* file)
return 0;
}
int windows_symlink(const char* existing, const char* file)
{
return windows_symlink_flags(existing, file, 0);
}
int windows_symlink_directory(const char* existing, const char* file)
{
return windows_symlink_flags(existing, file, SYMBOLIC_LINK_FLAG_DIRECTORY);
}
/* Adds missing definitions in MingW winnt.h */
#ifndef FSCTL_GET_REPARSE_POINT
#define FSCTL_GET_REPARSE_POINT 0x000900a8

View file

@ -341,6 +341,12 @@ int windows_readlink(const char* file, char* buffer, size_t size);
*/
int windows_symlink(const char* existing, const char* file);
/**
* Like symlink().
* Return ENOSYS if symlinks are not supported.
*/
int windows_symlink_directory(const char* existing, const char* file);
/**
* Like link().
*/