19namespace swoc {
inline namespace SWOC_VERSION_NS {
26 return parent ? parent :
"/"_tv;
32 return _path.substr(1);
40 return idx == std::string::npos ? self_type(
_path) :
_path.substr(idx + 1);
63 switch (_stat.st_mode & S_IFMT) {
65 _type = file_type::regular;
68 _type = file_type::directory;
71 _type = file_type::symlink;
74 _type = file_type::block;
77 _type = file_type::character;
80 _type = file_type::fifo;
83 _type = file_type::socket;
86 _type = file_type::unknown;
94 if (::stat(file.c_str(), &zret.
_stat) >= 0) {
98 ec = std::error_code(errno, std::system_category());
99 if (errno == ENOENT) {
100 zret._type = file_type::not_found;
108 return fs.
_stat.st_mode & S_IFMT;
113 return fs.
_stat.st_size;
130 auto s = realpath(src.
c_str(), buff);
132 if (errno == ENAMETOOLONG) {
133 s = realpath(src.
c_str(),
nullptr);
140 ec = std::error_code(errno, std::system_category());
149chrono_cast(timespec
const &ts) {
150 using namespace std::chrono;
151 return system_clock::time_point{duration_cast<system_clock::duration>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec})};
158a_time(S
const &s, meta::CaseTag<0>) ->
decltype(S::st_atim) {
164a_time(S
const &s, meta::CaseTag<1>) ->
decltype(S::st_atimespec) {
165 return s.st_atimespec;
170m_time(S
const &s, meta::CaseTag<0>) ->
decltype(S::st_mtim) {
176m_time(S
const &s, meta::CaseTag<1>) ->
decltype(S::st_mtimespec) {
177 return s.st_mtimespec;
182c_time(S
const &s, meta::CaseTag<0>) ->
decltype(S::st_ctim) {
188c_time(S
const &s, meta::CaseTag<1>) ->
decltype(S::st_ctimespec) {
189 return s.st_ctimespec;
196 return chrono_cast(m_time(fs.
_stat, meta::CaseArg));
201 return chrono_cast(a_time(fs.
_stat, meta::CaseArg));
206 return chrono_cast(c_time(fs.
_stat, meta::CaseArg));
213 return file_time_type::min();
220 return 0 == access(p.
c_str(), R_OK);
228 for (
char const *tp : {
"TMPDIR",
"TMP",
"TEMPDIR"}) {
229 if (
auto v = ::getenv(tp); v) {
238 char buff[PATH_MAX + 1];
239 if (
auto p = ::getcwd(buff,
sizeof(buff)); p) {
241#if !__FreeBSD__ && !__APPLE__
242 }
else if (ERANGE == errno) {
244 return path{raw.get()};
253 ec = std::error_code(EINVAL, std::system_category());
257 char buf[PATH_MAX + 1];
259 if (
auto rp = ::realpath(p.
c_str(), buf); rp) {
263 if (
auto rp = ::realpath(p.
c_str(),
nullptr); rp) {
267 ec = std::error_code(errno, std::system_category());
274 ec = std::error_code(EINVAL, std::system_category());
280 if (EEXIST == errno) {
281 std::error_code local_ec;
283 if (!local_ec &&
is_dir(fs)) {
287 ec = std::error_code(errno, std::system_category());
298 ec = std::error_code(EINVAL, std::system_category());
328 static constexpr size_t BUF_SIZE = 65536;
329 std::error_code local_ec;
334 ec = std::error_code(EINVAL, std::system_category());
341 if (NO_FD == src_fd) {
342 ec = std::error_code(errno, std::system_category());
348 if (
auto fs =
file::status(to, local_ec); !(local_ec && ENOENT == local_ec.value()) &&
is_dir(fs)) {
354 unique_fd dst_fd{::open(final_to.
c_str(), O_WRONLY | O_CREAT, src_fs.mode())};
355 if (NO_FD == dst_fd) {
356 ec = std::error_code(errno, std::system_category());
361 if (
auto n = read(src_fd, span.data(), span.size()); n > 0) {
362 if (::write(dst_fd, span.data(), n) < n) {
363 ec = std::error_code(errno, std::system_category());
378 struct dirent *entry =
nullptr;
384 ec = std::error_code(EINVAL, std::system_category());
386 }
else if (::stat(p.
c_str(), &s) < 0) {
387 ec = std::error_code(errno, std::system_category());
389 }
else if (S_ISREG(s.st_mode)) {
391 if (unlink(p.
c_str()) != 0) {
392 ec = std::error_code(errno, std::system_category());
397 }
else if (!S_ISDIR(s.st_mode)) {
398 ec = std::error_code(ENOTDIR, std::system_category());
405 if (
nullptr == (dir = opendir(p.
c_str()))) {
406 ec = std::error_code(errno, std::system_category());
411 while (
nullptr != (entry = readdir(dir))) {
412 if (!
strcmp(entry->d_name,
".") || !
strcmp(entry->d_name,
"..")) {
416 child /= entry->d_name;
420 if (0 != rmdir(p.
c_str())) {
421 ec = std::error_code(errno, std::system_category());
434 ec = std::error_code(EINVAL, std::system_category());
435 }
else if (::stat(p.
c_str(), &fs) < 0) {
436 ec = std::error_code(errno, std::system_category());
437 }
else if (S_ISREG(fs.st_mode)) {
439 if (unlink(p.
c_str()) != 0) {
440 ec = std::error_code(errno, std::system_category());
442 }
else if (S_ISDIR(fs.st_mode)) {
444 if (rmdir(p.
c_str()) != 0) {
445 ec = std::error_code(errno, std::system_category());
448 ec = std::error_code(EINVAL, std::system_category());
458 ec = std::error_code(errno, std::system_category());
461 if (0 != ::fstat(fd, &info)) {
462 ec = std::error_code(errno, std::system_category());
464 auto n = info.st_size;
466 auto read_len = ::read(fd, zret.data(), n);
468 ec = std::error_code(errno, std::system_category());
constexpr self_type prefix(size_t n) const noexcept
self_type take_prefix_at(char c)
self_type split_suffix_at(char c)
Information about a file.
friend file_time_type last_write_time(file_status const &fs)
friend file_time_type access_time(file_status const &fs)
struct::stat _stat
File information.
friend uintmax_t file_size(const self_type &)
Size of the file or block device.
friend self_type status(const path &file, std::error_code &ec) noexcept
friend int file_type(const self_type &)
Return the file type value.
friend file_time_type status_time(file_status const &fs)
bool empty() const
Check if the path is empty.
static constexpr char SEPARATOR
Default path separator.
self_type & reserve(size_t n)
char const * c_str() const
Access the path explicitly.
self_type relative_path() const
self_type filename() const
self_type & operator/=(const self_type &that)
std::string _path
File path.
self_type parent_path() const
Path of the parent.
std::string const & string() const
The path as a string.
bool is_absolute() const
Check if the path is absolute.
For template deduction guides.
BufferWriter & bwformat(BufferWriter &w, bwf::Spec const &spec, std::string_view sv)
std::unique_ptr< T, detail::malloc_liberator > unique_malloc
A variant of unique_ptr that handles memory from malloc.
int strcmp(const std::string_view &lhs, const std::string_view &rhs)
Scoped container for a file descriptor.
bool exists(const path &p)
Check if path exists.
path temp_directory_path()
Directory location suitable for temporary files.
uintmax_t remove_all(const path &p, std::error_code &ec)
file_time_type last_write_time(file_status const &fs)
std::string load(const path &p, std::error_code &ec)
bool copy(const path &from, const path &to, std::error_code &ec)
bool create_directories(const path &p, std::error_code &ec, mode_t mode) noexcept
bool is_readable(const path &p)
Check if file is readable.
path absolute(path const &src, std::error_code &ec)
path canonical(const path &p, std::error_code &ec)
bool create_directory(const path &path, std::error_code &ec, mode_t mode) noexcept
bool remove(path const &p, std::error_code &ec)
file_status status(path const &file, std::error_code &ec) noexcept
path current_path()
Current working directory.
bool is_dir(const file_status &p)
Check if the path is to a directory.