13 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
19 #elif defined(_WIN32) || defined(_WIN64)
25 #if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE)
26 #define SYMLINK_FLAG_RELATIVE 1
27 typedef struct _REPARSE_DATA_BUFFER
30 USHORT ReparseDataLength;
36 USHORT SubstituteNameOffset;
37 USHORT SubstituteNameLength;
38 USHORT PrintNameOffset;
39 USHORT PrintNameLength;
42 } SymbolicLinkReparseBuffer;
45 USHORT SubstituteNameOffset;
46 USHORT SubstituteNameLength;
47 USHORT PrintNameOffset;
48 USHORT PrintNameLength;
50 } MountPointReparseBuffer;
54 } GenericReparseBuffer;
56 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
57 #define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
59 #ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE
60 #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024)
68 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
69 std::vector<char> buffer(PATH_MAX);
72 while ((size = readlink(
string().c_str(), buffer.data(), buffer.size())) == (ssize_t)buffer.size())
73 buffer.resize(buffer.size() * 2);
79 return Path(std::string(buffer.data(), size));
80 #elif defined(_WIN32) || defined(_WIN64)
81 HANDLE hSymlink = CreateFileW(
wstring().c_str(), GENERIC_READ, 0,
nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
nullptr);
82 if (hSymlink == INVALID_HANDLE_VALUE)
86 auto file =
resource(hSymlink, [](HANDLE hObject) { CloseHandle(hObject); });
90 char buffer[REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
91 REPARSE_DATA_BUFFER rdb;
96 if (!DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT,
nullptr, 0, info.buffer,
sizeof(info), &size,
nullptr))
100 if (!CloseHandle(hSymlink))
105 std::wstring result((
wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer +
106 (info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset /
sizeof(WCHAR)),
107 (
wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer +
108 (info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset /
sizeof(WCHAR)) +
109 (info.rdb.SymbolicLinkReparseBuffer.PrintNameLength /
sizeof(WCHAR)));
118 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
120 int result = lstat(
string().c_str(), &lstatus);
123 if ((errno == ENOENT) || (errno == ENOTDIR))
129 if (S_ISLNK(lstatus.st_mode))
133 #elif defined(_WIN32) || defined(_WIN64)
138 return (
attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
144 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
145 int result = symlink(src.
string().c_str(), dst.
string().c_str());
148 #elif defined(_WIN32) || defined(_WIN64)
149 std::wstring source = src.
wstring();
150 DWORD
attributes = GetFileAttributesW(source.c_str());
156 if (!CreateSymbolicLinkW(dst.
wstring().c_str(), source.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY))
161 if (!CreateSymbolicLinkW(dst.
wstring().c_str(), source.c_str(), 0))
170 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
171 int result = link(src.
string().c_str(), dst.
string().c_str());
174 #elif defined(_WIN32) || defined(_WIN64)
175 if (!CreateHardLinkW(dst.
wstring().c_str(), src.
wstring().c_str(),
nullptr))
static std::string ToUTF8(std::wstring_view wstr)
Convert system wide-string to UTF-8 encoded string.
FileSystemException & Attach(const Path &path)
Attach the given path to the exception.
std::wstring wstring() const
Get the path value as a wide string.
Flags< FileAttributes > attributes() const
Get the path file attributes.
Path()
Initialize path with an empty value.
const std::string & string() const noexcept
Get the path value as UTF-8 string.
static Path CreateHardlink(const Path &src, const Path &dst)
Create a new hardlink.
static Symlink CreateSymlink(const Path &src, const Path &dst)
Create a new symlink.
Path target() const
Read symlink target path.
bool IsSymlinkExists() const
Is the symlink exists?
#define throwex
Throw extended exception macro.
C++ Common project definitions.
auto resource(T handle, TCleaner cleaner)
Resource smart cleaner pattern.
Resource smart cleaner pattern definition.
Filesystem symlink definition.