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
369  {
370  using iterator_category = std::input_iterator_tag;
371  using value_type = struct dirent;
372  using difference_type = int;
373  using pointer = struct dirent*;
374  using reference = struct dirent&;
375 
376  Path* path = nullptr;
377  DIR* dir = nullptr;
378  struct dirent* cur_entry = nullptr;
379 
380  // End iterator
381  iterator();
382  // Start iteration on dir
383  iterator(Path& dir);
384  iterator(iterator&) = delete;
385  iterator(iterator&& o)
386  : dir(o.dir), cur_entry(o.cur_entry)
387  {
388  o.dir = nullptr;
389  o.cur_entry = nullptr;
390  }
391  ~iterator();
392  iterator& operator=(iterator&) = delete;
393  iterator& operator=(iterator&&) = delete;
394 
395  bool operator==(const iterator& i) const;
396  bool operator!=(const iterator& i) const;
397  struct dirent& operator*() const { return *cur_entry; }
398  struct dirent* operator->() const { return cur_entry; }
399  void operator++();
400 
402  bool isdir() const;
403 
405  bool isblk() const;
406 
408  bool ischr() const;
409 
411  bool isfifo() const;
412 
414  bool islnk() const;
415 
417  bool isreg() const;
418 
420  bool issock() const;
421 
423  Path open_path(int flags=0) const;
424  };
425 
426  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
427 
431  Path(const char* pathname, int flags=0, mode_t mode=0777);
435  Path(const std::string& pathname, int flags=0, mode_t mode=0777);
439  Path(Path& parent, const char* pathname, int flags=0, mode_t mode=0777);
440  Path(const Path&) = delete;
441  Path(Path&&) = default;
442  Path& operator=(const Path&) = delete;
443  Path& operator=(Path&&) = default;
444 
446  void open(int flags, mode_t mode=0777);
447 
448  DIR* fdopendir();
449 
452 
455 
456  int openat(const char* pathname, int flags, mode_t mode=0777);
457 
459  int openat_ifexists(const char* pathname, int flags, mode_t mode=0777);
460 
461  bool faccessat(const char* pathname, int mode, int flags=0);
462 
463  void fstatat(const char* pathname, struct stat& st);
464 
466  bool fstatat_ifexists(const char* pathname, struct stat& st);
467 
469  void lstatat(const char* pathname, struct stat& st);
470 
472  bool lstatat_ifexists(const char* pathname, struct stat& st);
473 
474  void unlinkat(const char* pathname);
475 
476  void mkdirat(const char* pathname, mode_t mode=0777);
477 
479  void rmdirat(const char* pathname);
480 
481  void symlinkat(const char* target, const char* linkpath);
482 
483  std::string readlinkat(const char* pathname);
484 
490  void rmtree();
491 
492  static std::string mkdtemp(const std::string& prefix);
493  static std::string mkdtemp(const char* prefix);
494  static std::string mkdtemp(char* pathname_template);
495 };
496 
497 
502 {
503 public:
504  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
505 
506  File(File&&) = default;
507  File(const File&) = delete;
508 
512  File(const std::string& pathname);
513 
515  File(const std::string& pathname, int flags, mode_t mode=0777);
516 
517  File& operator=(const File&) = delete;
518  File& operator=(File&&) = default;
519 
521  void open(int flags, mode_t mode=0777);
522 
527  bool open_ifexists(int flags, mode_t mode=0777);
528 
529  static File mkstemp(const std::string& prefix);
530  static File mkstemp(const char* prefix);
531  static File mkstemp(char* pathname_template);
532 };
533 
534 
540 class Tempfile : public File
541 {
542 protected:
543  bool m_unlink_on_exit = true;
544 
545 public:
546  Tempfile();
547  Tempfile(const std::string& prefix);
548  Tempfile(const char* prefix);
549  ~Tempfile();
550 
552  void unlink_on_exit(bool val);
553 
555  void unlink();
556 };
557 
558 
565 class Tempdir : public Path
566 {
567 protected:
568  bool m_rmtree_on_exit = true;
569 
570 public:
571  Tempdir();
572  Tempdir(const std::string& prefix);
573  Tempdir(const char* prefix);
574  ~Tempdir();
575 
577  void rmtree_on_exit(bool val);
578 };
579 
580 
582 std::string read_file(const std::string &file);
583 
590 void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
591 
598 void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
599 
609 void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
610 
620 void write_file_atomically(const std::string& file, const void* data, size_t size, mode_t mode=0777);
621 
622 #if 0
623 // Create a temporary directory based on a template.
624 std::string mkdtemp(std::string templ);
625 
628 void mkFilePath(const std::string& file);
629 #endif
630 
636 bool unlink_ifexists(const std::string& file);
637 
643 bool rename_ifexists(const std::string& src, const std::string& dst);
644 
653 bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
654 
655 bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
656 
663 bool makedirs(const std::string& pathname, mode_t=0777);
664 
672 std::string which(const std::string& name);
673 
675 void unlink(const std::string& pathname);
676 
678 void rmdir(const std::string& pathname);
679 
681 void rmtree(const std::string& pathname);
682 
688 bool rmtree_ifexists(const std::string& pathname);
689 
696 void rename(const std::string& src_pathname, const std::string& dst_pathname);
697 
701 void touch(const std::string& pathname, time_t ts);
702 
706 void clock_gettime(::clockid_t clk_id, struct ::timespec& ts);
707 
711 unsigned long long timesec_elapsed(const struct ::timespec& begin, const struct ::timespec& until);
712 
716 struct Clock
717 {
718  ::clockid_t clk_id;
719  struct ::timespec ts;
720 
724  Clock(::clockid_t clk_id);
725 
730  unsigned long long elapsed();
731 };
732 
738 void getrlimit(int resource, struct ::rlimit& rlim);
739 
741 void setrlimit(int resource, const struct ::rlimit& rlim);
742 
745 {
746  int resource;
747  struct ::rlimit orig;
748 
749  OverrideRlimit(int resource, rlim_t rlim);
750  ~OverrideRlimit();
751 
753  void set(rlim_t rlim);
754 };
755 
756 }
757 }
758 
759 #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:502
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:566
void rmtree_on_exit(bool val)
Change the rmtree-on-exit behaviour.
Open a temporary file.
Definition: sys.h:541
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:717
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:745
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.