libwreport  3.10
sys.h
1 #ifndef WREPORT_SYS_H
2 #define WREPORT_SYS_H
3 
11 #include <string>
12 //#include <iosfwd>
13 #include <memory>
14 #include <iterator>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <dirent.h>
19 #include <fcntl.h>
20 
21 namespace wreport {
22 namespace sys {
23 
29 std::unique_ptr<struct stat> stat(const std::string& pathname);
30 
35 void stat(const std::string& pathname, struct stat& st);
36 
42 bool isdir(const std::string& pathname);
43 
45 bool isblk(const std::string& pathname);
46 
48 bool ischr(const std::string& pathname);
49 
51 bool isfifo(const std::string& pathname);
52 
54 bool islnk(const std::string& pathname);
55 
57 bool isreg(const std::string& pathname);
58 
60 bool issock(const std::string& pathname);
61 
63 time_t timestamp(const std::string& file);
64 
66 time_t timestamp(const std::string& file, time_t def);
67 
69 size_t size(const std::string& file);
70 
72 size_t size(const std::string& file, size_t def);
73 
75 ino_t inode(const std::string& file);
76 
78 ino_t inode(const std::string& file, ino_t def);
79 
81 bool access(const std::string& s, int m);
82 
84 bool exists(const std::string& s);
85 
87 std::string getcwd();
88 
90 std::string abspath(const std::string& pathname);
91 
97 class MMap
98 {
99  void* addr;
100  size_t length;
101 
102 public:
103  MMap(const MMap&) = delete;
104  MMap(MMap&&);
105  MMap(void* addr, size_t length);
106  ~MMap();
107 
108  MMap& operator=(const MMap&) = delete;
109  MMap& operator=(MMap&&);
110 
111  size_t size() const { return length; }
112 
113  void munmap();
114 
115  template<typename T>
116  operator const T*() const { return reinterpret_cast<const T*>(addr); }
117 
118  template<typename T>
119  operator T*() const { return reinterpret_cast<T*>(addr); };
120 };
121 
134 {
135 protected:
136  int fd = -1;
137 
138 public:
139  FileDescriptor();
141  FileDescriptor(int fd);
142  virtual ~FileDescriptor();
143 
144  // We can copy at the FileDescriptor level because the destructor does not
145  // close fd
146  FileDescriptor(const FileDescriptor& o) = default;
147  FileDescriptor& operator=(const FileDescriptor& o) = default;
148 
156  [[noreturn]] virtual void throw_error(const char* desc);
157 
165  [[noreturn]] virtual void throw_runtime_error(const char* desc);
166 
168  bool is_open() const;
169 
175  void close();
176 
177  void fstat(struct stat& st);
178  void fchmod(mode_t mode);
179 
180  void futimens(const struct timespec ts[2]);
181 
182  void fsync();
183  void fdatasync();
184 
185  int dup();
186 
187  size_t read(void* buf, size_t count);
188 
193  void read_all_or_throw(void* buf, size_t count);
194 
195  size_t write(const void* buf, size_t count);
196 
197  template<typename Container>
198  size_t write(const Container& c)
199  {
200  return write(c.data(), c.size() * sizeof(Container::value_type));
201  }
202 
204  void write_all_or_retry(const void* buf, size_t count);
205 
206  template<typename Container>
207  void write_all_or_retry(const Container& c)
208  {
209  write_all_or_retry(c.data(), c.size() * sizeof(typename Container::value_type));
210  }
211 
216  void write_all_or_throw(const void* buf, size_t count);
217 
218  template<typename Container>
219  void write_all_or_throw(const Container& c)
220  {
221  write_all_or_throw(c.data(), c.size() * sizeof(typename Container::value_type));
222  }
223 
224  off_t lseek(off_t offset, int whence=SEEK_SET);
225 
226  size_t pread(void* buf, size_t count, off_t offset);
227  size_t pwrite(const void* buf, size_t count, off_t offset);
228 
229  template<typename Container>
230  size_t pwrite(const Container& c, off_t offset)
231  {
232  return pwrite(c.data(), c.size() * sizeof(typename Container::value_type), offset);
233  }
234 
235  void ftruncate(off_t length);
236 
237  MMap mmap(size_t length, int prot, int flags, off_t offset=0);
238 
245  bool ofd_setlk(struct ::flock&);
246 
256  bool ofd_setlkw(struct ::flock&, bool retry_on_signal=true);
257 
263  bool ofd_getlk(struct ::flock&);
264 
265  operator int() const { return fd; }
266 };
267 
268 
273 {
274 protected:
275  FileDescriptor fd;
276  struct timespec ts[2];
277 
278 public:
281 };
282 
283 
284 
289 {
290 protected:
291  std::string pathname;
292 
293 public:
294  NamedFileDescriptor(int fd, const std::string& pathname);
297 
298  // We can copy at the NamedFileDescriptor level because the destructor does not
299  // close fd
300  NamedFileDescriptor(const NamedFileDescriptor& o) = default;
301  NamedFileDescriptor& operator=(const NamedFileDescriptor& o) = default;
302 
303  [[noreturn]] virtual void throw_error(const char* desc);
304  [[noreturn]] virtual void throw_runtime_error(const char* desc);
305 
307  const std::string& name() const { return pathname; }
308 };
309 
310 
315 {
316  using NamedFileDescriptor::NamedFileDescriptor;
317 
320 
329 
330  ManagedNamedFileDescriptor& operator=(const ManagedNamedFileDescriptor&) = delete;
332 };
333 
334 
339 {
343  struct iterator : public std::iterator<std::input_iterator_tag, struct dirent>
344  {
345  Path* path = nullptr;
346  DIR* dir = nullptr;
347  struct dirent* cur_entry = nullptr;
348 
349  // End iterator
350  iterator();
351  // Start iteration on dir
352  iterator(Path& dir);
353  iterator(iterator&) = delete;
354  iterator(iterator&& o)
355  : dir(o.dir), cur_entry(o.cur_entry)
356  {
357  o.dir = nullptr;
358  o.cur_entry = nullptr;
359  }
360  ~iterator();
361  iterator& operator=(iterator&) = delete;
362  iterator& operator=(iterator&&) = delete;
363 
364  bool operator==(const iterator& i) const;
365  bool operator!=(const iterator& i) const;
366  struct dirent& operator*() const { return *cur_entry; }
367  struct dirent* operator->() const { return cur_entry; }
368  void operator++();
369 
371  bool isdir() const;
372 
374  bool isblk() const;
375 
377  bool ischr() const;
378 
380  bool isfifo() const;
381 
383  bool islnk() const;
384 
386  bool isreg() const;
387 
389  bool issock() const;
390 
392  Path open_path(int flags=0) const;
393  };
394 
395  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
396 
400  Path(const char* pathname, int flags=0);
404  Path(const std::string& pathname, int flags=0);
408  Path(Path& parent, const char* pathname, int flags=0);
409  Path(const Path&) = delete;
410  Path(Path&&) = default;
411  Path& operator=(const Path&) = delete;
412  Path& operator=(Path&&) = default;
413 
414  DIR* fdopendir();
415 
417  iterator begin();
418 
420  iterator end();
421 
422  int openat(const char* pathname, int flags, mode_t mode=0777);
423 
424  bool faccessat(const char* pathname, int mode, int flags=0);
425 
426  void fstatat(const char* pathname, struct stat& st);
427 
429  bool fstatat_ifexists(const char* pathname, struct stat& st);
430 
432  void lstatat(const char* pathname, struct stat& st);
433 
435  bool lstatat_ifexists(const char* pathname, struct stat& st);
436 
437  void unlinkat(const char* pathname);
438 
440  void rmdirat(const char* pathname);
441 
447  void rmtree();
448 };
449 
450 
455 {
456 public:
457  using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
458 
459  File(File&&) = default;
460  File(const File&) = delete;
461 
465  File(const std::string& pathname);
466 
468  File(const std::string& pathname, int flags, mode_t mode=0777);
469 
470  File& operator=(const File&) = delete;
471  File& operator=(File&&) = default;
472 
474  void open(int flags, mode_t mode=0777);
475 
480  bool open_ifexists(int flags, mode_t mode=0777);
481 
482  static File mkstemp(const std::string& prefix);
483  static File mkstemp(const char* prefix);
484  static File mkstemp(char* pathname_template);
485 };
486 
488 std::string read_file(const std::string &file);
489 
496 void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
497 
504 void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
505 
515 void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
516 
526 void write_file_atomically(const std::string& file, const void* data, size_t size, mode_t mode=0777);
527 
528 #if 0
529 // Create a temporary directory based on a template.
530 std::string mkdtemp(std::string templ);
531 
534 void mkFilePath(const std::string& file);
535 #endif
536 
542 bool unlink_ifexists(const std::string& file);
543 
549 bool rename_ifexists(const std::string& src, const std::string& dst);
550 
559 bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
560 
561 bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
562 
569 bool makedirs(const std::string& pathname, mode_t=0777);
570 
578 std::string which(const std::string& name);
579 
581 void unlink(const std::string& pathname);
582 
584 void rmdir(const std::string& pathname);
585 
587 void rmtree(const std::string& pathname);
588 
594 bool rmtree_ifexists(const std::string& pathname);
595 
602 void rename(const std::string& src_pathname, const std::string& dst_pathname);
603 
607 void touch(const std::string& pathname, time_t ts);
608 
609 #if 0
610 class Directory
612 {
613 protected:
615  std::string m_path;
616 
617 public:
618  class const_iterator
619  {
621  const Directory* dir;
623  void* dirp;
625  struct dirent* direntbuf;
626 
627  public:
628  // Create an end iterator
629  const_iterator();
630  // Create a begin iterator
631  const_iterator(const Directory& dir);
632  // Cleanup properly
633  ~const_iterator();
634 
636  const_iterator(const const_iterator& i);
637  const_iterator& operator=(const const_iterator& i);
638 
640  const_iterator& operator++();
641 
643  std::string operator*() const;
644 
645  bool operator==(const const_iterator& iter) const;
646  bool operator!=(const const_iterator& iter) const;
647  };
648 
649  Directory(const std::string& path);
650  ~Directory();
651 
653  const std::string& path() const { return m_path; }
654 
656  bool exists() const;
657 
659  const_iterator begin() const;
660 
662  const_iterator end() const;
663 };
664 
665 #endif
666 }
667 }
668 
669 #endif
virtual void throw_error(const char *desc)
Throw an exception based on errno and the given message.
bool ofd_setlkw(struct::flock &, bool retry_on_signal=true)
Open file description locks F_OFD_SETLKW operation.
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...
const std::string & name() const
Return the file pathname.
Definition: sys.h:307
RAII mechanism to save restore file times at the end of some file operations.
Definition: sys.h:272
Wraps a mmapped memory area, unmapping it on destruction.
Definition: sys.h:97
void close()
Close the file descriptor, setting its value to -1.
Common operations on file descriptors.
Definition: sys.h:133
bool ofd_setlk(struct::flock &)
Open file description locks F_OFD_SETLK operation.
File in the file system.
Definition: sys.h:454
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.
virtual void throw_runtime_error(const char *desc)
Throw a runtime_error unrelated from errno.
iterator begin()
Begin iterator on all directory entries.
File descriptor with a name.
Definition: sys.h:288
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:343
File descriptor that gets automatically closed in the object destructor.
Definition: sys.h:314
void open(int flags, mode_t mode=0777)
Wrapper around open(2)
Path open_path(int flags=0) const
Return a Path object for this entry.
Path(const char *pathname, int flags=0)
Open the given pathname with flags | O_PATH.
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.
iterator end()
End iterator on all directory entries.
void rmtree()
Delete the directory pointed to by this Path, with all its contents.
~ManagedNamedFileDescriptor()
The destructor closes the file descriptor, but does not check errors on ::close().
bool fstatat_ifexists(const char *pathname, struct stat &st)
fstatat, but in case of ENOENT returns false instead of throwing
bool ofd_getlk(struct::flock &)
Open file description locks F_OFD_GETLK operation.
bool lstatat_ifexists(const char *pathname, struct stat &st)
lstatat, but in case of ENOENT returns false instead of throwing
bool is_open() const
Check if the file descriptor is open (that is, if it is not -1)
virtual void throw_error(const char *desc)
Throw an exception based on errno and the given message.
Wrap a path on the file system opened with O_PATH.
Definition: sys.h:338
void rmdirat(const char *pathname)
unlinkat with the AT_REMOVEDIR flag set
virtual void throw_runtime_error(const char *desc)
Throw a runtime_error unrelated from errno.