aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/filesystem/posix_compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/src/filesystem/posix_compat.h')
-rw-r--r--libcxx/src/filesystem/posix_compat.h73
1 files changed, 33 insertions, 40 deletions
diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h
index b41c004..ddd99d8 100644
--- a/libcxx/src/filesystem/posix_compat.h
+++ b/libcxx/src/filesystem/posix_compat.h
@@ -11,9 +11,10 @@
//
// These generally behave like the proper posix functions, with these
// exceptions:
-// On Windows, they take paths in wchar_t* form, instead of char* form.
-// The symlink() function is split into two frontends, symlink_file()
-// and symlink_dir().
+// - On Windows, they take paths in wchar_t* form, instead of char* form.
+// - The symlink() function is split into two frontends, symlink_file()
+// and symlink_dir().
+// - Errors should be retrieved with get_last_error, not errno.
//
// These are provided within an anonymous namespace within the detail
// namespace - callers need to include this header and call them as
@@ -122,11 +123,6 @@ namespace detail {
# define O_NONBLOCK 0
-inline int set_errno(int e = GetLastError()) {
- errno = static_cast<int>(__win_err_to_errc(e));
- return -1;
-}
-
class WinHandle {
public:
WinHandle(const wchar_t* p, DWORD access, DWORD flags) {
@@ -153,7 +149,7 @@ private:
inline int stat_handle(HANDLE h, StatT* buf) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
- return set_errno();
+ return -1;
memset(buf, 0, sizeof(*buf));
buf->st_mtim = filetime_to_timespec(basic.LastWriteTime);
buf->st_atim = filetime_to_timespec(basic.LastAccessTime);
@@ -168,18 +164,18 @@ inline int stat_handle(HANDLE h, StatT* buf) {
if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
FILE_ATTRIBUTE_TAG_INFO tag;
if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag, sizeof(tag)))
- return set_errno();
+ return -1;
if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK)
buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK;
}
FILE_STANDARD_INFO standard;
if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard, sizeof(standard)))
- return set_errno();
+ return -1;
buf->st_nlink = standard.NumberOfLinks;
buf->st_size = standard.EndOfFile.QuadPart;
BY_HANDLE_FILE_INFORMATION info;
if (!GetFileInformationByHandle(h, &info))
- return set_errno();
+ return -1;
buf->st_dev = info.dwVolumeSerialNumber;
memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4);
memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4);
@@ -189,7 +185,7 @@ inline int stat_handle(HANDLE h, StatT* buf) {
inline int stat_file(const wchar_t* path, StatT* buf, DWORD flags) {
WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
if (!h)
- return set_errno();
+ return -1;
int ret = stat_handle(h, buf);
return ret;
}
@@ -206,7 +202,7 @@ inline int fstat(int fd, StatT* buf) {
inline int mkdir(const wchar_t* path, int permissions) {
(void)permissions;
if (!CreateDirectoryW(path, nullptr))
- return set_errno();
+ return -1;
return 0;
}
@@ -219,10 +215,10 @@ inline int symlink_file_dir(const wchar_t* oldname, const wchar_t* newname, bool
return 0;
int e = GetLastError();
if (e != ERROR_INVALID_PARAMETER)
- return set_errno(e);
+ return -1;
if (CreateSymbolicLinkW(newname, oldname, flags))
return 0;
- return set_errno();
+ return -1;
}
inline int symlink_file(const wchar_t* oldname, const wchar_t* newname) {
@@ -236,17 +232,17 @@ inline int symlink_dir(const wchar_t* oldname, const wchar_t* newname) {
inline int link(const wchar_t* oldname, const wchar_t* newname) {
if (CreateHardLinkW(newname, oldname, nullptr))
return 0;
- return set_errno();
+ return -1;
}
inline int remove(const wchar_t* path) {
detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
if (!h)
- return set_errno();
+ return -1;
FILE_DISPOSITION_INFO info;
info.DeleteFile = TRUE;
if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info)))
- return set_errno();
+ return -1;
return 0;
}
@@ -254,9 +250,9 @@ inline int truncate_handle(HANDLE h, off_t length) {
LARGE_INTEGER size_param;
size_param.QuadPart = length;
if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
- return set_errno();
+ return -1;
if (!SetEndOfFile(h))
- return set_errno();
+ return -1;
return 0;
}
@@ -268,19 +264,19 @@ inline int ftruncate(int fd, off_t length) {
inline int truncate(const wchar_t* path, off_t length) {
detail::WinHandle h(path, GENERIC_WRITE, 0);
if (!h)
- return set_errno();
+ return -1;
return truncate_handle(h, length);
}
inline int rename(const wchar_t* from, const wchar_t* to) {
if (!(MoveFileExW(from, to, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)))
- return set_errno();
+ return -1;
return 0;
}
inline int chdir(const wchar_t* path) {
if (!SetCurrentDirectoryW(path))
- return set_errno();
+ return -1;
return 0;
}
@@ -300,7 +296,7 @@ inline int statvfs(const wchar_t* p, StatVFS* buf) {
break;
path parent = dir.parent_path();
if (parent == dir) {
- errno = ENOENT;
+ SetLastError(ERROR_PATH_NOT_FOUND);
return -1;
}
dir = parent;
@@ -308,7 +304,7 @@ inline int statvfs(const wchar_t* p, StatVFS* buf) {
ULARGE_INTEGER free_bytes_available_to_caller, total_number_of_bytes, total_number_of_free_bytes;
if (!GetDiskFreeSpaceExW(
dir.c_str(), &free_bytes_available_to_caller, &total_number_of_bytes, &total_number_of_free_bytes))
- return set_errno();
+ return -1;
buf->f_frsize = 1;
buf->f_blocks = total_number_of_bytes.QuadPart;
buf->f_bfree = total_number_of_free_bytes.QuadPart;
@@ -330,7 +326,6 @@ inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t
retval = GetCurrentDirectoryW(buff_size, buff.get());
}
if (!retval) {
- set_errno();
return nullptr;
}
return buff.release();
@@ -342,7 +337,6 @@ inline wchar_t* realpath(const wchar_t* path, [[maybe_unused]] wchar_t* resolved
WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
if (!h) {
- set_errno();
return nullptr;
}
size_t buff_size = MAX_PATH + 10;
@@ -354,7 +348,6 @@ inline wchar_t* realpath(const wchar_t* path, [[maybe_unused]] wchar_t* resolved
retval = GetFinalPathNameByHandleW(h, buff.get(), buff_size, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
}
if (!retval) {
- set_errno();
return nullptr;
}
wchar_t* ptr = buff.get();
@@ -376,20 +369,20 @@ using ModeT = int;
inline int fchmod_handle(HANDLE h, int perms) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
- return set_errno();
+ return -1;
DWORD orig_attributes = basic.FileAttributes;
basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
if ((perms & 0222) == 0)
basic.FileAttributes |= FILE_ATTRIBUTE_READONLY;
if (basic.FileAttributes != orig_attributes && !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic)))
- return set_errno();
+ return -1;
return 0;
}
inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) {
DWORD attributes = GetFileAttributesW(path);
if (attributes == INVALID_FILE_ATTRIBUTES)
- return set_errno();
+ return -1;
if (attributes & FILE_ATTRIBUTE_REPARSE_POINT && !(flag & AT_SYMLINK_NOFOLLOW)) {
// If the file is a symlink, and we are supposed to operate on the target
// of the symlink, we need to open a handle to it, without the
@@ -397,7 +390,7 @@ inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) {
// symlink, and operate on it via the handle.
detail::WinHandle h(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0);
if (!h)
- return set_errno();
+ return -1;
return fchmod_handle(h, perms);
} else {
// For a non-symlink, or if operating on the symlink itself instead of
@@ -407,7 +400,7 @@ inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) {
if ((perms & 0222) == 0)
attributes |= FILE_ATTRIBUTE_READONLY;
if (attributes != orig_attributes && !SetFileAttributesW(path, attributes))
- return set_errno();
+ return -1;
}
return 0;
}
@@ -424,18 +417,18 @@ inline SSizeT readlink(const wchar_t* path, wchar_t* ret_buf, size_t bufsize) {
uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
if (!h)
- return set_errno();
+ return -1;
DWORD out;
if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf, sizeof(buf), &out, 0))
- return set_errno();
+ return -1;
const auto* reparse = reinterpret_cast<LIBCPP_REPARSE_DATA_BUFFER*>(buf);
size_t path_buf_offset = offsetof(LIBCPP_REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]);
if (out < path_buf_offset) {
- errno = EINVAL;
+ SetLastError(ERROR_REPARSE_TAG_INVALID);
return -1;
}
if (reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
- errno = EINVAL;
+ SetLastError(ERROR_REPARSE_TAG_INVALID);
return -1;
}
const auto& symlink = reparse->SymbolicLinkReparseBuffer;
@@ -449,11 +442,11 @@ inline SSizeT readlink(const wchar_t* path, wchar_t* ret_buf, size_t bufsize) {
}
// name_offset/length are expressed in bytes, not in wchar_t
if (path_buf_offset + name_offset + name_length > out) {
- errno = EINVAL;
+ SetLastError(ERROR_REPARSE_TAG_INVALID);
return -1;
}
if (name_length / sizeof(wchar_t) > bufsize) {
- errno = ENOMEM;
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return -1;
}
memcpy(ret_buf, &symlink.PathBuffer[name_offset / sizeof(wchar_t)], name_length);