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 
436 
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 
690 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
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.
bool ofd_setlk(struct ::flock &)
Open file description locks F_OFD_SETLK operation.
void sendfile(FileDescriptor &out_fd, off_t offset, size_t count)
Call sendfile with this file as in_fd, falling back on write if it is not available.
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.
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:476
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:307
const std::string & name() const
Return the file pathname.
Definition: sys.h:325
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:291
Open a temporary file.
Definition: sys.h:515
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:669
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:333
~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:697
void set(rlim_t rlim)
Change the limit value again.
Iterator for directory entries.
Definition: sys.h:362
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:357
bool lstatat_ifexists(const char *pathname, struct stat &st)
lstatat, but in case of ENOENT returns false instead of throwing
Path(Path &parent, const char *pathname, int flags=0)
Open the given pathname calling parent.openat, 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.
iterator begin()
Begin iterator on all directory entries.
Path(const char *pathname, int flags=0)
Open the given pathname with flags | O_PATH.
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 std::string &pathname, int flags=0)
Open the given pathname with flags | O_PATH.
iterator end()
End iterator on all directory entries.