libwreport  3.42
sys.h
1 #ifndef WREPORT_SYS_H
2 #define WREPORT_SYS_H
3 
11 #include <dirent.h>
12 #include <fcntl.h>
13 #include <filesystem>
14 #include <iterator>
15 #include <memory>
16 #include <string>
17 #include <sys/resource.h>
18 #include <sys/stat.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 namespace wreport::sys {
24 
31 std::filesystem::path with_suffix(const std::filesystem::path& path,
32  const std::string& suffix);
33 
39 std::unique_ptr<struct stat> stat(const char* pathname);
40 
46 std::unique_ptr<struct stat> stat(const std::string& pathname);
47 
53 std::unique_ptr<struct stat> stat(const std::filesystem::path& path);
54 
59 void stat(const char* pathname, struct stat& st);
60 
65 void stat(const std::string& pathname, struct stat& st);
66 
71 void stat(const std::filesystem::path& path, struct stat& st);
72 
78 [[deprecated("Use std::filesystem::is_directory")]] bool
79 isdir(const std::string& pathname);
80 
82 [[deprecated("Use std::filesystem::is_block_file")]] bool
83 isblk(const std::string& pathname);
84 
86 [[deprecated("Use std::filesystem::is_character_file")]] bool
87 ischr(const std::string& pathname);
88 
90 [[deprecated("Use std::filesystem::is_fifo")]] bool
91 isfifo(const std::string& pathname);
92 
94 [[deprecated("Use std::filesystem::is_symlink")]] bool
95 islnk(const std::string& pathname);
96 
98 [[deprecated("Use std::filesystem::is_regular_file")]] bool
99 isreg(const std::string& pathname);
100 
102 [[deprecated("Use std::filesystem::is_socket")]] bool
103 issock(const std::string& pathname);
104 
106 time_t timestamp(const std::filesystem::path& file);
107 
109 time_t timestamp(const std::filesystem::path& file, time_t def);
110 
112 size_t size(const std::filesystem::path& file);
113 
115 size_t size(const std::filesystem::path& file, size_t def);
116 
118 ino_t inode(const std::filesystem::path& file);
119 
121 ino_t inode(const std::filesystem::path& file, ino_t def);
122 
124 bool access(const std::filesystem::path& s, int m);
125 
127 [[deprecated("Use std::filesystem::exists")]] bool exists(const std::string& s);
128 
130 [[deprecated("Use std::filesystem::current_path")]] std::string getcwd();
131 
133 [[deprecated("Use std::filesystem::current_path")]] void
134 chdir(const std::string& dir);
135 
137 void chroot(const std::filesystem::path& dir);
138 
140 mode_t umask(mode_t mask);
141 
143 std::filesystem::path abspath(const std::filesystem::path& path);
144 [[deprecated("Use abspath(const std::filesystem::path&)")]] std::string
145 abspath(const std::string& pathname);
146 std::filesystem::path abspath(const char* path);
147 
153 class MMap
154 {
155  void* addr;
156  size_t length;
157 
158 public:
159  MMap(const MMap&) = delete;
160  MMap(MMap&&);
161  MMap(void* addr, size_t length);
162  ~MMap();
163 
164  MMap& operator=(const MMap&) = delete;
165  MMap& operator=(MMap&&);
166 
167  size_t size() const { return length; }
168 
169  void munmap();
170 
171  template <typename T> operator const T*() const
172  {
173  return reinterpret_cast<const T*>(addr);
174  }
175 
176  template <typename T> operator T*() const
177  {
178  return reinterpret_cast<T*>(addr);
179  }
180 };
181 
194 {
195 protected:
196  int fd = -1;
197 
198 public:
199  FileDescriptor();
201  explicit FileDescriptor(int fd);
202  virtual ~FileDescriptor();
203 
204  // We can copy at the FileDescriptor level because the destructor does not
205  // close fd
206  FileDescriptor(const FileDescriptor& o) = default;
207  FileDescriptor& operator=(const FileDescriptor& o) = default;
208 
216  [[noreturn]] virtual void throw_error(const char* desc);
217 
225  [[noreturn]] virtual void throw_error_string(const std::string& desc);
226 
234  [[noreturn]] virtual void throw_runtime_error(const char* desc);
235 
237  bool is_open() const;
238 
244  void close();
245 
246  void fstat(struct stat& st);
247  void fchmod(mode_t mode);
248 
249  void futimens(const ::timespec ts[2]);
250 
251  void fsync();
252  void fdatasync();
253 
254  int dup();
255 
256  size_t read(void* buf, size_t count);
257 
265  bool read_all_or_retry(void* buf, size_t count);
266 
271  void read_all_or_throw(void* buf, size_t count);
272 
273  size_t write(const void* buf, size_t count);
274 
275  template <typename Container> size_t write(const Container& c)
276  {
277  return write(c.data(),
278  c.size() * sizeof(typename Container::value_type));
279  }
280 
282  void write_all_or_retry(const void* buf, size_t count);
283 
284  template <typename Container> void write_all_or_retry(const Container& c)
285  {
286  write_all_or_retry(c.data(),
287  c.size() * sizeof(typename Container::value_type));
288  }
289 
294  void write_all_or_throw(const void* buf, size_t count);
295 
296  template <typename Container> void write_all_or_throw(const Container& c)
297  {
298  write_all_or_throw(c.data(),
299  c.size() * sizeof(typename Container::value_type));
300  }
301 
302  off_t lseek(off_t offset, int whence = SEEK_SET);
303 
304  size_t pread(void* buf, size_t count, off_t offset);
305  size_t pwrite(const void* buf, size_t count, off_t offset);
306 
307  template <typename Container>
308  size_t pwrite(const Container& c, off_t offset)
309  {
310  return pwrite(c.data(),
311  c.size() * sizeof(typename Container::value_type),
312  offset);
313  }
314 
315  void ftruncate(off_t length);
316 
317  MMap mmap(size_t length, int prot, int flags, off_t offset = 0);
318 
325  bool ofd_setlk(::flock&);
326 
336  bool ofd_setlkw(::flock&, bool retry_on_signal = true);
337 
343  bool ofd_getlk(::flock&);
344 
346  int getfl();
347 
349  void setfl(int flags);
350 
351  operator int() const { return fd; }
352 };
353 
358 {
359 protected:
360  FileDescriptor fd;
361  ::timespec ts[2];
362 
363 public:
364  explicit PreserveFileTimes(FileDescriptor fd);
366 };
367 
372 {
373 protected:
374  std::filesystem::path path_;
375 
376 public:
377  NamedFileDescriptor(int fd, const std::filesystem::path& path);
380 
381  // We can copy at the NamedFileDescriptor level because the destructor does
382  // not close fd
383  NamedFileDescriptor(const NamedFileDescriptor& o) = default;
384  NamedFileDescriptor& operator=(const NamedFileDescriptor& o) = default;
385 
386  [[noreturn]] virtual void throw_error(const char* desc) override;
387  [[noreturn]] virtual void
388  throw_error_string(const std::string& desc) override;
389  [[noreturn]] virtual void throw_runtime_error(const char* desc) override;
390 
392  [[deprecated("use path() instead")]] std::string name() const
393  {
394  return path_.string();
395  }
396  const std::filesystem::path& path() const { return path_; }
397 };
398 
403 {
404  using NamedFileDescriptor::NamedFileDescriptor;
405 
408 
417 
419  operator=(const ManagedNamedFileDescriptor&) = delete;
421 };
422 
427 {
431  struct iterator
432  {
433  using iterator_category = std::input_iterator_tag;
434  using value_type = ::dirent;
435  using difference_type = int;
436  using pointer = ::dirent*;
437  using reference = ::dirent&;
438 
439  Path* path = nullptr;
440  DIR* dir = nullptr;
441  ::dirent* cur_entry = nullptr;
442 
443  // End iterator
444  iterator();
445  // Start iteration on dir
446  explicit iterator(Path& dir);
447  iterator(iterator&) = delete;
448  iterator(iterator&& o) : dir(o.dir), cur_entry(o.cur_entry)
449  {
450  o.dir = nullptr;
451  o.cur_entry = nullptr;
452  }
453  ~iterator();
454  iterator& operator=(iterator&) = delete;
455  iterator& operator=(iterator&&) = delete;
456 
457  bool operator==(const iterator& i) const;
458  bool operator!=(const iterator& i) const;
459  ::dirent& operator*() const { return *cur_entry; }
460  ::dirent* operator->() const { return cur_entry; }
461  iterator& operator++();
462 
464  bool isdir() const;
465 
467  bool isblk() const;
468 
470  bool ischr() const;
471 
473  bool isfifo() const;
474 
476  bool islnk() const;
477 
479  bool isreg() const;
480 
482  bool issock() const;
483 
485  Path open_path(int flags = 0) const;
486  };
487 
488  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
489 
493  explicit Path(const std::filesystem::path& pathname, int flags = 0,
494  mode_t mode = 0777);
498  Path(Path& parent, const char* pathname, int flags = 0, mode_t mode = 0777);
499  Path(const Path&) = delete;
500  Path(Path&&) = default;
501  Path& operator=(const Path&) = delete;
502  Path& operator=(Path&&) = default;
503 
505  void open(int flags, mode_t mode = 0777);
506 
507  DIR* fdopendir();
508 
510  iterator begin();
511 
513  iterator end();
514 
515  int openat(const char* pathname, int flags, mode_t mode = 0777);
516 
518  int openat_ifexists(const char* pathname, int flags, mode_t mode = 0777);
519 
520  bool faccessat(const char* pathname, int mode, int flags = 0);
521 
522  void fstatat(const char* pathname, struct stat& st);
523 
525  bool fstatat_ifexists(const char* pathname, struct stat& st);
526 
528  void lstatat(const char* pathname, struct stat& st);
529 
531  bool lstatat_ifexists(const char* pathname, struct stat& st);
532 
533  void unlinkat(const char* pathname);
534 
535  void mkdirat(const char* pathname, mode_t mode = 0777);
536 
538  void rmdirat(const char* pathname);
539 
540  void symlinkat(const char* target, const char* linkpath);
541 
542  std::string readlinkat(const char* pathname);
543 
549  void rmtree();
550 
551  static std::string mkdtemp(const std::filesystem::path& prefix);
552  [[deprecated(
553  "Use mkdtemp(const std::filesystem::path&)")]] static std::string
554  mkdtemp(const std::string& prefix);
555  static std::string mkdtemp(const char* prefix);
556  static std::string mkdtemp(char* pathname_template);
557 };
558 
563 {
564 public:
565  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
566 
567  File(File&&) = default;
568  File(const File&) = delete;
569 
573  explicit File(const std::filesystem::path& path);
574  explicit File(const char* path);
575  [[deprecated("Use File(const std::filesystem::path&)")]] explicit File(
576  const std::string& path);
577 
579  File(const std::filesystem::path& path, int flags, mode_t mode = 0777);
580 
581  File& operator=(const File&) = delete;
582  File& operator=(File&&) = default;
583 
585  void open(int flags, mode_t mode = 0777);
586 
591  bool open_ifexists(int flags, mode_t mode = 0777);
592 
593  static File mkstemp(const std::filesystem::path& prefix);
594  [[deprecated("Use mkstemp(const std::filesysten::path&)")]] static File
595  mkstemp(const std::string& prefix);
596  static File mkstemp(const char* prefix);
597  static File mkstemp(char* pathname_template);
598 };
599 
605 class Tempfile : public File
606 {
607 protected:
608  bool m_unlink_on_exit = true;
609 
610 public:
611  Tempfile();
612  explicit Tempfile(const std::filesystem::path& prefix);
613  [[deprecated("Use Tempfile(const std::string&)")]] explicit Tempfile(
614  const std::string& prefix);
615  explicit Tempfile(const char* prefix);
616  ~Tempfile();
617 
619  void unlink_on_exit(bool val);
620 
622  void unlink();
623 };
624 
631 class Tempdir : public Path
632 {
633 protected:
634  bool m_rmtree_on_exit = true;
635 
636 public:
637  Tempdir();
638  explicit Tempdir(const std::filesystem::path& prefix);
639  [[deprecated(
640  "Use Tempdir(const "
641  "std::filesystem::path&)")]] explicit Tempdir(const std::string&
642  prefix);
643  explicit Tempdir(const char* prefix);
644  ~Tempdir();
645 
647  void rmtree_on_exit(bool val);
648 };
649 
651 std::string read_file(const std::filesystem::path& file);
652 [[deprecated("Use read_file(const std::filesystem::path&)")]] std::string
653 read_file(const std::string& file);
654 std::string read_file(const char* file);
655 
662 void write_file(const std::filesystem::path& file, const std::string& data,
663  mode_t mode = 0777);
664 [[deprecated("Use write_file(const std::filesystem::path&, …)")]] void
665 write_file(const std::string& file, const std::string& data,
666  mode_t mode = 0777);
667 void write_file(const char* file, const std::string& data, mode_t mode = 0777);
668 
675 void write_file(const std::filesystem::path& file, const void* data,
676  size_t size, mode_t mode = 0777);
677 [[deprecated("Use write_file(const std::filesystem::path&, …)")]] void
678 write_file(const std::string& file, const void* data, size_t size,
679  mode_t mode = 0777);
680 void write_file(const char* file, const void* data, size_t size,
681  mode_t mode = 0777);
682 
692 void write_file_atomically(const std::filesystem::path& file,
693  const std::string& data, mode_t mode = 0777);
694 [[deprecated(
695  "Use write_file_atomically(const std::filesystem::path&, …)")]] void
696 write_file_atomically(const std::string& file, const std::string& data,
697  mode_t mode = 0777);
698 void write_file_atomically(const char* file, const std::string& data,
699  mode_t mode = 0777);
700 
710 void write_file_atomically(const std::filesystem::path& file, const void* data,
711  size_t size, mode_t mode = 0777);
712 [[deprecated(
713  "Use write_file_atomically(const std::filesystem::path&, …)")]] void
714 write_file_atomically(const std::string& file, const void* data, size_t size,
715  mode_t mode = 0777);
716 
717 #if 0
718 // Create a temporary directory based on a template.
719 std::string mkdtemp(std::string templ);
720 
723 void mkFilePath(const std::string& file);
724 #endif
725 
731 [[deprecated("use std::filesystem::remove")]] bool
732 unlink_ifexists(const char* file);
733 [[deprecated("use std::filesystem::remove")]] bool
734 unlink_ifexists(const std::string& file);
735 [[deprecated("use std::filesystem::remove")]] bool
736 unlink_ifexists(const std::filesystem::path& file);
737 
743 bool rename_ifexists(const std::filesystem::path& src,
744  const std::filesystem::path& dst);
745 
754 [[deprecated("use std::filesystem::create_directory")]] bool
755 mkdir_ifmissing(const std::filesystem::path& path);
756 
763 [[deprecated("use std::filesystem::create_directories")]] bool
764 makedirs(const std::filesystem::path& path);
765 
773 std::filesystem::path which(const std::string& name);
774 
776 void unlink(const std::filesystem::path& pathname);
777 
779 void rmdir(const std::filesystem::path& pathname);
780 
782 void rmtree(const std::filesystem::path& pathname);
783 
789 bool rmtree_ifexists(const std::filesystem::path& pathname);
790 [[deprecated("use rmtree_ifexists(const std::filesystem::path&)")]] bool
791 rmtree_ifexists(const std::string& pathname);
792 bool rmtree_ifexists(const char* pathname);
793 
800 [[deprecated("use std::filesystem::rename")]] void
801 rename(const std::string& src_pathname, const std::string& dst_pathname);
802 
808 void touch(const std::filesystem::path& pathname, time_t ts);
809 
815 bool touch_ifexists(const std::filesystem::path& pathname, time_t ts);
816 
820 void clock_gettime(::clockid_t clk_id, ::timespec& ts);
821 
825 unsigned long long timesec_elapsed(const ::timespec& begin,
826  const ::timespec& until);
827 
831 struct Clock
832 {
833  ::clockid_t clk_id;
834  ::timespec ts;
835 
839  explicit Clock(::clockid_t clk_id);
840 
845  unsigned long long elapsed();
846 };
847 
852 void getrlimit(int resource, ::rlimit& rlim);
854 
856 void setrlimit(int resource, const ::rlimit& rlim);
857 
860 {
861  int resource;
862  ::rlimit orig;
863 
864  OverrideRlimit(int resource, rlim_t rlim);
865  ~OverrideRlimit();
866 
868  void set(rlim_t rlim);
869 };
870 
873 {
874  std::string name;
875  bool was_set = false;
876  std::string orig_value;
877 
878  // Unset the variable
879  explicit OverrideEnvironment(const std::string& name);
880  // Set the variable to the given value
881  OverrideEnvironment(const std::string& name, const std::string& value);
883 };
884 
886 template <typename T = char> class TempBuffer
887 {
888  T* buffer = nullptr;
889 
890 public:
891  explicit TempBuffer(size_t size) : buffer(new T[size]) {}
892  ~TempBuffer() { delete[] buffer; }
893  TempBuffer(const TempBuffer&) = delete;
894  TempBuffer(TempBuffer&&) = delete;
895  TempBuffer& operator=(const TempBuffer&) = delete;
896  TempBuffer& operator=(TempBuffer&&) = delete;
897 
898  T* data() { return buffer; }
899  const T* data() const { return buffer; }
900  operator T*() { return buffer; }
901  operator const T*() const { return buffer; }
902 };
903 
905 void breakpoint();
906 
907 } // namespace wreport::sys
908 
909 #endif
virtual void throw_error(const char *desc)
Throw an exception based on errno and the given message.
std::string name() const
Return the file pathname.
Definition: sys.h:392
mode_t umask(mode_t mask)
Change umask (always succeeds and returns the previous umask)
bool isdir(const std::string &pathname)
Returns true if the given pathname is a directory, else false.
virtual void throw_error_string(const std::string &desc)
Throw an exception based on errno and the given message.
Clock(::clockid_t clk_id)
Initialize ts with the value of the given clock.
void clock_gettime(::clockid_t clk_id, ::timespec &ts)
Call clock_gettime, raising an exception if it fails.
bool isblk(const std::string &pathname)
Same as isdir but checks for block devices.
bool open_ifexists(int flags, mode_t mode=0777)
Wrap open(2) and return false instead of throwing an exception if open fails with ENOENT...
void unlink()
Unlink the file right now.
RAII mechanism to save restore file times at the end of some file operations.
Definition: sys.h:357
bool read_all_or_retry(void *buf, size_t count)
Read count bytes into bufr, retrying partial reads, stopping at EOF.
Wraps a mmapped memory area, unmapping it on destruction.
Definition: sys.h:153
void breakpoint()
Set a breakpoint at this code location.
bool is_open() const
Check if the file descriptor is open (that is, if it is not -1)
bool makedirs(const std::filesystem::path &path)
Create all the component of the given directory, including the directory itself.
bool ofd_setlk(::flock &)
Open file description locks F_OFD_SETLK operation.
virtual void throw_runtime_error(const char *desc) override
Throw a runtime_error unrelated from errno.
void close()
Close the file descriptor, setting its value to -1.
void write_file(const std::filesystem::path &file, const std::string &data, mode_t mode=0777)
Write data to file, replacing existing contents if it already exists.
Common operations on file descriptors.
Definition: sys.h:193
File in the file system.
Definition: sys.h:562
void rename(const std::string &src_pathname, const std::string &dst_pathname)
Rename src_pathname into dst_pathname.
void write_all_or_throw(const void *buf, size_t count)
Write all the data in buf, throwing runtime_error in case of a partial write.
int getfl()
Get open flags for the file.
void unlink(const std::filesystem::path &pathname)
Delete the file using unlink()
bool rename_ifexists(const std::filesystem::path &src, const std::filesystem::path &dst)
Move src to dst, without raising exception if src does not exist.
void rmdir(const std::filesystem::path &pathname)
Remove the directory using rmdir(2)
ino_t inode(const std::filesystem::path &file)
File inode number.
Operating system functions.
Definition: sys.h:23
void setrlimit(int resource, const ::rlimit &rlim)
Call setrlimit, raising an exception if it fails.
bool ofd_setlkw(::flock &, bool retry_on_signal=true)
Open file description locks F_OFD_SETLKW operation.
virtual void throw_runtime_error(const char *desc)
Throw a runtime_error unrelated from errno.
Override an environment variable for the duration of this object.
Definition: sys.h:872
iterator begin()
Begin iterator on all directory entries.
std::filesystem::path abspath(const std::filesystem::path &path)
Get the absolute path of a file.
Path open_path(int flags=0) const
Return a Path object for this entry.
bool touch_ifexists(const std::filesystem::path &pathname, time_t ts)
Set mtime and atime for the file.
File descriptor with a name.
Definition: sys.h:371
void unlink_on_exit(bool val)
Change the unlink-on-exit behaviour.
bool unlink_ifexists(const char *file)
Delete a file if it exists.
RAII local memory buffer.
Definition: sys.h:886
void lstatat(const char *pathname, struct stat &st)
fstatat with the AT_SYMLINK_NOFOLLOW flag set
void write_all_or_retry(const void *buf, size_t count)
Write all the data in buf, retrying partial writes.
Iterator for directory entries.
Definition: sys.h:431
void rmtree_on_exit(bool val)
Change the rmtree-on-exit behaviour.
File descriptor that gets automatically closed in the object destructor.
Definition: sys.h:402
std::string getcwd()
Get the absolute path of the current working directory.
bool mkdir_ifmissing(const std::filesystem::path &path)
Create the given directory, if it does not already exists.
void open(int flags, mode_t mode=0777)
Wrapper around open(2)
void chdir(const std::string &dir)
Change working directory.
bool islnk(const std::string &pathname)
Same as isdir but checks for symbolic links.
Open a temporary directory.
Definition: sys.h:631
void setfl(int flags)
Set open flags for the file.
void open(int flags, mode_t mode=0777)
Wrapper around open(2) with flags | O_PATH.
void touch(const std::filesystem::path &pathname, time_t ts)
Set mtime and atime for the file.
std::filesystem::path with_suffix(const std::filesystem::path &path, const std::string &suffix)
Return the path with suffix appended to its filename.
void getrlimit(int resource, ::rlimit &rlim)
rlimit wrappers
Override a soft resource limit during the lifetime of the object.
Definition: sys.h:859
virtual void throw_error_string(const std::string &desc) override
Throw an exception based on errno and the given message.
void read_all_or_throw(void *buf, size_t count)
Read all the data into buf, throwing runtime_error in case of a partial read.
bool isfifo(const std::string &pathname)
Same as isdir but checks for FIFOs.
std::filesystem::path which(const std::string &name)
Compute the absolute path of an executable.
iterator end()
End iterator on all directory entries.
time_t timestamp(const std::filesystem::path &file)
File mtime.
std::string read_file(const std::filesystem::path &file)
Read whole file into memory. Throws exceptions on failure.
unsigned long long elapsed()
Return the number of nanoseconds elapsed since the last time ts was updated.
void rmtree()
Delete the directory pointed to by this Path, with all its contents.
Path(const std::filesystem::path &pathname, int flags=0, mode_t mode=0777)
Open the given pathname with flags | O_PATH.
bool ischr(const std::string &pathname)
Same as isdir but checks for character devices.
void rmtree(const std::filesystem::path &pathname)
Delete the directory pathname and all its contents.
~ManagedNamedFileDescriptor()
The destructor closes the file descriptor, but does not check errors on ::close().
bool ofd_getlk(::flock &)
Open file description locks F_OFD_GETLK operation.
void chroot(const std::filesystem::path &dir)
Change root directory.
bool issock(const std::string &pathname)
Same as isdir but checks for sockets.
unsigned long long timesec_elapsed(const ::timespec &begin, const ::timespec &until)
Return the time elapsed between two timesec structures, in nanoseconds.
int openat_ifexists(const char *pathname, int flags, mode_t mode=0777)
Same as openat, but returns -1 if the file does not exist.
std::unique_ptr< struct stat > stat(const char *pathname)
stat() the given file and return the struct stat with the results.
bool fstatat_ifexists(const char *pathname, struct stat &st)
fstatat, but in case of ENOENT returns false instead of throwing
bool lstatat_ifexists(const char *pathname, struct stat &st)
lstatat, but in case of ENOENT returns false instead of throwing
bool rmtree_ifexists(const std::filesystem::path &pathname)
Delete the directory pathname and all its contents.
virtual void throw_error(const char *desc) override
Throw an exception based on errno and the given message.
Access to clock_gettime.
Definition: sys.h:831
bool access(const std::filesystem::path &s, int m)
access() a filename
Open a temporary file.
Definition: sys.h:605
bool isreg(const std::string &pathname)
Same as isdir but checks for regular files.
bool exists(const std::string &s)
Same as access(s, F_OK);.
Wrap a path on the file system opened with O_PATH.
Definition: sys.h:426
void write_file_atomically(const std::filesystem::path &file, const std::string &data, mode_t mode=0777)
Write data to file, replacing existing contents if it already exists.
size_t size(const std::filesystem::path &file)
File size.
void rmdirat(const char *pathname)
unlinkat with the AT_REMOVEDIR flag set