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
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 : public std::iterator<std::input_iterator_tag, struct dirent>
369 {
370 Path* path = nullptr;
371 DIR* dir = nullptr;
372 struct dirent* cur_entry = nullptr;
373
374 // End iterator
375 iterator();
376 // Start iteration on dir
377 iterator(Path& dir);
378 iterator(iterator&) = delete;
379 iterator(iterator&& o)
380 : dir(o.dir), cur_entry(o.cur_entry)
381 {
382 o.dir = nullptr;
383 o.cur_entry = nullptr;
384 }
385 ~iterator();
386 iterator& operator=(iterator&) = delete;
387 iterator& operator=(iterator&&) = delete;
388
389 bool operator==(const iterator& i) const;
390 bool operator!=(const iterator& i) const;
391 struct dirent& operator*() const { return *cur_entry; }
392 struct dirent* operator->() const { return cur_entry; }
393 void operator++();
394
396 bool isdir() const;
397
399 bool isblk() const;
400
402 bool ischr() const;
403
405 bool isfifo() const;
406
408 bool islnk() const;
409
411 bool isreg() const;
412
414 bool issock() const;
415
417 Path open_path(int flags=0) const;
418 };
419
420 using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
421
425 Path(const char* pathname, int flags=0, mode_t mode=0777);
429 Path(const std::string& pathname, int flags=0, mode_t mode=0777);
433 Path(Path& parent, const char* pathname, int flags=0, mode_t mode=0777);
434 Path(const Path&) = delete;
435 Path(Path&&) = default;
436 Path& operator=(const Path&) = delete;
437 Path& operator=(Path&&) = default;
438
440 void open(int flags, mode_t mode=0777);
441
442 DIR* fdopendir();
443
446
449
450 int openat(const char* pathname, int flags, mode_t mode=0777);
451
453 int openat_ifexists(const char* pathname, int flags, mode_t mode=0777);
454
455 bool faccessat(const char* pathname, int mode, int flags=0);
456
457 void fstatat(const char* pathname, struct stat& st);
458
460 bool fstatat_ifexists(const char* pathname, struct stat& st);
461
463 void lstatat(const char* pathname, struct stat& st);
464
466 bool lstatat_ifexists(const char* pathname, struct stat& st);
467
468 void unlinkat(const char* pathname);
469
470 void mkdirat(const char* pathname, mode_t mode=0777);
471
473 void rmdirat(const char* pathname);
474
475 void symlinkat(const char* target, const char* linkpath);
476
477 std::string readlinkat(const char* pathname);
478
484 void rmtree();
485
486 static std::string mkdtemp(const std::string& prefix);
487 static std::string mkdtemp(const char* prefix);
488 static std::string mkdtemp(char* pathname_template);
489};
490
491
496{
497public:
498 using ManagedNamedFileDescriptor::ManagedNamedFileDescriptor;
499
500 File(File&&) = default;
501 File(const File&) = delete;
502
506 File(const std::string& pathname);
507
509 File(const std::string& pathname, int flags, mode_t mode=0777);
510
511 File& operator=(const File&) = delete;
512 File& operator=(File&&) = default;
513
515 void open(int flags, mode_t mode=0777);
516
521 bool open_ifexists(int flags, mode_t mode=0777);
522
523 static File mkstemp(const std::string& prefix);
524 static File mkstemp(const char* prefix);
525 static File mkstemp(char* pathname_template);
526};
527
528
534class Tempfile : public File
535{
536protected:
537 bool m_unlink_on_exit = true;
538
539public:
540 Tempfile();
541 Tempfile(const std::string& prefix);
542 Tempfile(const char* prefix);
543 ~Tempfile();
544
546 void unlink_on_exit(bool val);
547
549 void unlink();
550};
551
552
559class Tempdir : public Path
560{
561protected:
562 bool m_rmtree_on_exit = true;
563
564public:
565 Tempdir();
566 Tempdir(const std::string& prefix);
567 Tempdir(const char* prefix);
568 ~Tempdir();
569
571 void rmtree_on_exit(bool val);
572};
573
574
576std::string read_file(const std::string &file);
577
584void write_file(const std::string& file, const std::string& data, mode_t mode=0777);
585
592void write_file(const std::string& file, const void* data, size_t size, mode_t mode=0777);
593
603void write_file_atomically(const std::string& file, const std::string& data, mode_t mode=0777);
604
614void write_file_atomically(const std::string& file, const void* data, size_t size, mode_t mode=0777);
615
616#if 0
617// Create a temporary directory based on a template.
618std::string mkdtemp(std::string templ);
619
622void mkFilePath(const std::string& file);
623#endif
624
630bool unlink_ifexists(const std::string& file);
631
637bool rename_ifexists(const std::string& src, const std::string& dst);
638
647bool mkdir_ifmissing(const char* pathname, mode_t mode=0777);
648
649bool mkdir_ifmissing(const std::string& pathname, mode_t mode=0777);
650
657bool makedirs(const std::string& pathname, mode_t=0777);
658
666std::string which(const std::string& name);
667
669void unlink(const std::string& pathname);
670
672void rmdir(const std::string& pathname);
673
675void rmtree(const std::string& pathname);
676
682bool rmtree_ifexists(const std::string& pathname);
683
690void rename(const std::string& src_pathname, const std::string& dst_pathname);
691
695void touch(const std::string& pathname, time_t ts);
696
700void clock_gettime(::clockid_t clk_id, struct ::timespec& ts);
701
705unsigned long long timesec_elapsed(const struct ::timespec& begin, const struct ::timespec& until);
706
710struct Clock
711{
712 ::clockid_t clk_id;
713 struct ::timespec ts;
714
718 Clock(::clockid_t clk_id);
719
724 unsigned long long elapsed();
725};
726
732void getrlimit(int resource, struct ::rlimit& rlim);
733
735void setrlimit(int resource, const struct ::rlimit& rlim);
736
739{
740 int resource;
741 struct ::rlimit orig;
742
743 OverrideRlimit(int resource, rlim_t rlim);
745
747 void set(rlim_t rlim);
748};
749
750}
751}
752
753#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:496
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:560
void rmtree_on_exit(bool val)
Change the rmtree-on-exit behaviour.
Open a temporary file.
Definition: sys.h:535
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:711
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:739
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.