# include <windows.h> // ERROR_* macros
#endif
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
#if defined(_LIBCPP_WIN32API)
-errc __win_err_to_errc(int err) {
+inline errc __win_err_to_errc(int err) {
constexpr struct {
DWORD win;
errc errc;
#endif // _LIBCPP_WIN32API
-error_code capture_errno() {
+inline error_code capture_errno() {
_LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero");
return error_code(errno, generic_category());
}
#if defined(_LIBCPP_WIN32API)
-error_code make_windows_error(int err) {
+inline error_code make_windows_error(int err) {
return make_error_code(__win_err_to_errc(err));
}
#endif
template <class T>
T error_value();
template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
template <>
-bool error_value<bool>() {
+inline bool error_value<bool>() {
return false;
}
#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
template <>
-size_t error_value<size_t>() {
+inline size_t error_value<size_t>() {
return size_t(-1);
}
#endif
template <>
-uintmax_t error_value<uintmax_t>() {
+inline uintmax_t error_value<uintmax_t>() {
return uintmax_t(-1);
}
template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
return file_time_type::min();
}
template <>
-path error_value<path>() {
+inline path error_value<path>() {
return {};
}
ErrorHandler& operator=(ErrorHandler const&) = delete;
};
-} // end anonymous namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
# include <unistd.h>
#endif // defined(_LIBCPP_WIN32API)
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
#if !defined(_LIBCPP_WIN32API)
#if defined(DT_BLK)
template <class DirEntT, class = decltype(DirEntT::d_type)>
-static file_type get_file_type(DirEntT* ent, int) {
+file_type get_file_type(DirEntT* ent, int) {
switch (ent->d_type) {
case DT_BLK:
return file_type::block;
#endif // defined(DT_BLK)
template <class DirEntT>
-static file_type get_file_type(DirEntT*, long) {
+file_type get_file_type(DirEntT*, long) {
return file_type::none;
}
-static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
+inline pair<string_view, file_type> posix_readdir(DIR* dir_stream,
error_code& ec) {
struct dirent* dir_entry_ptr = nullptr;
errno = 0; // zero errno in order to detect errors
#else // _LIBCPP_WIN32API
-static file_type get_file_type(const WIN32_FIND_DATAW& data) {
+inline file_type get_file_type(const WIN32_FIND_DATAW& data) {
if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
return file_type::symlink;
return file_type::directory;
return file_type::regular;
}
-static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
+inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
}
-static file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
+inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
ULARGE_INTEGER tmp;
const FILETIME& time = data.ftLastWriteTime;
tmp.u.LowPart = time.dwLowDateTime;
explicit FileDescriptor(const path* p, int descriptor = -1) : name(*p), fd(descriptor) {}
};
-perms posix_get_perms(const StatT& st) noexcept {
+inline perms posix_get_perms(const StatT& st) noexcept {
return static_cast<perms>(st.st_mode) & perms::mask;
}
-file_status create_file_status(error_code& m_ec, path const& p,
- const StatT& path_stat, error_code* ec) {
+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)) {
return fs_tmp;
}
-file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
+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();
return create_file_status(m_ec, p, path_stat, ec);
}
-file_status posix_stat(path const& p, error_code* ec) {
+inline file_status posix_stat(path const& p, error_code* ec) {
StatT path_stat;
return posix_stat(p, path_stat, ec);
}
-file_status posix_lstat(path const& p, StatT& path_stat, 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();
return create_file_status(m_ec, p, path_stat, ec);
}
-file_status posix_lstat(path const& p, error_code* ec) {
+inline file_status posix_lstat(path const& p, error_code* ec) {
StatT path_stat;
return posix_lstat(p, path_stat, ec);
}
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
-bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
+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();
return true;
return false;
}
-bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
+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();
return true;
return false;
}
-bool stat_equivalent(const StatT& st1, const StatT& st2) {
+inline bool stat_equivalent(const StatT& st1, const StatT& st2) {
return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
}
-file_status FileDescriptor::refresh_status(error_code& ec) {
+inline file_status FileDescriptor::refresh_status(error_code& ec) {
// FD must be open and good.
m_status = file_status{};
m_stat = {};
return m_status;
}
-} // namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
#endif // FILESYSTEM_FILE_DESCRIPTOR_H
# define PATH_CSTR_FMT "\"%s\""
#endif
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
-_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0)
-string vformat_string(const char* msg, va_list ap) {
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
array<char, 256> buf;
va_list apcopy;
return result;
}
-_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
-string format_string(const char* msg, ...) {
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
string ret;
va_list ap;
va_start(ap, msg);
return ret;
}
-} // end anonymous namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
#endif // FILESYSTEM_FORMAT_STRING_H
return err.report(m_ec);
}
- if (!copy_file_impl(from_fd, to_fd, m_ec)) {
+ if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) {
// FIXME: Remove the dest file if we failed, and it didn't exist previously.
return err.report(m_ec);
}
#include "format_string.h"
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
-namespace {
-
-bool isSeparator(path::value_type C) {
+inline bool isSeparator(path::value_type C) {
if (C == '/')
return true;
#if defined(_LIBCPP_WIN32API)
return false;
}
-bool isDriveLetter(path::value_type C) {
+inline bool isDriveLetter(path::value_type C) {
return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
}
}
};
-string_view_pair separate_filename(string_view_t const& s) {
+inline string_view_pair separate_filename(string_view_t const& s) {
if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
return string_view_pair{s, PATHSTR("")};
auto pos = s.find_last_of('.');
return string_view_pair{s.substr(0, pos), s.substr(pos)};
}
-string_view_t createView(PosPtr S, PosPtr E) noexcept {
+inline string_view_t createView(PosPtr S, PosPtr E) noexcept {
return {S, static_cast<size_t>(E - S) + 1};
}
} // namespace parser
-} // namespace
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
#endif // PATH_PARSER_H
};
#endif
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
#if defined(_LIBCPP_WIN32API)
// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
// (1601) to the Unix epoch (1970).
#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
-TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
+inline TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
TimeSpec ret;
ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
ret.tv_nsec = (li.QuadPart % 10000000) * 100;
return ret;
}
-TimeSpec filetime_to_timespec(FILETIME ft) {
+inline TimeSpec filetime_to_timespec(FILETIME ft) {
LARGE_INTEGER li;
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
return filetime_to_timespec(li);
}
-FILETIME timespec_to_filetime(TimeSpec ts) {
+inline FILETIME timespec_to_filetime(TimeSpec ts) {
LARGE_INTEGER li;
li.QuadPart =
ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
return ft;
}
-int set_errno(int e = GetLastError()) {
+inline int set_errno(int e = GetLastError()) {
errno = static_cast<int>(__win_err_to_errc(e));
return -1;
}
HANDLE h;
};
-int stat_handle(HANDLE h, StatT *buf) {
+inline int stat_handle(HANDLE h, StatT *buf) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
return set_errno();
return 0;
}
-int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
+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 ret;
}
-int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
+inline int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
-int lstat(const wchar_t *path, StatT *buf) {
+inline int lstat(const wchar_t *path, StatT *buf) {
return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
}
-int fstat(int fd, StatT *buf) {
+inline int fstat(int fd, StatT *buf) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return stat_handle(h, buf);
}
-int mkdir(const wchar_t *path, int permissions) {
+inline int mkdir(const wchar_t *path, int permissions) {
(void)permissions;
return _wmkdir(path);
}
-int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
- bool is_dir) {
+inline int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
+ bool is_dir) {
path dest(oldname);
dest.make_preferred();
oldname = dest.c_str();
return set_errno();
}
-int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
return symlink_file_dir(oldname, newname, false);
}
-int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
return symlink_file_dir(oldname, newname, true);
}
-int link(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();
}
-int remove(const wchar_t *path) {
+inline int remove(const wchar_t *path) {
detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
if (!h)
return set_errno();
return 0;
}
-int truncate_handle(HANDLE h, off_t length) {
+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 0;
}
-int ftruncate(int fd, off_t length) {
+inline int ftruncate(int fd, off_t length) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return truncate_handle(h, length);
}
-int truncate(const wchar_t *path, 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 truncate_handle(h, length);
}
-int rename(const wchar_t *from, const wchar_t *to) {
+inline int rename(const wchar_t *from, const wchar_t *to) {
if (!(MoveFileExW(from, to,
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
MOVEFILE_WRITE_THROUGH)))
template <class... Args> int open(const wchar_t *filename, Args... args) {
return _wopen(filename, args...);
}
-int close(int fd) { return _close(fd); }
-int chdir(const wchar_t *path) { return _wchdir(path); }
+inline int close(int fd) { return _close(fd); }
+inline int chdir(const wchar_t *path) { return _wchdir(path); }
struct StatVFS {
uint64_t f_frsize;
uint64_t f_bavail;
};
-int statvfs(const wchar_t *p, StatVFS *buf) {
+inline int statvfs(const wchar_t *p, StatVFS *buf) {
path dir = p;
while (true) {
error_code local_ec;
return 0;
}
-wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
+inline wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
-wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
+inline wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
// Only expected to be used with us allocating the buffer.
_LIBCPP_ASSERT(resolved_name == nullptr,
"Windows realpath() assumes a null resolved_name");
#define AT_SYMLINK_NOFOLLOW 1
using ModeT = int;
-int fchmod_handle(HANDLE h, int perms) {
+inline int fchmod_handle(HANDLE h, int perms) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
return set_errno();
return 0;
}
-int fchmodat(int /*fd*/, const wchar_t *path, int perms, int flag) {
+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 0;
}
-int fchmod(int fd, int perms) {
+inline int fchmod(int fd, int perms) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return fchmod_handle(h, perms);
}
#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
using SSizeT = ::int64_t;
-SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
+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)
}
#else
-int symlink_file(const char *oldname, const char *newname) {
+inline int symlink_file(const char *oldname, const char *newname) {
return ::symlink(oldname, newname);
}
-int symlink_dir(const char *oldname, const char *newname) {
+inline int symlink_dir(const char *oldname, const char *newname) {
return ::symlink(oldname, newname);
}
using ::chdir;
#endif
-} // namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
#endif // POSIX_COMPAT_H
# define _LIBCPP_USE_UTIMENSAT
#endif
-// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template")
-
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
using chrono::duration;
using chrono::duration_cast;
}
#if defined(_LIBCPP_USE_UTIMENSAT)
-bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
ec = capture_errno();
return true;
}
#endif
-bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
#if !defined(_LIBCPP_USE_UTIMENSAT)
return posix_utimes(p, TS, ec);
#else
#endif // !_LIBCPP_WIN32API
-file_time_type __extract_last_write_time(const path& p, const StatT& st,
- error_code* ec) {
+inline file_time_type __extract_last_write_time(const path& p, const StatT& st,
+ error_code* ec) {
using detail::fs_time;
ErrorHandler<file_time_type> err("last_write_time", ec, &p);
return fs_time::convert_from_timespec(ts);
}
-} // namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
#endif // FILESYSTEM_TIME_UTILS_H