libwreport 3.36
sys.h
1#ifndef WREPORT_SYS_H
2#define WREPORT_SYS_H
3
10
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
143class FileDescriptor
144{
145protected:
146 int fd = -1;
147
148public:
149 FileDescriptor();
150 FileDescriptor(FileDescriptor&& o);
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
297class PreserveFileTimes
298{
299protected:
301 struct ::timespec ts[2];
302
303public:
304 PreserveFileTimes(FileDescriptor fd);
305 ~PreserveFileTimes();
306};
307
308
309
313class NamedFileDescriptor : public FileDescriptor
314{
315protected:
316 std::string pathname;
317
318public:
319 NamedFileDescriptor(int fd, const std::string& pathname);
320 NamedFileDescriptor(NamedFileDescriptor&&);
321 NamedFileDescriptor& operator=(NamedFileDescriptor&&);
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
339struct ManagedNamedFileDescriptor : public NamedFileDescriptor
340{
341 using NamedFileDescriptor::NamedFileDescriptor;
342
343 ManagedNamedFileDescriptor(ManagedNamedFileDescriptor&&) = default;
344 ManagedNamedFileDescriptor(const ManagedNamedFileDescriptor&) = delete;
345
354
355 ManagedNamedFileDescriptor& operator=(const ManagedNamedFileDescriptor&) = delete;
356 ManagedNamedFileDescriptor& operator=(ManagedNamedFileDescriptor&&);
357};
358
359
363struct Path : public ManagedNamedFileDescriptor
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
501class File : public ManagedNamedFileDescriptor
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
736
738void getrlimit(int resource, struct ::rlimit& rlim);
739
741void setrlimit(int resource, const struct ::rlimit& rlim);
742
744struct OverrideRlimit
745{
746 int resource;
747 struct ::rlimit orig;
748
749 OverrideRlimit(int resource, rlim_t rlim);
750 ~OverrideRlimit();
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.
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.
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.
void rmtree_on_exit(bool val)
Change the rmtree-on-exit behaviour.
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
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.
~ManagedNamedFileDescriptor()
The destructor closes the file descriptor, but does not check errors on close().
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.
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.