libwreport 3.37
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
22namespace wreport {
23namespace sys {
24
30std::unique_ptr<struct stat> stat(const std::string& pathname);
31
36void stat(const std::string& pathname, struct stat& st);
37
43bool isdir(const std::string& pathname);
44
46bool isblk(const std::string& pathname);
47
49bool ischr(const std::string& pathname);
50
52bool isfifo(const std::string& pathname);
53
55bool islnk(const std::string& pathname);
56
58bool isreg(const std::string& pathname);
59
61bool issock(const std::string& pathname);
62
64time_t timestamp(const std::string& file);
65
67time_t timestamp(const std::string& file, time_t def);
68
70size_t size(const std::string& file);
71
73size_t size(const std::string& file, size_t def);
74
76ino_t inode(const std::string& file);
77
79ino_t inode(const std::string& file, ino_t def);
80
82bool access(const std::string& s, int m);
83
85bool exists(const std::string& s);
86
88std::string getcwd();
89
91void chdir(const std::string& dir);
92
94void chroot(const std::string& dir);
95
97mode_t umask(mode_t mask);
98
100std::string abspath(const std::string& pathname);
101
107class MMap
108{
109 void* addr;
110 size_t length;
111
112public:
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{
145protected:
146 int fd = -1;
147
148public:
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{
299protected:
301 struct ::timespec ts[2];
302
303public:
306};
307
308
309
314{
315protected:
316 std::string pathname;
317
318public:
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{
503public:
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
540class Tempfile : public File
541{
542protected:
543 bool m_unlink_on_exit = true;
544
545public:
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
565class Tempdir : public Path
566{
567protected:
568 bool m_rmtree_on_exit = true;
569
570public:
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
582std::string read_file(const std::string &file);
583
590void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
591
598void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
599
609void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
610
620void 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.
624std::string mkdtemp(std::string templ);
625
628void mkFilePath(const std::string& file);
629#endif
630
636bool unlink_ifexists(const std::string& file);
637
643bool rename_ifexists(const std::string& src, const std::string& dst);
644
653bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
654
655bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
656
663bool makedirs(const std::string& pathname, mode_t=0777);
664
672std::string which(const std::string& name);
673
675void unlink(const std::string& pathname);
676
678void rmdir(const std::string& pathname);
679
681void rmtree(const std::string& pathname);
682
688bool rmtree_ifexists(const std::string& pathname);
689
696void rename(const std::string& src_pathname, const std::string& dst_pathname);
697
701void touch(const std::string& pathname, time_t ts);
702
706void clock_gettime(::clockid_t clk_id, struct ::timespec& ts);
707
711unsigned long long timesec_elapsed(const struct ::timespec& begin, const struct ::timespec& until);
712
716struct 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
738void getrlimit(int resource, struct ::rlimit& rlim);
739
741void setrlimit(int resource, const struct ::rlimit& rlim);
742
745{
746 int resource;
747 struct ::rlimit orig;
748
749 OverrideRlimit(int resource, rlim_t rlim);
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.