diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-10 19:22:46 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-10 19:22:46 +0900 |
commit | 8b02a27fc607ebc54c5a811188b3cea5063564e7 (patch) | |
tree | c1ca7d4acca553301204ebb83383aa87cb59311a /libcxx/src/filesystem | |
parent | 694a772457b2999b7bd68625a16bf0755e95dcdb (diff) | |
parent | 397ac44f623f891d8f05d6673a95984ac0a26671 (diff) | |
download | llvm-users/chapuni/cov/merge/mcdcsort.zip llvm-users/chapuni/cov/merge/mcdcsort.tar.gz llvm-users/chapuni/cov/merge/mcdcsort.tar.bz2 |
Merge branch 'main' into users/chapuni/cov/merge/mcdcsortusers/chapuni/cov/merge/mcdcsort
Diffstat (limited to 'libcxx/src/filesystem')
-rw-r--r-- | libcxx/src/filesystem/directory_iterator.cpp | 10 | ||||
-rw-r--r-- | libcxx/src/filesystem/error.h | 73 | ||||
-rw-r--r-- | libcxx/src/filesystem/file_descriptor.h | 12 | ||||
-rw-r--r-- | libcxx/src/filesystem/operations.cpp | 67 | ||||
-rw-r--r-- | libcxx/src/filesystem/posix_compat.h | 73 |
5 files changed, 92 insertions, 143 deletions
diff --git a/libcxx/src/filesystem/directory_iterator.cpp b/libcxx/src/filesystem/directory_iterator.cpp index d7ed9a3..7e8e40d 100644 --- a/libcxx/src/filesystem/directory_iterator.cpp +++ b/libcxx/src/filesystem/directory_iterator.cpp @@ -47,9 +47,9 @@ public: } __stream_ = ::FindFirstFileW((root / "*").c_str(), &__data_); if (__stream_ == INVALID_HANDLE_VALUE) { - ec = detail::make_windows_error(GetLastError()); + ec = detail::get_last_error(); const bool ignore_permission_denied = bool(opts & directory_options::skip_permission_denied); - if (ignore_permission_denied && ec.value() == static_cast<int>(errc::permission_denied)) + if (ignore_permission_denied && ec == errc::permission_denied) ec.clear(); return; } @@ -91,7 +91,7 @@ private: error_code close() noexcept { error_code ec; if (!::FindClose(__stream_)) - ec = detail::make_windows_error(GetLastError()); + ec = detail::get_last_error(); __stream_ = INVALID_HANDLE_VALUE; return ec; } @@ -118,7 +118,7 @@ public: if ((__stream_ = ::opendir(root.c_str())) == nullptr) { ec = detail::capture_errno(); const bool allow_eacces = bool(opts & directory_options::skip_permission_denied); - if (allow_eacces && ec.value() == EACCES) + if (allow_eacces && ec == errc::permission_denied) ec.clear(); return; } @@ -307,7 +307,7 @@ bool recursive_directory_iterator::__try_recursion(error_code* ec) { } if (m_ec) { const bool allow_eacess = bool(__imp_->__options_ & directory_options::skip_permission_denied); - if (m_ec.value() == EACCES && allow_eacess) { + if (m_ec == errc::permission_denied && allow_eacess) { if (ec) ec->clear(); } else { diff --git a/libcxx/src/filesystem/error.h b/libcxx/src/filesystem/error.h index 07ba7fc..c021391 100644 --- a/libcxx/src/filesystem/error.h +++ b/libcxx/src/filesystem/error.h @@ -32,80 +32,21 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace detail { -#if defined(_LIBCPP_WIN32API) - -inline errc __win_err_to_errc(int err) { - constexpr struct { - DWORD win; - errc errc; - } win_error_mapping[] = { - {ERROR_ACCESS_DENIED, errc::permission_denied}, - {ERROR_ALREADY_EXISTS, errc::file_exists}, - {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, - {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory}, - {ERROR_BAD_UNIT, errc::no_such_device}, - {ERROR_BROKEN_PIPE, errc::broken_pipe}, - {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, - {ERROR_BUSY, errc::device_or_resource_busy}, - {ERROR_BUSY_DRIVE, errc::device_or_resource_busy}, - {ERROR_CANNOT_MAKE, errc::permission_denied}, - {ERROR_CANTOPEN, errc::io_error}, - {ERROR_CANTREAD, errc::io_error}, - {ERROR_CANTWRITE, errc::io_error}, - {ERROR_CURRENT_DIRECTORY, errc::permission_denied}, - {ERROR_DEV_NOT_EXIST, errc::no_such_device}, - {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy}, - {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty}, - {ERROR_DIRECTORY, errc::invalid_argument}, - {ERROR_DISK_FULL, errc::no_space_on_device}, - {ERROR_FILE_EXISTS, errc::file_exists}, - {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory}, - {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device}, - {ERROR_INVALID_ACCESS, errc::permission_denied}, - {ERROR_INVALID_DRIVE, errc::no_such_device}, - {ERROR_INVALID_FUNCTION, errc::function_not_supported}, - {ERROR_INVALID_HANDLE, errc::invalid_argument}, - {ERROR_INVALID_NAME, errc::no_such_file_or_directory}, - {ERROR_INVALID_PARAMETER, errc::invalid_argument}, - {ERROR_LOCK_VIOLATION, errc::no_lock_available}, - {ERROR_LOCKED, errc::no_lock_available}, - {ERROR_NEGATIVE_SEEK, errc::invalid_argument}, - {ERROR_NOACCESS, errc::permission_denied}, - {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory}, - {ERROR_NOT_READY, errc::resource_unavailable_try_again}, - {ERROR_NOT_SAME_DEVICE, errc::cross_device_link}, - {ERROR_NOT_SUPPORTED, errc::not_supported}, - {ERROR_OPEN_FAILED, errc::io_error}, - {ERROR_OPEN_FILES, errc::device_or_resource_busy}, - {ERROR_OPERATION_ABORTED, errc::operation_canceled}, - {ERROR_OUTOFMEMORY, errc::not_enough_memory}, - {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory}, - {ERROR_READ_FAULT, errc::io_error}, - {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument}, - {ERROR_RETRY, errc::resource_unavailable_try_again}, - {ERROR_SEEK, errc::io_error}, - {ERROR_SHARING_VIOLATION, errc::permission_denied}, - {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open}, - {ERROR_WRITE_FAULT, errc::io_error}, - {ERROR_WRITE_PROTECT, errc::permission_denied}, - }; - - for (const auto& pair : win_error_mapping) - if (pair.win == static_cast<DWORD>(err)) - return pair.errc; - return errc::invalid_argument; -} - -#endif // _LIBCPP_WIN32API +// On windows, libc functions use errno, but system functions use GetLastError. +// So, callers need to be careful which of these next functions they call! inline error_code capture_errno() { _LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero"); return error_code(errno, generic_category()); } +inline error_code get_last_error() { #if defined(_LIBCPP_WIN32API) -inline error_code make_windows_error(int err) { return make_error_code(__win_err_to_errc(err)); } + return std::error_code(GetLastError(), std::system_category()); +#else + return capture_errno(); #endif +} template <class T> T error_value(); diff --git a/libcxx/src/filesystem/file_descriptor.h b/libcxx/src/filesystem/file_descriptor.h index db66ad5..9c279c4 100644 --- a/libcxx/src/filesystem/file_descriptor.h +++ b/libcxx/src/filesystem/file_descriptor.h @@ -201,7 +201,7 @@ inline perms posix_get_perms(const StatT& st) noexcept { return static_cast<perm inline file_status create_file_status(error_code& m_ec, path const& p, const StatT& path_stat, error_code* ec) { if (ec) *ec = m_ec; - if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { + if (m_ec && (m_ec == errc::no_such_file_or_directory || m_ec == errc::not_a_directory)) { return file_status(file_type::not_found); } else if (m_ec) { ErrorHandler<void> err("posix_stat", ec, &p); @@ -236,7 +236,7 @@ inline file_status create_file_status(error_code& m_ec, path const& p, const Sta inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::stat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); + m_ec = detail::get_last_error(); return create_file_status(m_ec, p, path_stat, ec); } @@ -248,7 +248,7 @@ inline file_status posix_stat(path const& p, error_code* ec) { inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::lstat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); + m_ec = detail::get_last_error(); return create_file_status(m_ec, p, path_stat, ec); } @@ -260,7 +260,7 @@ inline file_status posix_lstat(path const& p, error_code* ec) { // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { if (detail::ftruncate(fd.fd, to_size) == -1) { - ec = capture_errno(); + ec = get_last_error(); return true; } ec.clear(); @@ -269,7 +269,7 @@ inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { if (detail::fchmod(fd.fd, st.st_mode) == -1) { - ec = capture_errno(); + ec = get_last_error(); return true; } ec.clear(); @@ -286,7 +286,7 @@ inline file_status FileDescriptor::refresh_status(error_code& ec) { m_stat = {}; error_code m_ec; if (detail::fstat(fd, &m_stat) == -1) - m_ec = capture_errno(); + m_ec = get_last_error(); m_status = create_file_status(m_ec, name, m_stat, &ec); return m_status; } diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp index bd37c5a..23c1c28 100644 --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -39,8 +39,16 @@ #include <fcntl.h> /* values for fchmodat */ #include <time.h> -// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc and musl -#if (defined(__linux__) && (defined(__GLIBC__) || _LIBCPP_HAS_MUSL_LIBC)) || defined(__FreeBSD__) +// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl +#if defined(__linux__) +# if defined(_LIBCPP_GLIBC_PREREQ) +# if _LIBCPP_GLIBC_PREREQ(2, 27) +# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE +# endif +# elif _LIBCPP_HAS_MUSL_LIBC +# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE +# endif +#elif defined(__FreeBSD__) # define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE #endif #if __has_include(<sys/sendfile.h>) @@ -100,7 +108,7 @@ path __canonical(path const& orig_p, error_code* ec) { #if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || defined(_LIBCPP_WIN32API) std::unique_ptr<path::value_type, decltype(&::free)> hold(detail::realpath(p.c_str(), nullptr), &::free); if (hold.get() == nullptr) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); return {hold.get()}; #else # if defined(__MVS__) && !defined(PATH_MAX) @@ -110,7 +118,7 @@ path __canonical(path const& orig_p, error_code* ec) { # endif path::value_type* ret; if ((ret = detail::realpath(p.c_str(), buff)) == nullptr) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); return {ret}; #endif } @@ -238,8 +246,14 @@ bool copy_file_impl_copy_file_range(FileDescriptor& read_fd, FileDescriptor& wri return false; } // do not modify the fd positions as copy_file_impl_sendfile may be called after a partial copy +# if defined(__linux__) + loff_t off_in = 0; + loff_t off_out = 0; +# else off_t off_in = 0; off_t off_out = 0; +# endif + do { ssize_t res; @@ -499,9 +513,9 @@ bool __create_directory(const path& p, error_code* ec) { if (detail::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) return true; - if (errno != EEXIST) - return err.report(capture_errno()); - error_code mec = capture_errno(); + error_code mec = detail::get_last_error(); + if (mec != errc::file_exists) + return err.report(mec); error_code ignored_ec; const file_status st = status(p, ignored_ec); if (!is_directory(st)) @@ -523,10 +537,10 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0) return true; - if (errno != EEXIST) - return err.report(capture_errno()); + mec = detail::get_last_error(); + if (mec != errc::file_exists) + return err.report(mec); - mec = capture_errno(); error_code ignored_ec; st = status(p, ignored_ec); if (!is_directory(st)) @@ -537,19 +551,19 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { void __create_directory_symlink(path const& from, path const& to, error_code* ec) { ErrorHandler<void> err("create_directory_symlink", ec, &from, &to); if (detail::symlink_dir(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } void __create_hard_link(const path& from, const path& to, error_code* ec) { ErrorHandler<void> err("create_hard_link", ec, &from, &to); if (detail::link(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } void __create_symlink(path const& from, path const& to, error_code* ec) { ErrorHandler<void> err("create_symlink", ec, &from, &to); if (detail::symlink_file(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } path __current_path(error_code* ec) { @@ -592,7 +606,7 @@ path __current_path(error_code* ec) { unique_ptr<path::value_type, Deleter> hold(detail::getcwd(ptr, size), deleter); if (hold.get() == nullptr) - return err.report(capture_errno(), "call to getcwd failed"); + return err.report(detail::get_last_error(), "call to getcwd failed"); return {hold.get()}; } @@ -600,7 +614,7 @@ path __current_path(error_code* ec) { void __current_path(const path& p, error_code* ec) { ErrorHandler<void> err("current_path", ec, &p); if (detail::chdir(p.c_str()) == -1) - err.report(capture_errno()); + err.report(detail::get_last_error()); } bool __equivalent(const path& p1, const path& p2, error_code* ec) { @@ -688,10 +702,10 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) { return err.report(errc::value_too_large); detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0); if (!h) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); FILETIME last_write = timespec_to_filetime(ts); if (!SetFileTime(h, nullptr, nullptr, &last_write)) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); #else error_code m_ec; array<TimeSpec, 2> tbuf; @@ -749,7 +763,7 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec) #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; if (detail::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } #else if (set_sym_perms) @@ -777,14 +791,14 @@ path __read_symlink(const path& p, error_code* ec) { #else StatT sb; if (detail::lstat(p.c_str(), &sb) == -1) { - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } const size_t size = sb.st_size + 1; auto buff = unique_ptr<path::value_type[]>(new path::value_type[size]); #endif detail::SSizeT ret; if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); // Note that `ret` returning `0` would work, resulting in a valid empty string being returned. if (static_cast<size_t>(ret) >= size) return err.report(errc::value_too_large); @@ -795,8 +809,9 @@ path __read_symlink(const path& p, error_code* ec) { bool __remove(const path& p, error_code* ec) { ErrorHandler<bool> err("remove", ec, &p); if (detail::remove(p.c_str()) == -1) { - if (errno != ENOENT) - err.report(capture_errno()); + error_code mec = detail::get_last_error(); + if (mec != errc::no_such_file_or_directory) + err.report(mec); return false; } return true; @@ -949,13 +964,13 @@ uintmax_t __remove_all(const path& p, error_code* ec) { void __rename(const path& from, const path& to, error_code* ec) { ErrorHandler<void> err("rename", ec, &from, &to); if (detail::rename(from.c_str(), to.c_str()) == -1) - err.report(capture_errno()); + err.report(detail::get_last_error()); } void __resize_file(const path& p, uintmax_t size, error_code* ec) { ErrorHandler<void> err("resize_file", ec, &p); if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } space_info __space(const path& p, error_code* ec) { @@ -963,7 +978,7 @@ space_info __space(const path& p, error_code* ec) { space_info si; detail::StatVFS m_svfs = {}; if (detail::statvfs(p.c_str(), &m_svfs) == -1) { - err.report(capture_errno()); + err.report(detail::get_last_error()); si.capacity = si.free = si.available = static_cast<uintmax_t>(-1); return si; } @@ -990,7 +1005,7 @@ path __temp_directory_path(error_code* ec) { wchar_t buf[MAX_PATH]; DWORD retval = GetTempPathW(MAX_PATH, buf); if (!retval) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); if (retval > MAX_PATH) return err.report(errc::filename_too_long); // GetTempPathW returns a path with a trailing slash, which we 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); |