libwreport  3.23
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 
203  void read_all_or_throw(void* buf, size_t count);
204 
205  size_t write(const void* buf, size_t count);
206 
207  template<typename Container>
208  size_t write(const Container& c)
209  {
210  return write(c.data(), c.size() * sizeof(Container::value_type));
211  }
212 
214  void write_all_or_retry(const void* buf, size_t count);
215 
216  template<typename Container>
217  void write_all_or_retry(const Container& c)
218  {
219  write_all_or_retry(c.data(), c.size() * sizeof(typename Container::value_type));
220  }
221 
226  void write_all_or_throw(const void* buf, size_t count);
227 
228  template<typename Container>
229  void write_all_or_throw(const Container& c)
230  {
231  write_all_or_throw(c.data(), c.size() * sizeof(typename Container::value_type));
232  }
233 
234  off_t lseek(off_t offset, int whence=SEEK_SET);
235 
236  size_t pread(void* buf, size_t count, off_t offset);
237  size_t pwrite(const void* buf, size_t count, off_t offset);
238 
239  template<typename Container>
240  size_t pwrite(const Container& c, off_t offset)
241  {
242  return pwrite(c.data(), c.size() * sizeof(typename Container::value_type), offset);
243  }
244 
245  void ftruncate(off_t length);
246 
247  MMap mmap(size_t length, int prot, int flags, off_t offset=0);
248 
255  bool ofd_setlk(struct ::flock&);
256 
266  bool ofd_setlkw(struct ::flock&, bool retry_on_signal=true);
267 
273  bool ofd_getlk(struct ::flock&);
274 
281  void sendfile(FileDescriptor& out_fd, off_t offset, size_t count);
282 
283  operator int() const { return fd; }
284 };
285 
286 
291 {
292 protected:
293  FileDescriptor fd;
294  struct ::timespec ts[2];
295 
296 public:
299 };
300 
301 
302 
307 {
308 protected:
309  std::string pathname;
310 
311 public:
312  NamedFileDescriptor(int fd, const std::string& pathname);
315 
316  // We can copy at the NamedFileDescriptor level because the destructor does not
317  // close fd
318  NamedFileDescriptor(const NamedFileDescriptor& o) = default;
319  NamedFileDescriptor& operator=(const NamedFileDescriptor& o) = default;
320 
321  [[noreturn]] virtual void throw_error(const char* desc);
322  [[noreturn]] virtual void throw_runtime_error(const char* desc);
323 
325  const std::string& name() const { return pathname; }
326 };
327 
328 
333 {
334  using NamedFileDescriptor::NamedFileDescriptor;
335 
338 
347 
348  ManagedNamedFileDescriptor& operator=(const ManagedNamedFileDescriptor&) = delete;
350 };
351 
352 
357 {
361  struct iterator : public std::iterator<std::input_iterator_tag, struct dirent>
362  {
363  Path* path = nullptr;
364  DIR* dir = nullptr;
365  struct dirent* cur_entry = nullptr;
366 
367  // End iterator
368  iterator();
369  // Start iteration on dir
370  iterator(Path& dir);
371  iterator(iterator&) = delete;
372  iterator(iterator&& o)
373  : dir(o.dir), cur_entry(o.cur_entry)
374  {
375  o.dir = nullptr;
376  o.cur_entry = nullptr;
377  }
378  ~iterator();
379  iterator& operator=(iterator&) = delete;
380  iterator& operator=(iterator&&) = delete;
381 
382  bool operator==(const iterator& i) const;
383  bool operator!=(const iterator& i) const;
384  struct dirent& operator*() const { return *cur_entry; }
385  struct dirent* operator->() const { return cur_entry; }
386  void operator++();
387 
389  bool isdir() const;
390 
392  bool isblk() const;
393 
395  bool ischr() const;
396 
398  bool isfifo() const;
399 
401  bool islnk() const;
402 
404  bool isreg() const;
405 
407  bool issock() const;
408 
410  Path open_path(int flags=0) const;
411  };
412 
413  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
414 
418  Path(const char* pathname, int flags=0);
422  Path(const std::string& pathname, int flags=0);
426  Path(Path& parent, const char* pathname, int flags=0);
427  Path(const Path&) = delete;
428  Path(Path&&) = default;
429  Path& operator=(const Path&) = delete;
430  Path& operator=(Path&&) = default;
431 
432  DIR* fdopendir();
433 
435  iterator begin();
436 
438  iterator end();
439 
440  int openat(const char* pathname, int flags, mode_t mode=0777);
441 
443  int openat_ifexists(const char* pathname, int flags, mode_t mode=0777);
444 
445  bool faccessat(const char* pathname, int mode, int flags=0);
446 
447  void fstatat(const char* pathname, struct stat& st);
448 
450  bool fstatat_ifexists(const char* pathname, struct stat& st);
451 
453  void lstatat(const char* pathname, struct stat& st);
454 
456  bool lstatat_ifexists(const char* pathname, struct stat& st);
457 
458  void unlinkat(const char* pathname);
459 
461  void rmdirat(const char* pathname);
462 
468  void rmtree();
469 };
470 
471 
476 {
477 public:
478  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
479 
480  File(File&&) = default;
481  File(const File&) = delete;
482 
486  File(const std::string& pathname);
487 
489  File(const std::string& pathname, int flags, mode_t mode=0777);
490 
491  File& operator=(const File&) = delete;
492  File& operator=(File&&) = default;
493 
495  void open(int flags, mode_t mode=0777);
496 
501  bool open_ifexists(int flags, mode_t mode=0777);
502 
503  static File mkstemp(const std::string& prefix);
504  static File mkstemp(const char* prefix);
505  static File mkstemp(char* pathname_template);
506 };
507 
508 
514 class Tempfile : public File
515 {
516 protected:
517  bool m_unlink_on_exit = true;
518 
519 public:
520  Tempfile();
521  Tempfile(const std::string& prefix);
522  Tempfile(const char* prefix);
523  ~Tempfile();
524 
526  void unlink_on_exit(bool val);
527 
529  void unlink();
530 };
531 
532 
534 std::string read_file(const std::string &file);
535 
542 void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
543 
550 void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
551 
561 void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
562 
572 void write_file_atomically(const std::string& file, const void* data, size_t size, mode_t mode=0777);
573 
574 #if 0
575 // Create a temporary directory based on a template.
576 std::string mkdtemp(std::string templ);
577 
580 void mkFilePath(const std::string& file);
581 #endif
582 
588 bool unlink_ifexists(const std::string& file);
589 
595 bool rename_ifexists(const std::string& src, const std::string& dst);
596 
605 bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
606 
607 bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
608 
615 bool makedirs(const std::string& pathname, mode_t=0777);
616 
624 std::string which(const std::string& name);
625 
627 void unlink(const std::string& pathname);
628 
630 void rmdir(const std::string& pathname);
631 
633 void rmtree(const std::string& pathname);
634 
640 bool rmtree_ifexists(const std::string& pathname);
641 
648 void rename(const std::string& src_pathname, const std::string& dst_pathname);
649 
653 void touch(const std::string& pathname, time_t ts);
654 
658 void clock_gettime(::clockid_t clk_id, struct ::timespec& ts);
659 
663 unsigned long long timesec_elapsed(const struct ::timespec& begin, const struct ::timespec& until);
664 
668 struct Clock
669 {
670  ::clockid_t clk_id;
671  struct ::timespec ts;
672 
676  Clock(::clockid_t clk_id);
677 
682  unsigned long long elapsed();
683 };
684 
689 void getrlimit(int resource, struct ::rlimit& rlim);
691 
693 void setrlimit(int resource, const struct ::rlimit& rlim);
694 
697 {
698  int resource;
699  struct ::rlimit orig;
700 
701  OverrideRlimit(int resource, rlim_t rlim);
702  ~OverrideRlimit();
703 
705  void set(rlim_t rlim);
706 };
707 
708 }
709 }
710 
711 #endif
RAII mechanism to save restore file times at the end of some file operations.
Definition: sys.h:290
Wraps a mmapped memory area, unmapping it on destruction.
Definition: sys.h:107
Common operations on file descriptors.
Definition: sys.h:143
File in the file system.
Definition: sys.h:475
File descriptor with a name.
Definition: sys.h:306
Iterator for directory entries.
Definition: sys.h:361
File descriptor that gets automatically closed in the object destructor.
Definition: sys.h:332
Override a soft resource limit during the lifetime of the object.
Definition: sys.h:696
const std::string & name() const
Return the file pathname.
Definition: sys.h:325
String functions.
Definition: benchmark.h:13
Access to clock_gettime.
Definition: sys.h:668
Open a temporary file.
Definition: sys.h:514
Wrap a path on the file system opened with O_PATH.
Definition: sys.h:356