libwreport  3.34
sys.h
1 #ifndef WREPORT_SYS_H
2 #define WREPORT_SYS_H
3 
11 #include <string>
12 #include <memory>
13 #include <iterator>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #include <unistd.h>
19 #include <dirent.h>
20 #include <fcntl.h>
21 
22 namespace wreport {
23 namespace sys {
24 
30 std::unique_ptr<struct stat> stat(const std::string& pathname);
31 
36 void stat(const std::string& pathname, struct stat& st);
37 
43 bool isdir(const std::string& pathname);
44 
46 bool isblk(const std::string& pathname);
47 
49 bool ischr(const std::string& pathname);
50 
52 bool isfifo(const std::string& pathname);
53 
55 bool islnk(const std::string& pathname);
56 
58 bool isreg(const std::string& pathname);
59 
61 bool issock(const std::string& pathname);
62 
64 time_t timestamp(const std::string& file);
65 
67 time_t timestamp(const std::string& file, time_t def);
68 
70 size_t size(const std::string& file);
71 
73 size_t size(const std::string& file, size_t def);
74 
76 ino_t inode(const std::string& file);
77 
79 ino_t inode(const std::string& file, ino_t def);
80 
82 bool access(const std::string& s, int m);
83 
85 bool exists(const std::string& s);
86 
88 std::string getcwd();
89 
91 void chdir(const std::string& dir);
92 
94 void chroot(const std::string& dir);
95 
97 mode_t umask(mode_t mask);
98 
100 std::string abspath(const std::string& pathname);
101 
107 class MMap
108 {
109  void* addr;
110  size_t length;
111 
112 public:
113  MMap(const MMap&) = delete;
114  MMap(MMap&&);
115  MMap(void* addr, size_t length);
116  ~MMap();
117 
118  MMap& operator=(const MMap&) = delete;
119  MMap& operator=(MMap&&);
120 
121  size_t size() const { return length; }
122 
123  void munmap();
124 
125  template<typename T>
126  operator const T*() const { return reinterpret_cast<const T*>(addr); }
127 
128  template<typename T>
129  operator T*() const { return reinterpret_cast<T*>(addr); }
130 };
131 
144 {
145 protected:
146  int fd = -1;
147 
148 public:
149  FileDescriptor();
151  FileDescriptor(int fd);
152  virtual ~FileDescriptor();
153 
154  // We can copy at the FileDescriptor level because the destructor does not
155  // close fd
156  FileDescriptor(const FileDescriptor& o) = default;
157  FileDescriptor& operator=(const FileDescriptor& o) = default;
158 
166  [[noreturn]] virtual void throw_error(const char* desc);
167 
175  [[noreturn]] virtual void throw_runtime_error(const char* desc);
176 
178  bool is_open() const;
179 
185  void close();
186 
187  void fstat(struct stat& st);
188  void fchmod(mode_t mode);
189 
190  void futimens(const struct ::timespec ts[2]);
191 
192  void fsync();
193  void fdatasync();
194 
195  int dup();
196 
197  size_t read(void* buf, size_t count);
198 
206  bool read_all_or_retry(void* buf, size_t count);
207 
212  void read_all_or_throw(void* buf, size_t count);
213 
214  size_t write(const void* buf, size_t count);
215 
216  template<typename Container>
217  size_t write(const Container& c)
218  {
219  return write(c.data(), c.size() * sizeof(Container::value_type));
220  }
221 
223  void write_all_or_retry(const void* buf, size_t count);
224 
225  template<typename Container>
226  void write_all_or_retry(const Container& c)
227  {
228  write_all_or_retry(c.data(), c.size() * sizeof(typename Container::value_type));
229  }
230 
235  void write_all_or_throw(const void* buf, size_t count);
236 
237  template<typename Container>
238  void write_all_or_throw(const Container& c)
239  {
240  write_all_or_throw(c.data(), c.size() * sizeof(typename Container::value_type));
241  }
242 
243  off_t lseek(off_t offset, int whence=SEEK_SET);
244 
245  size_t pread(void* buf, size_t count, off_t offset);
246  size_t pwrite(const void* buf, size_t count, off_t offset);
247 
248  template<typename Container>
249  size_t pwrite(const Container& c, off_t offset)
250  {
251  return pwrite(c.data(), c.size() * sizeof(typename Container::value_type), offset);
252  }
253 
254  void ftruncate(off_t length);
255 
256  MMap mmap(size_t length, int prot, int flags, off_t offset=0);
257 
264  bool ofd_setlk(struct ::flock&);
265 
275  bool ofd_setlkw(struct ::flock&, bool retry_on_signal=true);
276 
282  bool ofd_getlk(struct ::flock&);
283 
285  int getfl();
286 
288  void setfl(int flags);
289 
290  operator int() const { return fd; }
291 };
292 
293 
298 {
299 protected:
300  FileDescriptor fd;
301  struct ::timespec ts[2];
302 
303 public:
306 };
307 
308 
309 
314 {
315 protected:
316  std::string pathname;
317 
318 public:
319  NamedFileDescriptor(int fd, const std::string& pathname);
322 
323  // We can copy at the NamedFileDescriptor level because the destructor does not
324  // close fd
325  NamedFileDescriptor(const NamedFileDescriptor& o) = default;
326  NamedFileDescriptor& operator=(const NamedFileDescriptor& o) = default;
327 
328  [[noreturn]] virtual void throw_error(const char* desc);
329  [[noreturn]] virtual void throw_runtime_error(const char* desc);
330 
332  const std::string& name() const { return pathname; }
333 };
334 
335 
340 {
341  using NamedFileDescriptor::NamedFileDescriptor;
342 
345 
354 
355  ManagedNamedFileDescriptor& operator=(const ManagedNamedFileDescriptor&) = delete;
357 };
358 
359 
364 {
368  struct iterator : public std::iterator<std::input_iterator_tag, struct dirent>
369  {
370  Path* path = nullptr;
371  DIR* dir = nullptr;
372  struct dirent* cur_entry = nullptr;
373 
374  // End iterator
375  iterator();
376  // Start iteration on dir
377  iterator(Path& dir);
378  iterator(iterator&) = delete;
379  iterator(iterator&& o)
380  : dir(o.dir), cur_entry(o.cur_entry)
381  {
382  o.dir = nullptr;
383  o.cur_entry = nullptr;
384  }
385  ~iterator();
386  iterator& operator=(iterator&) = delete;
387  iterator& operator=(iterator&&) = delete;
388 
389  bool operator==(const iterator& i) const;
390  bool operator!=(const iterator& i) const;
391  struct dirent& operator*() const { return *cur_entry; }
392  struct dirent* operator->() const { return cur_entry; }
393  void operator++();
394 
396  bool isdir() const;
397 
399  bool isblk() const;
400 
402  bool ischr() const;
403 
405  bool isfifo() const;
406 
408  bool islnk() const;
409 
411  bool isreg() const;
412 
414  bool issock() const;
415 
417  Path open_path(int flags=0) const;
418  };
419 
420  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
421 
425  Path(const char* pathname, int flags=0, mode_t mode=0777);
429  Path(const std::string& pathname, int flags=0, mode_t mode=0777);
433  Path(Path& parent, const char* pathname, int flags=0, mode_t mode=0777);
434  Path(const Path&) = delete;
435  Path(Path&&) = default;
436  Path& operator=(const Path&) = delete;
437  Path& operator=(Path&&) = default;
438 
440  void open(int flags, mode_t mode=0777);
441 
442  DIR* fdopendir();
443 
446 
449 
450  int openat(const char* pathname, int flags, mode_t mode=0777);
451 
453  int openat_ifexists(const char* pathname, int flags, mode_t mode=0777);
454 
455  bool faccessat(const char* pathname, int mode, int flags=0);
456 
457  void fstatat(const char* pathname, struct stat& st);
458 
460  bool fstatat_ifexists(const char* pathname, struct stat& st);
461 
463  void lstatat(const char* pathname, struct stat& st);
464 
466  bool lstatat_ifexists(const char* pathname, struct stat& st);
467 
468  void unlinkat(const char* pathname);
469 
470  void mkdirat(const char* pathname, mode_t mode=0777);
471 
473  void rmdirat(const char* pathname);
474 
475  void symlinkat(const char* target, const char* linkpath);
476 
477  std::string readlinkat(const char* pathname);
478 
484  void rmtree();
485 
486  static std::string mkdtemp(const std::string& prefix);
487  static std::string mkdtemp(const char* prefix);
488  static std::string mkdtemp(char* pathname_template);
489 };
490 
491 
496 {
497 public:
498  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
499 
500  File(File&&) = default;
501  File(const File&) = delete;
502 
506  File(const std::string& pathname);
507 
509  File(const std::string& pathname, int flags, mode_t mode=0777);
510 
511  File& operator=(const File&) = delete;
512  File& operator=(File&&) = default;
513 
515  void open(int flags, mode_t mode=0777);
516 
521  bool open_ifexists(int flags, mode_t mode=0777);
522 
523  static File mkstemp(const std::string& prefix);
524  static File mkstemp(const char* prefix);
525  static File mkstemp(char* pathname_template);
526 };
527 
528 
534 class Tempfile : public File
535 {
536 protected:
537  bool m_unlink_on_exit = true;
538 
539 public:
540  Tempfile();
541  Tempfile(const std::string& prefix);
542  Tempfile(const char* prefix);
543  ~Tempfile();
544 
546  void unlink_on_exit(bool val);
547 
549  void unlink();
550 };
551 
552 
559 class Tempdir : public Path
560 {
561 protected:
562  bool m_rmtree_on_exit = true;
563 
564 public:
565  Tempdir();
566  Tempdir(const std::string& prefix);
567  Tempdir(const char* prefix);
568  ~Tempdir();
569 
571  void rmtree_on_exit(bool val);
572 };
573 
574 
576 std::string read_file(const std::string &file);
577 
584 void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
585 
592 void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
593 
603 void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
604 
614 void write_file_atomically(const std::string& file, const void* data, size_t size, mode_t mode=0777);
615 
616 #if 0
617 // Create a temporary directory based on a template.
618 std::string mkdtemp(std::string templ);
619 
622 void mkFilePath(const std::string& file);
623 #endif
624 
630 bool unlink_ifexists(const std::string& file);
631 
637 bool rename_ifexists(const std::string& src, const std::string& dst);
638 
647 bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
648 
649 bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
650 
657 bool makedirs(const std::string& pathname, mode_t=0777);
658 
666 std::string which(const std::string& name);
667 
669 void unlink(const std::string& pathname);
670 
672 void rmdir(const std::string& pathname);
673 
675 void rmtree(const std::string& pathname);
676 
682 bool rmtree_ifexists(const std::string& pathname);
683 
690 void rename(const std::string& src_pathname, const std::string& dst_pathname);
691 
695 void touch(const std::string& pathname, time_t ts);
696 
700 void clock_gettime(::clockid_t clk_id, struct ::timespec& ts);
701 
705 unsigned long long timesec_elapsed(const struct ::timespec& begin, const struct ::timespec& until);
706 
710 struct Clock
711 {
712  ::clockid_t clk_id;
713  struct ::timespec ts;
714 
718  Clock(::clockid_t clk_id);
719 
724  unsigned long long elapsed();
725 };
726 
732 void getrlimit(int resource, struct ::rlimit& rlim);
733 
735 void setrlimit(int resource, const struct ::rlimit& rlim);
736 
739 {
740  int resource;
741  struct ::rlimit orig;
742 
743  OverrideRlimit(int resource, rlim_t rlim);
744  ~OverrideRlimit();
745 
747  void set(rlim_t rlim);
748 };
749 
750 }
751 }
752 
753 #endif
Common operations on file descriptors.
Definition: sys.h:144
void write_all_or_retry(const void *buf, size_t count)
Write all the data in buf, retrying partial writes.
void setfl(int flags)
Set open flags for the file.
bool ofd_setlk(struct ::flock &)
Open file description locks F_OFD_SETLK operation.
bool read_all_or_retry(void *buf, size_t count)
Read count bytes into bufr, retrying partial reads, stopping at EOF.
bool ofd_setlkw(struct ::flock &, bool retry_on_signal=true)
Open file description locks F_OFD_SETLKW operation.
bool ofd_getlk(struct ::flock &)
Open file description locks F_OFD_GETLK operation.
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.
void close()
Close the file descriptor, setting its value to -1.
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.
int getfl()
Get open flags for the file.
bool is_open() const
Check if the file descriptor is open (that is, if it is not -1)
virtual void throw_runtime_error(const char *desc)
Throw a runtime_error unrelated from errno.
virtual void throw_error(const char *desc)
Throw an exception based on errno and the given message.
File in the file system.
Definition: sys.h:496
void open(int flags, mode_t mode=0777)
Wrapper around open(2)
File(const std::string &pathname, int flags, mode_t mode=0777)
Wrapper around open(2)
File(const std::string &pathname)
Create an unopened File object for the given pathname.
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.
Wraps a mmapped memory area, unmapping it on destruction.
Definition: sys.h:108
File descriptor with a name.
Definition: sys.h:314
const std::string & name() const
Return the file pathname.
Definition: sys.h:332
virtual void throw_runtime_error(const char *desc)
Throw a runtime_error unrelated from errno.
virtual void throw_error(const char *desc)
Throw an exception based on errno and the given message.
RAII mechanism to save restore file times at the end of some file operations.
Definition: sys.h:298
Open a temporary directory.
Definition: sys.h:560
void rmtree_on_exit(bool val)
Change the rmtree-on-exit behaviour.
Open a temporary file.
Definition: sys.h:535
void unlink_on_exit(bool val)
Change the unlink-on-exit behaviour.
void unlink()
Unlink the file right now.
String functions.
Definition: benchmark.h:13
Access to clock_gettime.
Definition: sys.h:711
Clock(::clockid_t clk_id)
Initialize ts with the value of the given clock.
unsigned long long elapsed()
Return the number of nanoseconds elapsed since the last time ts was updated.
File descriptor that gets automatically closed in the object destructor.
Definition: sys.h:340
~ManagedNamedFileDescriptor()
The destructor closes the file descriptor, but does not check errors on ::close().
Override a soft resource limit during the lifetime of the object.
Definition: sys.h:739
void set(rlim_t rlim)
Change the limit value again.
Iterator for directory entries.
Definition: sys.h:369
Path open_path(int flags=0) const
Return a Path object for this entry.
Wrap a path on the file system opened with O_PATH.
Definition: sys.h:364
bool lstatat_ifexists(const char *pathname, struct stat &st)
lstatat, but in case of ENOENT returns false instead of throwing
Path(const std::string &pathname, int flags=0, mode_t mode=0777)
Open the given pathname with flags | O_PATH.
void lstatat(const char *pathname, struct stat &st)
fstatat with the AT_SYMLINK_NOFOLLOW flag set
int openat_ifexists(const char *pathname, int flags, mode_t mode=0777)
Same as openat, but returns -1 if the file does not exist.
void open(int flags, mode_t mode=0777)
Wrapper around open(2) with flags | O_PATH.
iterator begin()
Begin iterator on all directory entries.
bool fstatat_ifexists(const char *pathname, struct stat &st)
fstatat, but in case of ENOENT returns false instead of throwing
void rmdirat(const char *pathname)
unlinkat with the AT_REMOVEDIR flag set
void rmtree()
Delete the directory pointed to by this Path, with all its contents.
Path(const char *pathname, int flags=0, mode_t mode=0777)
Open the given pathname with flags | O_PATH.
iterator end()
End iterator on all directory entries.
Path(Path &parent, const char *pathname, int flags=0, mode_t mode=0777)
Open the given pathname calling parent.openat, with flags | O_PATH.