jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
file_util.hpp
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef JAU_FILE_UTIL_HPP_
26#define JAU_FILE_UTIL_HPP_
27
28#include <sys/mount.h>
29#include <jau/fraction_type.hpp>
30#include <jau/functional.hpp>
31#include <jau/enum_util.hpp>
32#include <memory>
33#include <string>
34
35extern "C" {
36 // #include <sys/stat.h>
37 // for ::mode_t posix protection bits
38 #include <sys/types.h>
39}
40
41namespace jau::fs {
42
43 using namespace jau::enums;
44
45 /** @defgroup FileUtils File Utilities
46 * File types and functionality.
47 *
48 * @{
49 */
50
51 /**
52 * Return the current working directory or empty on failure.
53 */
54 std::string get_cwd() noexcept;
55
56 /** Change working directory */
57 bool chdir(const std::string& path) noexcept;
58
59 /**
60 * Returns the absolute path of given `relpath` if existing,
61 * otherwise an empty string.
62 * @param relpath a path, might be relative
63 */
64 std::string absolute(const std::string_view& relpath) noexcept;
65
66 /**
67 * Return stripped last component from given path separated by `/`, excluding the trailing separator `/`.
68 *
69 * If no directory separator `/` is contained, return `.`.
70 *
71 * If only the root path `/` is given, return `/`.
72 *
73 * @param path given path
74 * @return leading directory name w/o slash or `.`
75 */
76 std::string dirname(const std::string_view& path) noexcept;
77
78 /**
79 * Return stripped leading directory components from given path separated by `/`.
80 *
81 * If only the root path `/` is given, return `/`.
82 *
83 * @param path given path
84 * @return last non-slash component or `.`
85 */
86 std::string basename(const std::string_view& path) noexcept;
87
88 /**
89 * Return stripped leading directory components from given path separated by `/`,
90 * as well as removing the given suffix, if existing at the end.
91 *
92 * If only the root path `/` is given, return `/`.
93 *
94 * @param path given path
95 * @param suffix suffix at end of path to be removed
96 * @return last non-slash component or `.`
97 */
98 std::string basename(const std::string_view& path, const std::string_view& suffix) noexcept;
99
100 /**
101 * Return stripped leading directory components from given path separated by `/`,
102 * as well as removing the given suffixes, if existing at the end.
103 *
104 * If only the root path `/` is given, return `/`.
105 *
106 * @param path given path
107 * @param suffixes suffixes at end of path to be removed
108 * @return last non-slash component or `.`
109 */
110 std::string basename(const std::string_view& path, const std::vector<std::string_view>& suffixes) noexcept;
111
112 /** Returns true if first character is `/` or - in case of Windows - `\\`. */
113 bool isAbsolute(const std::string_view& path) noexcept;
114
115 /** Returns true if path exists _and_ is accessible. */
116 bool exists(const std::string& path, bool verbose_on_error=false) noexcept;
117
118 /**
119 * Returns located asset directory if found, otherwise an empty string.
120 *
121 * The asset dir is attempted as follows (cwd is current working dir)
122 * - cwd/`resources`/asset_file -> cwd/`resources`
123 * - dirname(exe_path)/../share/"+asset_install_subdir/asset_file -> dirname(exe_path)/../share/"+asset_install_subdir
124 */
125 std::string lookup_asset_dir(const char* exe_path, const char* asset_file, const char* asset_install_subdir) noexcept;
126
127 /**
128 * Representing a directory item split into dirname() and basename().
129 */
130 class dir_item {
131 private:
132 std::string dirname_;
133 std::string basename_;
134 bool empty_;
135
136 struct backed_string_view {
137 std::string backing;
138 std::string_view view;
139
140 backed_string_view() noexcept
141 : backing(), view(backing) {}
142
143 backed_string_view(const std::string& backing_, const std::string_view& view_) noexcept
144 : backing(backing_),
145 view(backing_.size() > 0 ? ((std::string_view)backing).substr(view_.data() - backing_.data(), view_.size()) : view_) {}
146
147 backed_string_view(const std::string_view& view_) noexcept
148 : backing(), view(view_) {}
149
150#if 0
151 backed_string_view(const backed_string_view& o) noexcept
152 : backing(o.backing),
153 view( o.is_backed() ? ((std::string_view)backing).substr(o.view.data() - o.backing.data(), o.view.size()) : o.view)
154 {}
155#else
156 /** Reason: Inefficient, removing the whole purpose of this class reducing std::string duplication. */
157 backed_string_view(const backed_string_view& o) noexcept = delete;
158#endif
159
160#if 0
161 backed_string_view(backed_string_view&& o) noexcept
162 : backing( std::move(o.backing) ),
163 view( std::move(o.view) )
164 {
165 fprintf(stderr, "backed_string_view move_ctor %s\n", to_string(true).c_str());
166 }
167#else
168 /** Reason: clang - for some reason - does not move a std::string, but copies it */
169 backed_string_view(backed_string_view&& o) noexcept = delete;
170#endif
171
172 bool is_backed() const noexcept { return backing.size() > 0; }
173
174 void backup() noexcept {
175 backing = std::string(view);
176 view = backing;
177 }
178 void backup(const std::string& orig) noexcept {
179 backing = orig;
180 view = backing;
181 }
182 void backup(const std::string_view& orig) noexcept {
183 backing = std::string(orig);
184 view = backing;
185 }
186 void backup_and_append(const std::string& orig, const std::string& appendix) noexcept {
187 backing = orig;
188 backing.append(appendix);
189 view = backing;
190 }
191 void backup_and_append(const std::string_view& orig, const std::string& appendix) noexcept {
192 backing = std::string(orig);
193 backing.append(appendix);
194 view = backing;
195 }
196
197 std::string to_string(const bool destailed = false) const noexcept {
198 if (destailed) {
199 return "[backing '" + backing + "', view '" + std::string(view) + "']";
200 }
201 return std::string(view);
202 }
203 };
204 static std::unique_ptr<backed_string_view> reduce(const std::string_view& path_) noexcept;
205
206 dir_item(std::unique_ptr<backed_string_view> cleanpath) noexcept;
207
208 public:
209 /** Empty item w/ `.` set for both, dirname and basename. empty() will return true; */
210 dir_item() noexcept;
211
212 /**
213 * Create a dir_item where path is split into dirname and basename after `.` and `..` has been reduced.
214 *
215 * empty() will return true if given path_ is empty
216 *
217 * @param path_ the raw path
218 */
219 dir_item(const std::string_view& path_) noexcept;
220
221 /**
222 * Create a dir_item with already cleaned dirname and basename
223 * without any further processing nor validation.
224 *
225 * empty() will return true if both, given dirname_ and basename_ is empty
226 *
227 * @param dirname__
228 * @param basename__
229 * @see reduce()
230 * @see jau::fs::dirname()
231 * @see jau::fs::basename()
232 */
233 dir_item(std::string dirname__, std::string basename__) noexcept;
234
235 /** Returns the dirname, shall not be empty and denotes `.` for current working director. */
236 const std::string& dirname() const noexcept { return dirname_; }
237
238 /** Return the basename, shall not be empty nor contain a dirname. */
239 const std::string& basename() const noexcept { return basename_; }
240
241 /**
242 * Returns a full unix path representation combining dirname() and basename().
243 */
244 std::string path() const noexcept;
245
246 /**
247 * Returns true if bot, dirname() and basename() refer to `.`, e.g.. default ctor.
248 */
249 bool empty() const noexcept { return empty_; }
250
251 bool operator==(const dir_item& rhs) const noexcept {
252 return dirname_ == rhs.dirname_ && basename_ == rhs.basename_;
253 }
254
255 bool operator!=(const dir_item& rhs) const noexcept {
256 return !(*this == rhs);
257 }
258
259 /**
260 * Returns a comprehensive string representation of this item
261 */
262 std::string to_string() const noexcept;
263 };
264
265 /**
266 * Generic file type and POSIX protection mode bits as used in file_stats, touch(), mkdir() etc.
267 *
268 * The POSIX protection mode bits reside in the lower 16-bits and are bit-wise POSIX compliant
269 * while the file type bits reside in the upper 16-bits and are platform agnostic.
270 *
271 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
272 *
273 * @see file_stats
274 * @see file_stats::mode()
275 */
276 enum class fmode_t : uint32_t {
277 /** No mode bit set */
278 none = 0,
279
280 /** Protection bit: POSIX S_ISUID */
281 set_uid = 04000,
282 /** Protection bit: POSIX S_ISGID */
283 set_gid = 02000,
284 /** Protection bit: POSIX S_ISVTX */
285 sticky = 01000,
286 /** Protection bit: POSIX S_ISUID | S_ISGID | S_ISVTX */
287 ugs_set = 07000,
288
289 /** Protection bit: POSIX S_IRUSR */
290 read_usr = 00400,
291 /** Protection bit: POSIX S_IWUSR */
292 write_usr = 00200,
293 /** Protection bit: POSIX S_IXUSR */
294 exec_usr = 00100,
295 /** Protection bit: POSIX S_IRWXU */
296 rwx_usr = 00700,
297
298 /** Protection bit: POSIX S_IRGRP */
299 read_grp = 00040,
300 /** Protection bit: POSIX S_IWGRP */
301 write_grp = 00020,
302 /** Protection bit: POSIX S_IXGRP */
303 exec_grp = 00010,
304 /** Protection bit: POSIX S_IRWXG */
305 rwx_grp = 00070,
306
307 /** Protection bit: POSIX S_IROTH */
308 read_oth = 00004,
309 /** Protection bit: POSIX S_IWOTH */
310 write_oth = 00002,
311 /** Protection bit: POSIX S_IXOTH */
312 exec_oth = 00001,
313 /** Protection bit: POSIX S_IRWXO */
314 rwx_oth = 00007,
315
316 /** Protection bit: POSIX S_IRWXU | S_IRWXG | S_IRWXO or rwx_usr | rwx_grp | rwx_oth */
317 rwx_all = 00777,
318
319 /** Default directory protection bit: Safe default: POSIX S_IRWXU | S_IRGRP | S_IXGRP or rwx_usr | read_grp | exec_grp */
321
322 /** Default file protection bit: Safe default: POSIX S_IRUSR | S_IWUSR | S_IRGRP or read_usr | write_usr | read_grp */
324
325 /** 12 bit protection bit mask 07777 for rwx_all | set_uid | set_gid | sticky . */
326 protection_mask = 0b00000000000000000000111111111111,
327
328 /** Type: Entity is a socket, might be in combination with link. */
329 sock = 0b00000000000000000001000000000000,
330 /** Type: Entity is a block device, might be in combination with link. */
331 blk = 0b00000000000000000010000000000000,
332 /** Type: Entity is a character device, might be in combination with link. */
333 chr = 0b00000000000000000100000000000000,
334 /** Type: Entity is a fifo/pipe, might be in combination with link. */
335 fifo = 0b00000000000000001000000000000000,
336 /** Type: Entity is a directory, might be in combination with link. */
337 dir = 0b00000000000000010000000000000000,
338 /** Type: Entity is a file, might be in combination with link. */
339 file = 0b00000000000000100000000000000000,
340 /** Type: Entity is a symbolic link, might be in combination with file or dir, fifo, chr, blk or sock. */
341 link = 0b00000000000001000000000000000000,
342 /** Type: Entity gives no access to user, exclusive bit. */
343 no_access = 0b00100000000000000000000000000000,
344 /** Type: Entity does not exist, exclusive bit. */
345 not_existing = 0b01000000000000000000000000000000,
346 /** Type mask for sock | blk | chr | fifo | dir | file | link | no_access | not_existing. */
347 type_mask = 0b01100000000001111111000000000000,
348 };
350
351 /**
352 * Return the string representation of fmode_t
353 * @param mask the fmode_t to convert
354 * @param show_rwx if true, return verbose POSIX protection bit string representation using `rwx` for user, group and others. Otherwise simply show the octal representation (default)
355 * @return the string representation.
356 */
357 std::string to_string(const fmode_t mask, const bool show_rwx) noexcept;
358
359 /** Returns the POSIX protection bits: rwx_all | set_uid | set_gid | sticky, i.e. fmode_t masked with fmode_t::protection_mask. */
360 constexpr ::mode_t posix_protection_bits(const fmode_t mask) noexcept { return static_cast<::mode_t>(mask & fmode_t::protection_mask); }
361
362 /**
363 * Returns platform dependent named file descriptor of given file descriptor, if supported.
364 *
365 * Implementation returns (`%d` stands for integer):
366 * - `/dev/fd/%d` (GNU/Linux, FreeBSD, ..)
367 *
368 * Following standard POSIX mappings exist
369 * - fd 0, `/dev/fd/0`, `/dev/stdin`
370 * - fd 1, `/dev/fd/1`, `/dev/stdout`
371 * - fd 2, `/dev/fd/2`, `/dev/stderr`
372 * - fd [0-99], `/dev/fd/[0-99]`
373 *
374 * Currently implementation always returns above pattern,
375 * not handling the target OS differences.
376 *
377 * @param fd file descriptor.
378 * @return the named file descriptor or an empty string if fd < 0 or not supported by OS.
379 *
380 * @see jau::fs::from_named_fd()
381 * @see jau::fs::file_stats:has_fd()
382 */
383 std::string to_named_fd(const int fd) noexcept;
384
385 /**
386 * Returns the file descriptor from the given named file descriptor.
387 *
388 * Detected named file descriptors are (`%d` stands for integer)
389 * - `/dev/fd/%d` (GNU/Linux, FreeBSD, ..)
390 * - `/proc/self/fd/%d` (GNU/Linux)
391 *
392 * @param named_fd the named file descriptor
393 * @return file descriptor or -1 if invalid or not supported by OS.
394 *
395 * @see jau::fs::to_named_fd()
396 * @see jau::fs::file_stats:has_fd()
397 */
398 int from_named_fd(const std::string& named_fd) noexcept;
399
400 /**
401 * Platform agnostic representation of POSIX ::lstat() and ::stat()
402 * for a given pathname.
403 *
404 * Implementation follows the symbolic link, i.e. first opens
405 * the given pathname with ::lstat() and if identifying as a symbolic link
406 * opens it via ::stat() to retrieve the actual properties like size, time and ownership.
407 *
408 * Implementation supports named file descriptor, see is_fd().
409 *
410 * On `GNU/Linux` implementation uses ::statx().
411 */
413 public:
414 /**
415 * Field identifier which bit-mask indicates field_t fields
416 */
417 enum class field_t : uint32_t {
418 /** No mode bit set */
419 none = 0,
420 /** File type mode bits */
421 type = 0b0000000000000001,
422 /** POSIX file protection mode bits */
423 mode = 0b0000000000000010,
424 nlink = 0b0000000000000100,
425 uid = 0b0000000000001000,
426 gid = 0b0000000000010000,
427 atime = 0b0000000000100000,
428 mtime = 0b0000000001000000,
429 ctime = 0b0000000010000000,
430 ino = 0b0000000100000000,
431 size = 0b0000001000000000,
432 blocks = 0b0000010000000000,
433 btime = 0b0000100000000000,
434 fd = 0b0001000000000000
435 };
436
437 typedef uint32_t uid_t;
438 typedef uint32_t gid_t;
439
440 private:
441 field_t has_fields_;
442
443 dir_item item_;
444
445 std::shared_ptr<std::string> link_target_path_; // stored link-target path this symbolic-link points to if is_link(), otherwise nullptr.
446 std::shared_ptr<file_stats> link_target_; // link-target this symbolic-link points to if is_link(), otherwise nullptr.
447
448 fmode_t mode_;
449 int fd_;
450 uid_t uid_;
451 gid_t gid_;
452 uint64_t size_;
453 fraction_timespec btime_; // Birth or creation time
454 fraction_timespec atime_; // Last access
455 fraction_timespec ctime_; // Last meta-status change
456 fraction_timespec mtime_; // Last modification
457
458 int errno_res_;
459
460 /** Private class only for private make_shared(). */
461 class ctor_cookie {
462 friend file_stats;
463 uint16_t rec_level;
464 ctor_cookie(const uint16_t recursion_level_) { rec_level = recursion_level_; }
465 };
466
467 public:
468 /** Instantiate an empty file_stats with fmode_t::not_existing set. */
469 file_stats() noexcept;
470
471 /** Private ctor for private make_shared<file_stats>() intended for friends. */
472 file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, const bool dirfd_is_item_dirname) noexcept;
473
474 /**
475 * Instantiates a file_stats for the given `path`.
476 *
477 * The dir_item will be constructed without parent_dir
478 *
479 * @param path the path to produce stats for
480 */
481 file_stats(const std::string& path) noexcept;
482
483 /**
484 * Instantiates a file_stats for the given `path`.
485 *
486 * The dir_item will be constructed without parent_dir
487 *
488 * @param dirfd file descriptor of given dir_item item's directory, dir_item::dirname(), or AT_FDCWD for the current working directory of the calling process
489 * @param path the path to produce stats for
490 */
491 file_stats(const int dirfd, const std::string& path) noexcept;
492
493 /**
494 * Instantiates a file_stats for the given dir_item.
495 *
496 * @param item the dir_item to produce stats for
497 */
498 file_stats(const dir_item& item) noexcept;
499
500 /**
501 * Instantiates a file_stats for the given dir_item.
502 *
503 * @param dirfd file descriptor of given dir_item item's directory, dir_item::dirname(), or AT_FDCWD for the current working directory of the calling process
504 * @param item the dir_item to produce stats for
505 * @param dirfd_is_item_dirname if true, dir_item::basename() is relative to dirfd (default), otherwise full dir_item::path() is relative to dirfd.
506 */
507 file_stats(const int dirfd, const dir_item& item, const bool dirfd_is_item_dirname = true) noexcept;
508
509 /**
510 * Instantiates a file_stats for the given `fd` file descriptor.
511 *
512 * @param fd file descriptor of an opened file
513 */
514 file_stats(const int fd) noexcept;
515
516 /**
517 * Returns the dir_item.
518 *
519 * In case this instance is created by following a symbolic link instance,
520 * it represents the resolved path relative to the used symbolic link's dirname.
521 *
522 * @see is_link()
523 * @see path()
524 */
525 const dir_item& item() const noexcept { return item_; }
526
527 /**
528 * Returns the unix path representation.
529 *
530 * In case this instance is created by following a symbolic link instance,
531 * it represents the resolved path relative to the used symbolic link's dirname.
532 *
533 * @see is_link()
534 * @see item()
535 */
536 std::string path() const noexcept { return item_.path(); }
537
538 /**
539 * Returns the stored link-target path this symbolic-link points to if instance is a symbolic-link, otherwise nullptr.
540 *
541 * @see is_link()
542 * @see link_target()
543 * @see final_target()
544 */
545 const std::shared_ptr<std::string>& link_target_path() const noexcept { return link_target_path_; }
546
547 /**
548 * Returns the link-target this symbolic-link points to if instance is a symbolic-link, otherwise nullptr.
549 *
550 * nullptr is also returned for an erroneous symbolic-links, i.e. non-existing link-targets or recursive loop-errors.
551 *
552 * @see is_link()
553 * @see link_target_path()
554 * @see final_target()
555 */
556 const std::shared_ptr<file_stats>& link_target() const noexcept { return link_target_; }
557
558 /**
559 * Returns the final target element, either a pointer to this instance if not a symbolic-link
560 * or the final link-target a symbolic-link (chain) points to.
561 *
562 * @param link_count optional size_t pointer to store the number of symbolic links leading to the final target, excluding the final instance. 0 indicates no symbolic-link;
563 *
564 * @see is_link()
565 * @see link_target_path()
566 * @see link_target()
567 */
568 const file_stats* final_target(size_t* link_count = nullptr) const noexcept;
569
570 /** Returns true if the given field_t fields were retrieved, otherwise false. */
571 bool has(const field_t fields) const noexcept;
572
573 /** Returns the retrieved field_t fields. */
574 constexpr field_t fields() const noexcept { return has_fields_; }
575
576 /** Returns the fmode_t, file type and mode. */
577 fmode_t mode() const noexcept { return mode_; }
578
579 /** Returns the POSIX protection bit portion of fmode_t, i.e. mode() & fmode_t::protection_mask. */
580 fmode_t prot_mode() const noexcept { return mode_ & fmode_t::protection_mask; }
581
582 /** Returns the type bit portion of fmode_t, i.e. mode() & fmode_t::type_mask. */
583 fmode_t type_mode() const noexcept { return mode_ & fmode_t::type_mask; }
584
585 /**
586 * Returns the file descriptor if has_fd(), otherwise -1 for no file descriptor.
587 *
588 * @see has_fd()
589 */
590 int fd() const noexcept { return fd_; }
591
592 /** Returns the user id, owning the element. */
593 uid_t uid() const noexcept { return uid_; }
594
595 /** Returns the group id, owning the element. */
596 gid_t gid() const noexcept { return gid_; }
597
598 /**
599 * Returns the size in bytes of this element if is_file(), otherwise zero.
600 *
601 * If the element also is_link(), the linked target size is returned.
602 */
603 uint64_t size() const noexcept { return size_; }
604
605 /** Returns the birth time of this element since Unix Epoch, i.e. its creation time. */
606 const fraction_timespec& btime() const noexcept { return btime_; }
607 /** Returns the last access time of this element since Unix Epoch. */
608 const fraction_timespec& atime() const noexcept { return atime_; }
609 /** Returns the last status change time of this element since Unix Epoch. */
610 const fraction_timespec& ctime() const noexcept { return ctime_; }
611 /** Returns the last modification time of this element since Unix Epoch. */
612 const fraction_timespec& mtime() const noexcept { return mtime_; }
613
614 /** Returns the `errno` value occurred to produce this instance, or zero for no error. */
615 constexpr int errno_res() const noexcept { return errno_res_; }
616
617 /** Returns true if no error occurred */
618 constexpr bool ok() const noexcept { return 0 == errno_res_; }
619
620 /**
621 * Returns true if entity has a file descriptor.
622 *
623 * @see fd()
624 * @see jau::fs::from_named_fd()
625 * @see jau::fs::to_named_fd()
626 */
627 constexpr bool has_fd() const noexcept { return 0 <= fd_; }
628
629 /** Returns true if entity is a socket, might be in combination with is_link(). */
630 constexpr bool is_socket() const noexcept { return is_set(mode_, fmode_t::sock); }
631
632 /** Returns true if entity is a block device, might be in combination with is_link(). */
633 constexpr bool is_block() const noexcept { return is_set(mode_, fmode_t::blk); }
634
635 /** Returns true if entity is a character device, might be in combination with is_link(). */
636 constexpr bool is_char() const noexcept { return is_set(mode_, fmode_t::chr); }
637
638 /** Returns true if entity is a fifo/pipe, might be in combination with is_link(). */
639 constexpr bool is_fifo() const noexcept { return is_set(mode_, fmode_t::fifo); }
640
641 /** Returns true if entity is a directory, might be in combination with is_link(). */
642 constexpr bool is_dir() const noexcept { return is_set(mode_, fmode_t::dir); }
643
644 /** Returns true if entity is a file, might be in combination with is_link(). */
645 constexpr bool is_file() const noexcept { return is_set(mode_, fmode_t::file); }
646
647 /** Returns true if entity is a symbolic link, might be in combination with is_file(), is_dir(), is_fifo(), is_char(), is_block(), is_socket(). */
648 constexpr bool is_link() const noexcept { return is_set(mode_, fmode_t::link); }
649
650 /** Returns true if entity gives no access to user, exclusive bit. */
651 constexpr bool has_access() const noexcept { return !is_set(mode_, fmode_t::no_access); }
652
653 /** Returns true if entity does not exist, exclusive bit. */
654 constexpr bool exists() const noexcept { return !is_set(mode_, fmode_t::not_existing); }
655
656 bool operator==(const file_stats& rhs) const noexcept;
657
658 bool operator!=(const file_stats& rhs) const noexcept {
659 return !(*this == rhs);
660 }
661
662 /**
663 * Returns a comprehensive string representation of this element
664 */
665 std::string to_string() const noexcept;
666 };
667 JAU_MAKE_BITFIELD_ENUM_STRING2(file_stats::field_t, field_t, type, mode, nlink, uid, gid, atime, mtime, ctime, ino, size, blocks, btime);
668
669 /**
670 * Create directory
671 * @param path full path to new directory
672 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_dir_prot
673 * @param verbose defaults to false
674 * @return true if successful, otherwise false
675 */
676 bool mkdir(const std::string& path, const fmode_t mode = jau::fs::fmode_t::def_dir_prot, const bool verbose = false) noexcept;
677
678 /**
679 * Touch the file with given atime and mtime and create file if not existing yet.
680 * @param path full path to file
681 * @param atime new access time
682 * @param mtime new modification time
683 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_file_prot
684 * @return true if successful, otherwise false
685 */
686 bool touch(const std::string& path, const jau::fraction_timespec& atime, const jau::fraction_timespec& mtime,
687 const fmode_t mode = jau::fs::fmode_t::def_file_prot) noexcept;
688
689 /**
690 * Touch the file with current time and create file if not existing yet.
691 * @param path full path to file
692 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_file_prot
693 * @return true if successful, otherwise false
694 */
695 bool touch(const std::string& path, const fmode_t mode = jau::fs::fmode_t::def_file_prot) noexcept;
696
697 /**
698 * `void consume_dir_item(const dir_item& item)`
699 */
700 typedef jau::function<void(const dir_item&)> consume_dir_item;
701
702 /**
703 * Returns a list of directory elements excluding `.` and `..` for the given path, non recursive.
704 *
705 * The custom consume_dir_item `digest` may also be used to filter the element, besides storing it.
706 *
707 * @param path path to directory
708 * @param digest consume_dir_item function to receive each directory item, e.g. `void consume_dir_item(const dir_item& item)`
709 * @return true if given path exists, is directory and is readable, otherwise false
710 */
711 bool get_dir_content(const std::string& path, const consume_dir_item& digest) noexcept;
712
713 /**
714 * Returns a list of directory elements excluding `.` and `..` for the given path, non recursive.
715 *
716 * The custom consume_dir_item `digest` may also be used to filter the element, besides storing it.
717 *
718 * @param dirfd file descriptor to given `path` left untouched as a copy is being used to retrieve the directory content.
719 * @param path path to directory
720 * @param digest consume_dir_item function to receive each directory item, e.g. `void consume_dir_item(const dir_item& item)`
721 * @return true if given path exists, is directory and is readable, otherwise false
722 */
723 bool get_dir_content(const int dirfd, const std::string& path, const consume_dir_item& digest) noexcept;
724
725 /**
726 * Filesystem traverse event used to call path_visitor for path elements from visit().
727 *
728 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
729 *
730 * @see path_visitor
731 * @see visit()
732 */
733 enum class traverse_event : uint16_t {
734 /** No value, neither file, symlink nor dir_entry or dir_exit. Implying an error state in file_stat, e.g. !file_stats::has_access(). */
735 none = 0,
736
737 /**
738 * Visiting a symbolic-link, either to a file or a non-existing entity. Not followed symbolic-links to a directory is expressed via dir_symlink.
739 *
740 * In case of a symbolic-link to an existing file, file is also set, i.e. file_symlink.
741 */
742 symlink = 1 << 0,
743
744 /** Visiting a file, may be in conjunction with symlink, i.e. file_symlink. */
745 file = 1 << 1,
746
747 /** Visiting a symlink to a file, i.e. symlink | file */
749
750 /**
751 * Visiting a symbolic-link to a directory which is not followed, i.e. traverse_options::follow_symlinks not set.
752 */
753 dir_symlink = 1 << 2,
754
755 /**
756 * Visiting a directory on entry, see traverse_options::dir_check_entry.
757 *
758 * This allows the path_visitor to deny traversal into the directory by returning false,
759 * otherwise continuing traversal.
760 */
762
763 /**
764 * Visiting a directory on entry, see traverse_options::dir_entry.
765 *
766 * If a directory is visited non-recursive, i.e. traverse_options::recursive not set,
767 * dir_entry and dir_exit are set, see dir_non_recursive.
768 *
769 * If a directory is a symbolic link which is not followed, i.e. traverse_options::follow_symlinks not set,
770 * dir_symlink is used instead.
771 */
772 dir_entry = 1 << 8,
773
774 /**
775 * Visiting a directory on exit, see traverse_options::dir_exit.
776 *
777 * If a directory is visited non-recursive, i.e. traverse_options::recursive not set,
778 * dir_entry and dir_exit are set, see dir_non_recursive.
779 *
780 * If a directory is a symbolic link which is not followed, i.e. traverse_options::follow_symlinks not set,
781 * dir_symlink is used instead.
782 */
783 dir_exit = 1 << 9,
784
785 /**
786 * Visiting a directory non-recursive, i.e. traverse_options::recursive not set.
787 *
788 * Value is a bit-mask of dir_entry | dir_exit
789 */
791 };
793
794 /**
795 * path_visitor jau::FunctionDef definition
796 * - `bool visitor(traverse_event tevt, const file_stats& item_stats, size_t depth)`
797 *
798 * Depth being the recursive directory depth starting with 1 for the initial directory.
799 *
800 * Returning `false` stops traversal in general but traverse_options::dir_check_entry
801 * will only skip traversing the denied directory.
802 */
803 typedef jau::function<bool(traverse_event, const file_stats&, size_t)> path_visitor;
804
805 /**
806 * Filesystem traverse options used to visit() path elements.
807 *
808 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
809 *
810 * @see visit()
811 * @see remove()
812 */
813 enum class traverse_options : uint16_t {
814 /** No option set */
815 none = 0,
816
817 /** Traverse through directories, i.e. perform visit, copy, remove etc actions recursively throughout the directory structure. */
818 recursive = 1U << 0,
819
820 /** Traverse through symbolic linked directories if traverse_options::recursive is set, i.e. directories with property fmode_t::link set. */
822
823 /** Traverse through elements in lexicographical order. This might be required when computing an order dependent outcome like a hash value. */
825
826 /** Call path_visitor at directory entry, allowing path_visitor to skip traversal of this directory if returning false. */
828
829 /** Call path_visitor at directory entry. Both, dir_entry and dir_exit can be set, only one or none. */
830 dir_entry = 1U << 8,
831
832 /** Call path_visitor at directory exit. Both, dir_entry and dir_exit can be set, only one or none. */
833 dir_exit = 1U << 9,
834
835 /** Enable verbosity mode, potentially used by a path_visitor implementation like remove(). */
836 verbose = 1U << 15
837 };
839
840 /**
841 * Visit element(s) of a given path, see traverse_options for detailed settings.
842 *
843 * All elements of type fmode_t::file, fmode_t::dir and fmode_t::no_access or fmode_t::not_existing
844 * will be visited by the given path_visitor `visitor`.
845 *
846 * Depth passed to path_visitor is the recursive directory depth and starts with 1 for the initial directory.
847 *
848 * path_visitor returning `false` stops traversal in general but traverse_options::dir_check_entry
849 * will only skip traversing the denied directory.
850 *
851 * @param path the starting path
852 * @param topts given traverse_options for this operation
853 * @param visitor path_visitor function `bool visitor(const file_stats& item_stats, size_t depth)`.
854 * @param dirfds optional empty `dirfd` stack pointer defaults to nullptr.
855 * If user provided, exposes the used `dirfd` stack, which last entry represents the currently visited directory.
856 * The `dirfd` stack starts and ends empty, i.e. all directory file descriptor are closed.
857 * In case of recursive directory traversion, the initial dir_entry visit starts with depth 1 and 2 fds, its parent and current directory.
858 * @return true if successful including no path_visitor stopped traversal by returning `false` excluding traverse_options::dir_check_entry.
859 */
860 bool visit(const std::string& path, const traverse_options topts, const path_visitor& visitor, std::vector<int>* dirfds = nullptr) noexcept;
861
862 /**
863 * Visit element(s) of a given path, see traverse_options for detailed settings.
864 *
865 * All elements of type fmode_t::file, fmode_t::dir and fmode_t::no_access or fmode_t::not_existing
866 * will be visited by the given path_visitor `visitor`.
867 *
868 * Depth passed to path_visitor is the recursive directory depth and starts with 1 for the initial directory.
869 *
870 * path_visitor returning `false` stops traversal in general but traverse_options::dir_check_entry
871 * will only skip traversing the denied directory.
872 *
873 * @param item_stats pre-fetched file_stats for a given dir_item, used for efficiency
874 * @param topts given traverse_options for this operation
875 * @param visitor path_visitor function `bool visitor(const file_stats& item_stats, size_t depth)`.
876 * @param dirfds optional empty `dirfd` stack pointer defaults to nullptr.
877 * If user provided, exposes the used `dirfd` stack, which last entry represents the currently visited directory.
878 * The `dirfd` stack starts and ends empty, i.e. all directory file descriptor are closed.
879 * In case of recursive directory traversion, the initial dir_entry visit starts with depth 1 and 2 fds, its parent and current directory.
880 * @return true if successful including no path_visitor stopped traversal by returning `false` excluding traverse_options::dir_check_entry.
881 */
882 bool visit(const file_stats& item_stats, const traverse_options topts, const path_visitor& visitor, std::vector<int>* dirfds = nullptr) noexcept;
883
884 /**
885 * Remove the given path. If path represents a director, `recursive` must be set to true.
886 *
887 * The given traverse_options `options` are handled as follows:
888 * - traverse_options::parent_dir_last will be added by implementation to operate correct
889 * - traverse_options::recursive shall shall be set by caller to remove directories
890 * - traverse_options::follow_symlinks shall be set by caller to remove symbolic linked directories recursively, which is kind of dangerous.
891 * If not set, only the symbolic link will be removed (default)
892 *
893 * Implementation is most data-race-free (DRF), utilizes following safeguards
894 * - utilizing parent directory file descriptor and `openat()` and `unlinkat()` operations against concurrent mutation
895 *
896 * @param path path to remove
897 * @param topts given traverse_options for this operation, defaults to traverse_options::none
898 * @return true only if the file or the directory with content has been deleted, otherwise false
899 */
900 bool remove(const std::string& path, const traverse_options topts = traverse_options::none) noexcept;
901
902 /**
903 * Compare the bytes of both files, denoted by source1 and source2.
904 *
905 * @param source1 first source file to compare
906 * @param source2 second source file to compare
907 * @param verbose defaults to false
908 * @return true if both elements are files and their bytes are equal, otherwise false.
909 */
910 bool compare(const file_stats& source1, const file_stats& source2, const bool verbose = false) noexcept;
911
912 /**
913 * Compare the bytes of both files, denoted by source1 and source2.
914 *
915 * @param source1 first source file to compare
916 * @param source2 second source file to compare
917 * @param verbose defaults to false
918 * @return true if both elements are files and their bytes are equal, otherwise false.
919 */
920 bool compare(const std::string& source1, const std::string& source2, const bool verbose = false) noexcept;
921
922 /**
923 * Filesystem copy options used to copy() path elements.
924 *
925 * By default, the fmode_t POSIX protection mode bits are preserved
926 * while using the caller's uid and gid as well as current timestamps. <br />
927 * Use copy_options::preserve_all to preserve uid and gid if allowed from the caller and access- and modification-timestamps.
928 *
929 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
930 *
931 * @see copy()
932 */
933 enum class copy_options : uint16_t {
934 /** No option set */
935 none = 0,
936
937 /** Traverse through directories, i.e. perform visit, copy, remove etc actions recursively throughout the directory structure. */
938 recursive = 1 << 0,
939
940 /** Copy referenced symbolic linked files or directories instead of just the symbolic link with property fmode_t::link set. */
942
943 /**
944 * Copy source dir content into an already existing destination directory as if destination directory did not exist.
945 *
946 * Otherwise, if destination directory already exist, the source directory will be copied below the destination directory.
947 */
949
950 /**
951 * Ignore errors from erroneous symlinks, e.g. non-existing link-targets, recursive loop-errors.or unsupported symmlinks on target filesystem.
952 *
953 * This flag is required to
954 * - copy erroneous non-existing symlinks if using follow_symlinks
955 * - copy erroneous recursive loop-error symlinks if using follow_symlinks
956 * - ignore symlinks if not supported by target filesystem if not using follow_symlinks
957 */
959
960 /** Overwrite existing destination files. */
961 overwrite = 1 << 9,
962
963 /** Preserve uid and gid if allowed and access- and modification-timestamps, i.e. producing a most exact meta-data copy. */
964 preserve_all = 1 << 10,
965
966 /** Ensure data and meta-data file synchronization is performed via ::fsync() after asynchronous copy operations of a file's content. */
967 sync = 1 << 11,
968
969 /** Enable verbosity mode, show error messages on stderr. */
970 verbose = 1 << 15
971 };
973
974 /**
975 * Copy the given source_path to dest_path using copy_options.
976 *
977 * The behavior is similar like POSIX `cp` commandline tooling.
978 *
979 * The following behavior is being followed regarding dest_path:
980 * - If source_path is a directory and copy_options::recursive set
981 * - If dest_path doesn't exist, source_path dir content is copied into the newly created dest_path.
982 * - If dest_path exists as a directory, source_path dir will be copied below the dest_path directory
983 * _if_ copy_options::into_existing_dir is not set. Otherwise its content is copied into the existing dest_path.
984 * - Everything else is considered an error
985 * - If source_path is a file
986 * - If dest_path doesn't exist, source_path file is copied to dest_path as a file.
987 * - If dest_path exists as a directory, source_path file will be copied below the dest_path directory.
988 * - If dest_path exists as a file, copy_options::overwrite must be set to have it overwritten by the source_path file
989 * - Everything else is considered an error
990 *
991 * Implementation either uses ::sendfile() if running under `GNU/Linux`,
992 * otherwise POSIX ::read() and ::write().
993 *
994 * Implementation is most data-race-free (DRF), utilizes following safeguards on recursive directory copy
995 * - utilizing parent directory file descriptor and `openat()` operations against concurrent mutation
996 * - for each entered *directory*
997 * - new destination directory is create with '.<random_number>' and user-rwx permissions only
998 * - its file descriptor is being opened
999 * - its user-read permission is dropped, remains user-wx permissions only
1000 * - its renamed to destination path
1001 * - all copy operations are performed inside
1002 * - at exit, its permissions are restored, etc.
1003 *
1004 * See copy_options for details.
1005 *
1006 * @param source_path
1007 * @param dest_path
1008 * @param copts
1009 * @return true if successful, otherwise false
1010 */
1011 bool copy(const std::string& source_path, const std::string& dest_path, const copy_options copts = copy_options::none) noexcept;
1012
1013 /**
1014 * Rename oldpath to newpath using POSIX `::rename()`, with the following combinations
1015 * - oldpath and newpath refer to the same file, a successful no-operation.
1016 * - oldpath file
1017 * - newpath not-existing file
1018 * - newpath existing file to be atomically replaced
1019 * - oldpath directory
1020 * - newpath not-existing directory
1021 * - newpath existing empty directory
1022 * - oldpath symlink will be renamed
1023 * - newpath symlink will be overwritten
1024 *
1025 * @param oldpath previous path
1026 * @param newpath new path
1027 * @return true only if the rename operation was successful, otherwise false
1028 */
1029 bool rename(const std::string& oldpath, const std::string& newpath) noexcept;
1030
1031 /**
1032 * Synchronizes filesystems, i.e. all pending modifications to filesystem metadata and cached file data will be written to the underlying filesystems.
1033 */
1034 void sync() noexcept;
1035
1036 struct mount_ctx {
1038 std::string target;
1040
1041 mount_ctx(std::string target_, const int loop_device_id_)
1042 : mounted(true), target(std::move(target_)), loop_device_id(loop_device_id_) {}
1043
1045 : mounted(false), target(), loop_device_id(-1) {}
1046 };
1047
1048 /**
1049 * Generic flag bit values for mount() `flags`.
1050 *
1051 * See mount(2) for a detailed description.
1052 */
1053 typedef uint64_t mountflags_t;
1054
1055 /**
1056 * Flag bit values for mount() `flags` under GNU/Linux.
1057 *
1058 * See mount(2) for a detailed description.
1059 */
1061 none = 0,
1069 dirsync = 128,
1070 noatime = 1024,
1072 bind = 4096,
1073 move = 8192,
1074 rec = 16384,
1075 silent = 32768,
1076 posixacl = 1 << 16,
1077 unbindable = 1 << 17,
1078 private_ = 1 << 18,
1079 slave = 1 << 19,
1080 shared = 1 << 20,
1081 relatime = 1 << 21,
1082 kernmount = 1 << 22,
1083 i_version = 1 << 23,
1084 strictatime = 1 << 24,
1085 lazytime = 1 << 25,
1086 active = 1 << 30,
1087 nouser = 1UL << 31
1088 };
1092
1093 /**
1094 * Attach the filesystem image named in `image_path` to `target`
1095 * using an intermediate platform specific filesystem image loop-device.
1096 *
1097 * This method either requires root permissions <br />
1098 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1099 *
1100 * Unmounting shall be done via umount() with mount_ctx argument to ensure
1101 * all intermediate resources are released.
1102 *
1103 * @param image_path path of image source file
1104 * @param target directory where `image_path` filesystem shall be attached to
1105 * @param fs_type type of filesystem, e.g. `squashfs`, `tmpfs`, `iso9660`, etc.
1106 * @param flags filesystem agnostic mount flags, see mountflags_linux.
1107 * @param fs_options comma separated options for the filesystem `fs_type`, see mount(8) for available options for the used filesystem.
1108 * @return mount_ctx structure containing mounted status etc
1109 *
1110 * @see mountflags_t
1111 * @see mountflags_linux
1112 * @see mount()
1113 * @see umount()
1114 */
1115 mount_ctx mount_image(const std::string& image_path, const std::string& target, const std::string& fs_type,
1116 const mountflags_t flags, const std::string& fs_options = "");
1117
1118 /**
1119 * Attach the filesystem named in `source` to `target`
1120 * using the given filesystem source directly.
1121 *
1122 * This method either requires root permissions <br />
1123 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1124 *
1125 * @param source filesystem path for device, directory, file or dummy-string which shall be attached
1126 * @param target directory where `source` filesystem shall be attached to
1127 * @param fs_type type of filesystem, e.g. `squashfs`, `tmpfs`, `iso9660`, etc.
1128 * @param flags filesystem agnostic mount flags, see mountflags_linux.
1129 * @param fs_options comma separated options for the filesystem `fs_type`, see mount(8) for available options for the used filesystem.
1130 * @return mount_ctx structure containing mounted status etc
1131 *
1132 * @see mountflags_t
1133 * @see mountflags_linux
1134 * @see mount_image()
1135 * @see umount()
1136 */
1137 mount_ctx mount(const std::string& source, const std::string& target, const std::string& fs_type,
1138 const mountflags_t flags, const std::string& fs_options = "");
1139
1140 /**
1141 * Generic flag bit values for umount() `flags`.
1142 *
1143 * See umount(2) for a detailed description.
1144 */
1145 typedef int umountflags_t;
1146
1147 /**
1148 * Flag bit values for umount() `flags` under GNU/Linux.
1149 *
1150 * See umount(2) for a detailed description.
1151 */
1159
1160 /**
1161 * Detach the given mount_ctx `context`
1162 *
1163 * This method either requires root permissions <br />
1164 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1165 *
1166 * @param context mount_ctx previously attached via mount_image() or mount()
1167 * @param flags optional umount options, if supported by the system. See umount_options_linux.
1168 * @return true if successful, otherwise false
1169 *
1170 * @see umountflags_t
1171 * @see umountflags_linux
1172 * @see mount()
1173 * @see mount_image()
1174 */
1175 bool umount(const mount_ctx& context, const umountflags_t flags);
1176
1177 /**
1178 * Detach the topmost filesystem mounted on `target`
1179 * optionally using given `umountflags` options if supported.
1180 *
1181 * This method either requires root permissions <br />
1182 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1183 *
1184 * @param target directory of previously attached filesystem
1185 * @param flags optional umount options, if supported by the system. See umount_options_linux.
1186 * @return true if successful, otherwise false
1187 *
1188 * @see umountflags_t
1189 * @see umountflags_linux
1190 * @see mount()
1191 * @see mount_image()
1192 */
1193 bool umount(const std::string& target, const umountflags_t flags);
1194
1195 /**@}*/
1196
1197} // namespace jau::fs
1198
1199#endif /* JAU_FILE_UTIL_HPP_ */
Representing a directory item split into dirname() and basename().
std::string path() const noexcept
Returns a full unix path representation combining dirname() and basename().
const std::string & basename() const noexcept
Return the basename, shall not be empty nor contain a dirname.
bool operator!=(const dir_item &rhs) const noexcept
bool empty() const noexcept
Returns true if bot, dirname() and basename() refer to .
std::string to_string() const noexcept
Returns a comprehensive string representation of this item.
dir_item() noexcept
Empty item w/ .
bool operator==(const dir_item &rhs) const noexcept
const std::string & dirname() const noexcept
Returns the dirname, shall not be empty and denotes .
Platform agnostic representation of POSIX ::lstat() and ::stat() for a given pathname.
constexpr bool is_char() const noexcept
Returns true if entity is a character device, might be in combination with is_link().
int fd() const noexcept
Returns the file descriptor if has_fd(), otherwise -1 for no file descriptor.
constexpr bool exists() const noexcept
Returns true if entity does not exist, exclusive bit.
fmode_t type_mode() const noexcept
Returns the type bit portion of fmode_t, i.e.
constexpr bool has_fd() const noexcept
Returns true if entity has a file descriptor.
const fraction_timespec & mtime() const noexcept
Returns the last modification time of this element since Unix Epoch.
constexpr bool is_fifo() const noexcept
Returns true if entity is a fifo/pipe, might be in combination with is_link().
constexpr bool is_link() const noexcept
Returns true if entity is a symbolic link, might be in combination with is_file(),...
constexpr bool is_file() const noexcept
Returns true if entity is a file, might be in combination with is_link().
const fraction_timespec & ctime() const noexcept
Returns the last status change time of this element since Unix Epoch.
gid_t gid() const noexcept
Returns the group id, owning the element.
constexpr bool is_dir() const noexcept
Returns true if entity is a directory, might be in combination with is_link().
const dir_item & item() const noexcept
Returns the dir_item.
field_t
Field identifier which bit-mask indicates field_t fields.
@ type
File type mode bits.
uint64_t size() const noexcept
Returns the size in bytes of this element if is_file(), otherwise zero.
constexpr bool is_socket() const noexcept
Returns true if entity is a socket, might be in combination with is_link().
const fraction_timespec & btime() const noexcept
Returns the birth time of this element since Unix Epoch, i.e.
constexpr bool has_access() const noexcept
Returns true if entity gives no access to user, exclusive bit.
constexpr bool ok() const noexcept
Returns true if no error occurred.
file_stats() noexcept
Instantiate an empty file_stats with fmode_t::not_existing set.
const std::shared_ptr< std::string > & link_target_path() const noexcept
Returns the stored link-target path this symbolic-link points to if instance is a symbolic-link,...
fmode_t mode() const noexcept
Returns the fmode_t, file type and mode.
const std::shared_ptr< file_stats > & link_target() const noexcept
Returns the link-target this symbolic-link points to if instance is a symbolic-link,...
uid_t uid() const noexcept
Returns the user id, owning the element.
constexpr int errno_res() const noexcept
Returns the errno value occurred to produce this instance, or zero for no error.
bool operator!=(const file_stats &rhs) const noexcept
fmode_t prot_mode() const noexcept
Returns the POSIX protection bit portion of fmode_t, i.e.
const fraction_timespec & atime() const noexcept
Returns the last access time of this element since Unix Epoch.
constexpr field_t fields() const noexcept
Returns the retrieved field_t fields.
constexpr bool is_block() const noexcept
Returns true if entity is a block device, might be in combination with is_link().
std::string path() const noexcept
Returns the unix path representation.
Class template jau::function is a general-purpose static-polymorphic function wrapper.
#define JAU_MAKE_BITFIELD_ENUM_STRING(type,...)
constexpr bool is_set(const E mask, const E bits) noexcept
bool exists(const std::string &path, bool verbose_on_error=false) noexcept
Returns true if path exists and is accessible.
bool mkdir(const std::string &path, const fmode_t mode=jau::fs::fmode_t::def_dir_prot, const bool verbose=false) noexcept
Create directory.
uint64_t mountflags_t
Generic flag bit values for mount() flags.
std::string lookup_asset_dir(const char *exe_path, const char *asset_file, const char *asset_install_subdir) noexcept
Returns located asset directory if found, otherwise an empty string.
std::string to_named_fd(const int fd) noexcept
Returns platform dependent named file descriptor of given file descriptor, if supported.
mount_ctx mount(const std::string &source, const std::string &target, const std::string &fs_type, const mountflags_t flags, const std::string &fs_options="")
Attach the filesystem named in source to target using the given filesystem source directly.
mount_ctx mount_image(const std::string &image_path, const std::string &target, const std::string &fs_type, const mountflags_t flags, const std::string &fs_options="")
Attach the filesystem image named in image_path to target using an intermediate platform specific fil...
std::string to_string(const fmode_t mask, const bool show_rwx) noexcept
Return the string representation of fmode_t.
bool copy(const std::string &source_path, const std::string &dest_path, const copy_options copts=copy_options::none) noexcept
Copy the given source_path to dest_path using copy_options.
fmode_t
Generic file type and POSIX protection mode bits as used in file_stats, touch(), mkdir() etc.
std::string basename(const std::string_view &path) noexcept
Return stripped leading directory components from given path separated by /.
mountflags_linux
Flag bit values for mount() flags under GNU/Linux.
std::string get_cwd() noexcept
Return the current working directory or empty on failure.
Definition file_util.cpp:84
bool compare(const file_stats &source1, const file_stats &source2, const bool verbose=false) noexcept
Compare the bytes of both files, denoted by source1 and source2.
bool visit(const std::string &path, const traverse_options topts, const path_visitor &visitor, std::vector< int > *dirfds=nullptr) noexcept
Visit element(s) of a given path, see traverse_options for detailed settings.
std::string absolute(const std::string_view &relpath) noexcept
Returns the absolute path of given relpath if existing, otherwise an empty string.
int umountflags_t
Generic flag bit values for umount() flags.
std::string dirname(const std::string_view &path) noexcept
Return stripped last component from given path separated by /, excluding the trailing separator /.
copy_options
Filesystem copy options used to copy() path elements.
bool get_dir_content(const std::string &path, const consume_dir_item &digest) noexcept
Returns a list of directory elements excluding .
bool touch(const std::string &path, const jau::fraction_timespec &atime, const jau::fraction_timespec &mtime, const fmode_t mode=jau::fs::fmode_t::def_file_prot) noexcept
Touch the file with given atime and mtime and create file if not existing yet.
traverse_options
Filesystem traverse options used to visit() path elements.
bool rename(const std::string &oldpath, const std::string &newpath) noexcept
Rename oldpath to newpath using POSIX rename(), with the following combinations.
jau::function< void(const dir_item &)> consume_dir_item
void consume_dir_item(const dir_item& item)
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
void sync() noexcept
Synchronizes filesystems, i.e.
int from_named_fd(const std::string &named_fd) noexcept
Returns the file descriptor from the given named file descriptor.
bool umount(const mount_ctx &context, const umountflags_t flags)
Detach the given mount_ctx context
umountflags_linux
Flag bit values for umount() flags under GNU/Linux.
bool chdir(const std::string &path) noexcept
Change working directory.
bool isAbsolute(const std::string_view &path) noexcept
Returns true if first character is / or - in case of Windows - \\.
traverse_event
Filesystem traverse event used to call path_visitor for path elements from visit().
constexpr ::mode_t posix_protection_bits(const fmode_t mask) noexcept
Returns the POSIX protection bits: rwx_all | set_uid | set_gid | sticky, i.e.
jau::function< bool(traverse_event, const file_stats &, size_t)> path_visitor
path_visitor jau::FunctionDef definition
JAU_MAKE_BITFIELD_ENUM_STRING2(file_stats::field_t, field_t, type, mode, nlink, uid, gid, atime, mtime, ctime, ino, size, blocks, btime)
@ exec_usr
Protection bit: POSIX S_IXUSR.
@ exec_grp
Protection bit: POSIX S_IXGRP.
@ def_file_prot
Default file protection bit: Safe default: POSIX S_IRUSR | S_IWUSR | S_IRGRP or read_usr | write_usr ...
@ write_grp
Protection bit: POSIX S_IWGRP.
@ no_access
Type: Entity gives no access to user, exclusive bit.
@ set_uid
Protection bit: POSIX S_ISUID.
@ write_usr
Protection bit: POSIX S_IWUSR.
@ ugs_set
Protection bit: POSIX S_ISUID | S_ISGID | S_ISVTX.
@ link
Type: Entity is a symbolic link, might be in combination with file or dir, fifo, chr,...
@ sock
Type: Entity is a socket, might be in combination with link.
@ none
No mode bit set.
@ chr
Type: Entity is a character device, might be in combination with link.
@ rwx_oth
Protection bit: POSIX S_IRWXO.
@ sticky
Protection bit: POSIX S_ISVTX.
@ rwx_usr
Protection bit: POSIX S_IRWXU.
@ read_usr
Protection bit: POSIX S_IRUSR.
@ dir
Type: Entity is a directory, might be in combination with link.
@ rwx_all
Protection bit: POSIX S_IRWXU | S_IRWXG | S_IRWXO or rwx_usr | rwx_grp | rwx_oth.
@ file
Type: Entity is a file, might be in combination with link.
@ protection_mask
12 bit protection bit mask 07777 for rwx_all | set_uid | set_gid | sticky .
@ blk
Type: Entity is a block device, might be in combination with link.
@ read_grp
Protection bit: POSIX S_IRGRP.
@ read_oth
Protection bit: POSIX S_IROTH.
@ not_existing
Type: Entity does not exist, exclusive bit.
@ rwx_grp
Protection bit: POSIX S_IRWXG.
@ fifo
Type: Entity is a fifo/pipe, might be in combination with link.
@ write_oth
Protection bit: POSIX S_IWOTH.
@ set_gid
Protection bit: POSIX S_ISGID.
@ def_dir_prot
Default directory protection bit: Safe default: POSIX S_IRWXU | S_IRGRP | S_IXGRP or rwx_usr | read_g...
@ type_mask
Type mask for sock | blk | chr | fifo | dir | file | link | no_access | not_existing.
@ exec_oth
Protection bit: POSIX S_IXOTH.
@ ignore_symlink_errors
Ignore errors from erroneous symlinks, e.g.
@ none
No option set.
@ overwrite
Overwrite existing destination files.
@ preserve_all
Preserve uid and gid if allowed and access- and modification-timestamps, i.e.
@ into_existing_dir
Copy source dir content into an already existing destination directory as if destination directory di...
@ lexicographical_order
Traverse through elements in lexicographical order.
@ verbose
Enable verbosity mode, potentially used by a path_visitor implementation like remove().
@ follow_symlinks
Traverse through symbolic linked directories if traverse_options::recursive is set,...
@ recursive
Traverse through directories, i.e.
@ dir_symlink
Visiting a symbolic-link to a directory which is not followed, i.e.
@ dir_non_recursive
Visiting a directory non-recursive, i.e.
@ dir_check_entry
Visiting a directory on entry, see traverse_options::dir_check_entry.
@ dir_entry
Visiting a directory on entry, see traverse_options::dir_entry.
@ symlink
Visiting a symbolic-link, either to a file or a non-existing entity.
@ dir_exit
Visiting a directory on exit, see traverse_options::dir_exit.
@ file_symlink
Visiting a symlink to a file, i.e.
Author: Sven Gothel sgothel@jausoft.com Copyright Gothel Software e.K.
Definition enum_util.hpp:65
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2022 Gothel Software e.K.
Definition file_util.hpp:41
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
mount_ctx(std::string target_, const int loop_device_id_)
bool operator==(const Addr48Bit &lhs, const Addr48Bit &rhs) noexcept