jaulib v1.4.0-2-g788cf73
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_IO_FS_FILE_UTIL_HPP_
26#define JAU_IO_FS_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::io::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 toString() 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 /** A generic file-descriptor not necessarily a file, possible pipe etc. */
435 fd = 0b0001000000000000
436 };
437
438 typedef uint32_t uid_t;
439 typedef uint32_t gid_t;
440
441 private:
442 field_t has_fields_;
443
444 dir_item item_;
445
446 std::shared_ptr<std::string> link_target_path_; // stored link-target path this symbolic-link points to if is_link(), otherwise nullptr.
447 std::shared_ptr<file_stats> link_target_; // link-target this symbolic-link points to if is_link(), otherwise nullptr.
448
449 fmode_t mode_;
450 int fd_;
451 uid_t uid_;
452 gid_t gid_;
453 uint64_t size_;
454 fraction_timespec btime_; // Birth or creation time
455 fraction_timespec atime_; // Last access
456 fraction_timespec ctime_; // Last meta-status change
457 fraction_timespec mtime_; // Last modification
458
459 int errno_res_;
460
461 /** Private class only for private make_shared(). */
462 class ctor_cookie {
463 friend file_stats;
464 uint16_t rec_level;
465 ctor_cookie(const uint16_t recursion_level_) { rec_level = recursion_level_; }
466 };
467
468 public:
469 /** Instantiate an empty file_stats with fmode_t::not_existing set. */
470 file_stats() noexcept;
471
472 /** Private ctor for private make_shared<file_stats>() intended for friends. */
473 file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, const bool dirfd_is_item_dirname) noexcept;
474
475 /**
476 * Instantiates a file_stats for the given `path`.
477 *
478 * The dir_item will be constructed without parent_dir
479 *
480 * @param path the path to produce stats for
481 */
482 file_stats(const std::string& path) noexcept;
483
484 /**
485 * Instantiates a file_stats for the given `path`.
486 *
487 * The dir_item will be constructed without parent_dir
488 *
489 * @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
490 * @param path the path to produce stats for
491 */
492 file_stats(const int dirfd, const std::string& path) noexcept;
493
494 /**
495 * Instantiates a file_stats for the given dir_item.
496 *
497 * @param item the dir_item to produce stats for
498 */
499 file_stats(const dir_item& item) noexcept;
500
501 /**
502 * Instantiates a file_stats for the given dir_item.
503 *
504 * @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
505 * @param item the dir_item to produce stats for
506 * @param dirfd_is_item_dirname if true, dir_item::basename() is relative to dirfd (default), otherwise full dir_item::path() is relative to dirfd.
507 */
508 file_stats(const int dirfd, const dir_item& item, const bool dirfd_is_item_dirname = true) noexcept;
509
510 /**
511 * Instantiates a file_stats for the given `fd` file descriptor.
512 *
513 * @param fd file descriptor of an opened file
514 */
515 file_stats(const int fd) noexcept;
516
517 /**
518 * Returns the dir_item.
519 *
520 * In case this instance is created by following a symbolic link instance,
521 * it represents the resolved path relative to the used symbolic link's dirname.
522 *
523 * @see is_link()
524 * @see path()
525 */
526 const dir_item& item() const noexcept { return item_; }
527
528 /**
529 * Returns the unix path representation.
530 *
531 * In case this instance is created by following a symbolic link instance,
532 * it represents the resolved path relative to the used symbolic link's dirname.
533 *
534 * @see is_link()
535 * @see item()
536 */
537 std::string path() const noexcept { return item_.path(); }
538
539 /**
540 * Returns the stored link-target path this symbolic-link points to if instance is a symbolic-link, otherwise nullptr.
541 *
542 * @see is_link()
543 * @see link_target()
544 * @see final_target()
545 */
546 const std::shared_ptr<std::string>& link_target_path() const noexcept { return link_target_path_; }
547
548 /**
549 * Returns the link-target this symbolic-link points to if instance is a symbolic-link, otherwise nullptr.
550 *
551 * nullptr is also returned for an erroneous symbolic-links, i.e. non-existing link-targets or recursive loop-errors.
552 *
553 * @see is_link()
554 * @see link_target_path()
555 * @see final_target()
556 */
557 const std::shared_ptr<file_stats>& link_target() const noexcept { return link_target_; }
558
559 /**
560 * Returns the final target element, either a pointer to this instance if not a symbolic-link
561 * or the final link-target a symbolic-link (chain) points to.
562 *
563 * @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;
564 *
565 * @see is_link()
566 * @see link_target_path()
567 * @see link_target()
568 */
569 const file_stats* final_target(size_t* link_count = nullptr) const noexcept;
570
571 /** Returns true if the given field_t fields were retrieved, otherwise false. */
572 bool has(const field_t fields) const noexcept;
573
574 /** Returns the retrieved field_t fields. */
575 constexpr field_t fields() const noexcept { return has_fields_; }
576
577 /** Returns the fmode_t, file type and mode. */
578 fmode_t mode() const noexcept { return mode_; }
579
580 /** Returns the POSIX protection bit portion of fmode_t, i.e. mode() & fmode_t::protection_mask. */
581 fmode_t prot_mode() const noexcept { return mode_ & fmode_t::protection_mask; }
582
583 /** Returns the type bit portion of fmode_t, i.e. mode() & fmode_t::type_mask. */
584 fmode_t type_mode() const noexcept { return mode_ & fmode_t::type_mask; }
585
586 /**
587 * Returns the file descriptor if has_fd(), otherwise -1 for no file descriptor.
588 *
589 * @see has_fd()
590 */
591 int fd() const noexcept { return fd_; }
592
593 /** Returns the user id, owning the element. */
594 uid_t uid() const noexcept { return uid_; }
595
596 /** Returns the group id, owning the element. */
597 gid_t gid() const noexcept { return gid_; }
598
599 /**
600 * Returns the size in bytes of this element if is_file(), otherwise zero.
601 *
602 * If the element also is_link(), the linked target size is returned.
603 */
604 uint64_t size() const noexcept { return size_; }
605
606 /** Returns the birth time of this element since Unix Epoch, i.e. its creation time. */
607 const fraction_timespec& btime() const noexcept { return btime_; }
608 /** Returns the last access time of this element since Unix Epoch. */
609 const fraction_timespec& atime() const noexcept { return atime_; }
610 /** Returns the last status change time of this element since Unix Epoch. */
611 const fraction_timespec& ctime() const noexcept { return ctime_; }
612 /** Returns the last modification time of this element since Unix Epoch. */
613 const fraction_timespec& mtime() const noexcept { return mtime_; }
614
615 /** Returns the `errno` value occurred to produce this instance, or zero for no error. */
616 constexpr int errno_res() const noexcept { return errno_res_; }
617
618 /** Returns true if no error occurred */
619 constexpr bool ok() const noexcept { return 0 == errno_res_; }
620
621 /**
622 * Returns true if entity has a file descriptor.
623 *
624 * @see fd()
625 * @see jau::fs::from_named_fd()
626 * @see jau::fs::to_named_fd()
627 */
628 constexpr bool has_fd() const noexcept { return 0 <= fd_; }
629
630 /** Returns true if entity is a socket, might be in combination with is_link(). */
631 constexpr bool is_socket() const noexcept { return is_set(mode_, fmode_t::sock); }
632
633 /** Returns true if entity is a block device, might be in combination with is_link(). */
634 constexpr bool is_block() const noexcept { return is_set(mode_, fmode_t::blk); }
635
636 /** Returns true if entity is a character device, might be in combination with is_link(). */
637 constexpr bool is_char() const noexcept { return is_set(mode_, fmode_t::chr); }
638
639 /** Returns true if entity is a fifo/pipe, might be in combination with is_link(). */
640 constexpr bool is_fifo() const noexcept { return is_set(mode_, fmode_t::fifo); }
641
642 /** Returns true if entity is a directory, might be in combination with is_link(). */
643 constexpr bool is_dir() const noexcept { return is_set(mode_, fmode_t::dir); }
644
645 /** Returns true if entity is a file, might be in combination with is_link(). */
646 constexpr bool is_file() const noexcept { return is_set(mode_, fmode_t::file); }
647
648 /** 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(). */
649 constexpr bool is_link() const noexcept { return is_set(mode_, fmode_t::link); }
650
651 /** Returns true if entity allows access to user, exclusive bit. */
652 constexpr bool has_access() const noexcept { return !is_set(mode_, fmode_t::no_access); }
653
654 /** Returns true if entity does not exist, exclusive bit. */
655 constexpr bool exists() const noexcept { return !is_set(mode_, fmode_t::not_existing); }
656
657 bool operator==(const file_stats& rhs) const noexcept;
658
659 bool operator!=(const file_stats& rhs) const noexcept {
660 return !(*this == rhs);
661 }
662
663 /**
664 * Returns a comprehensive string representation of this element
665 */
666 std::string toString() const noexcept;
667 };
668 JAU_MAKE_BITFIELD_ENUM_STRING2(file_stats::field_t, field_t, type, mode, nlink, uid, gid, atime, mtime, ctime, ino, size, blocks, btime);
669
670 inline std::ostream& operator<<(std::ostream& os, const file_stats& v) { return os << v.toString(); }
671
672 /**
673 * Create directory
674 * @param path full path to new directory
675 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_dir_prot
676 * @param verbose defaults to false
677 * @return true if successful, otherwise false
678 */
679 bool mkdir(const std::string& path, const fmode_t mode = fmode_t::def_dir_prot, const bool verbose = false) noexcept;
680
681 /**
682 * Touch the file with given atime and mtime and create file if not existing yet.
683 * @param path full path to file
684 * @param atime new access time
685 * @param mtime new modification time
686 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_file_prot
687 * @return true if successful, otherwise false
688 */
689 bool touch(const std::string& path, const jau::fraction_timespec& atime, const jau::fraction_timespec& mtime,
690 const fmode_t mode = fmode_t::def_file_prot) noexcept;
691
692 /**
693 * Touch the file with current time and create file if not existing yet.
694 * @param path full path to file
695 * @param mode fmode_t POSIX protection bits used, defaults to jau::fs::fmode_t::def_file_prot
696 * @return true if successful, otherwise false
697 */
698 bool touch(const std::string& path, const fmode_t mode = fmode_t::def_file_prot) noexcept;
699
700 /**
701 * `void consume_dir_item(const dir_item& item)`
702 */
703 typedef jau::function<void(const dir_item&)> consume_dir_item;
704
705 /**
706 * Returns a list of directory elements excluding `.` and `..` for the given path, non recursive.
707 *
708 * The custom consume_dir_item `digest` may also be used to filter the element, besides storing it.
709 *
710 * @param path path to directory
711 * @param digest consume_dir_item function to receive each directory item, e.g. `void consume_dir_item(const dir_item& item)`
712 * @return true if given path exists, is directory and is readable, otherwise false
713 */
714 bool get_dir_content(const std::string& path, const consume_dir_item& digest) noexcept;
715
716 /**
717 * Returns a list of directory elements excluding `.` and `..` for the given path, non recursive.
718 *
719 * The custom consume_dir_item `digest` may also be used to filter the element, besides storing it.
720 *
721 * @param dirfd file descriptor to given `path` left untouched as a copy is being used to retrieve the directory content.
722 * @param path path to directory
723 * @param digest consume_dir_item function to receive each directory item, e.g. `void consume_dir_item(const dir_item& item)`
724 * @return true if given path exists, is directory and is readable, otherwise false
725 */
726 bool get_dir_content(const int dirfd, const std::string& path, const consume_dir_item& digest) noexcept;
727
728 /**
729 * Filesystem traverse event used to call path_visitor for path elements from visit().
730 *
731 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
732 *
733 * @see path_visitor
734 * @see visit()
735 */
736 enum class traverse_event : uint16_t {
737 /** No value, neither file, symlink nor dir_entry or dir_exit. Implying an error state in file_stat, e.g. !file_stats::has_access(). */
738 none = 0,
739
740 /**
741 * 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.
742 *
743 * In case of a symbolic-link to an existing file, file is also set, i.e. file_symlink.
744 */
745 symlink = 1 << 0,
746
747 /** Visiting a file, may be in conjunction with symlink, i.e. file_symlink. */
748 file = 1 << 1,
749
750 /** Visiting a symlink to a file, i.e. symlink | file */
752
753 /**
754 * Visiting a symbolic-link to a directory which is not followed, i.e. traverse_options::follow_symlinks not set.
755 */
756 dir_symlink = 1 << 2,
757
758 /**
759 * Visiting a directory on entry, see traverse_options::dir_check_entry.
760 *
761 * This allows the path_visitor to deny traversal into the directory by returning false,
762 * otherwise continuing traversal.
763 */
765
766 /**
767 * Visiting a directory on entry, see traverse_options::dir_entry.
768 *
769 * If a directory is visited non-recursive, i.e. traverse_options::recursive not set,
770 * dir_entry and dir_exit are set, see dir_non_recursive.
771 *
772 * If a directory is a symbolic link which is not followed, i.e. traverse_options::follow_symlinks not set,
773 * dir_symlink is used instead.
774 */
775 dir_entry = 1 << 8,
776
777 /**
778 * Visiting a directory on exit, see traverse_options::dir_exit.
779 *
780 * If a directory is visited non-recursive, i.e. traverse_options::recursive not set,
781 * dir_entry and dir_exit are set, see dir_non_recursive.
782 *
783 * If a directory is a symbolic link which is not followed, i.e. traverse_options::follow_symlinks not set,
784 * dir_symlink is used instead.
785 */
786 dir_exit = 1 << 9,
787
788 /**
789 * Visiting a directory non-recursive, i.e. traverse_options::recursive not set.
790 *
791 * Value is a bit-mask of dir_entry | dir_exit
792 */
794 };
796
797 /**
798 * path_visitor jau::FunctionDef definition
799 * - `bool visitor(traverse_event tevt, const file_stats& item_stats, size_t depth)`
800 *
801 * Depth being the recursive directory depth starting with 1 for the initial directory.
802 *
803 * Returning `false` stops traversal in general but traverse_options::dir_check_entry
804 * will only skip traversing the denied directory.
805 */
806 typedef jau::function<bool(traverse_event, const file_stats&, size_t)> path_visitor;
807
808 /**
809 * Filesystem traverse options used to visit() path elements.
810 *
811 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
812 *
813 * @see visit()
814 * @see remove()
815 */
816 enum class traverse_options : uint16_t {
817 /** No option set */
818 none = 0,
819
820 /** Traverse through directories, i.e. perform visit, copy, remove etc actions recursively throughout the directory structure. */
821 recursive = 1U << 0,
822
823 /** Traverse through symbolic linked directories if traverse_options::recursive is set, i.e. directories with property fmode_t::link set. */
825
826 /** Traverse through elements in lexicographical order. This might be required when computing an order dependent outcome like a hash value. */
828
829 /** Call path_visitor at directory entry, allowing path_visitor to skip traversal of this directory if returning false. */
831
832 /** Call path_visitor at directory entry. Both, dir_entry and dir_exit can be set, only one or none. */
833 dir_entry = 1U << 8,
834
835 /** Call path_visitor at directory exit. Both, dir_entry and dir_exit can be set, only one or none. */
836 dir_exit = 1U << 9,
837
838 /** Enable verbosity mode, potentially used by a path_visitor implementation like remove(). */
839 verbose = 1U << 15
840 };
842
843 /**
844 * Visit element(s) of a given path, see traverse_options for detailed settings.
845 *
846 * All elements of type fmode_t::file, fmode_t::dir and fmode_t::no_access or fmode_t::not_existing
847 * will be visited by the given path_visitor `visitor`.
848 *
849 * Depth passed to path_visitor is the recursive directory depth and starts with 1 for the initial directory.
850 *
851 * path_visitor returning `false` stops traversal in general but traverse_options::dir_check_entry
852 * will only skip traversing the denied directory.
853 *
854 * @param path the starting path
855 * @param topts given traverse_options for this operation
856 * @param visitor path_visitor function `bool visitor(const file_stats& item_stats, size_t depth)`.
857 * @param dirfds optional empty `dirfd` stack pointer defaults to nullptr.
858 * If user provided, exposes the used `dirfd` stack, which last entry represents the currently visited directory.
859 * The `dirfd` stack starts and ends empty, i.e. all directory file descriptor are closed.
860 * In case of recursive directory traversion, the initial dir_entry visit starts with depth 1 and 2 fds, its parent and current directory.
861 * @return true if successful including no path_visitor stopped traversal by returning `false` excluding traverse_options::dir_check_entry.
862 */
863 bool visit(const std::string& path, const traverse_options topts, const path_visitor& visitor, std::vector<int>* dirfds = nullptr) noexcept;
864
865 /**
866 * Visit element(s) of a given path, see traverse_options for detailed settings.
867 *
868 * All elements of type fmode_t::file, fmode_t::dir and fmode_t::no_access or fmode_t::not_existing
869 * will be visited by the given path_visitor `visitor`.
870 *
871 * Depth passed to path_visitor is the recursive directory depth and starts with 1 for the initial directory.
872 *
873 * path_visitor returning `false` stops traversal in general but traverse_options::dir_check_entry
874 * will only skip traversing the denied directory.
875 *
876 * @param item_stats pre-fetched file_stats for a given dir_item, used for efficiency
877 * @param topts given traverse_options for this operation
878 * @param visitor path_visitor function `bool visitor(const file_stats& item_stats, size_t depth)`.
879 * @param dirfds optional empty `dirfd` stack pointer defaults to nullptr.
880 * If user provided, exposes the used `dirfd` stack, which last entry represents the currently visited directory.
881 * The `dirfd` stack starts and ends empty, i.e. all directory file descriptor are closed.
882 * In case of recursive directory traversion, the initial dir_entry visit starts with depth 1 and 2 fds, its parent and current directory.
883 * @return true if successful including no path_visitor stopped traversal by returning `false` excluding traverse_options::dir_check_entry.
884 */
885 bool visit(const file_stats& item_stats, const traverse_options topts, const path_visitor& visitor, std::vector<int>* dirfds = nullptr) noexcept;
886
887 /**
888 * Remove the given path. If path represents a director, `recursive` must be set to true.
889 *
890 * The given traverse_options `options` are handled as follows:
891 * - traverse_options::parent_dir_last will be added by implementation to operate correct
892 * - traverse_options::recursive shall shall be set by caller to remove directories
893 * - traverse_options::follow_symlinks shall be set by caller to remove symbolic linked directories recursively, which is kind of dangerous.
894 * If not set, only the symbolic link will be removed (default)
895 *
896 * Implementation is most data-race-free (DRF), utilizes following safeguards
897 * - utilizing parent directory file descriptor and `openat()` and `unlinkat()` operations against concurrent mutation
898 *
899 * @param path path to remove
900 * @param topts given traverse_options for this operation, defaults to traverse_options::none
901 * @return true only if the file or the directory with content has been deleted, otherwise false
902 */
903 bool remove(const std::string& path, const traverse_options topts = traverse_options::none) noexcept;
904
905 /**
906 * Compare the bytes of both files, denoted by source1 and source2.
907 *
908 * @param source1 first source file to compare
909 * @param source2 second source file to compare
910 * @param verbose defaults to false
911 * @return true if both elements are files and their bytes are equal, otherwise false.
912 */
913 bool compare(const file_stats& source1, const file_stats& source2, const bool verbose = false) noexcept;
914
915 /**
916 * Compare the bytes of both files, denoted by source1 and source2.
917 *
918 * @param source1 first source file to compare
919 * @param source2 second source file to compare
920 * @param verbose defaults to false
921 * @return true if both elements are files and their bytes are equal, otherwise false.
922 */
923 bool compare(const std::string& source1, const std::string& source2, const bool verbose = false) noexcept;
924
925 /**
926 * Filesystem copy options used to copy() path elements.
927 *
928 * By default, the fmode_t POSIX protection mode bits are preserved
929 * while using the caller's uid and gid as well as current timestamps. <br />
930 * Use copy_options::preserve_all to preserve uid and gid if allowed from the caller and access- and modification-timestamps.
931 *
932 * This `enum class` type fulfills `C++ named requirements: BitmaskType`.
933 *
934 * @see copy()
935 */
936 enum class copy_options : uint16_t {
937 /** No option set */
938 none = 0,
939
940 /** Traverse through directories, i.e. perform visit, copy, remove etc actions recursively throughout the directory structure. */
941 recursive = 1 << 0,
942
943 /** Copy referenced symbolic linked files or directories instead of just the symbolic link with property fmode_t::link set. */
945
946 /**
947 * Copy source dir content into an already existing destination directory as if destination directory did not exist.
948 *
949 * Otherwise, if destination directory already exist, the source directory will be copied below the destination directory.
950 */
952
953 /**
954 * Ignore errors from erroneous symlinks, e.g. non-existing link-targets, recursive loop-errors.or unsupported symmlinks on target filesystem.
955 *
956 * This flag is required to
957 * - copy erroneous non-existing symlinks if using follow_symlinks
958 * - copy erroneous recursive loop-error symlinks if using follow_symlinks
959 * - ignore symlinks if not supported by target filesystem if not using follow_symlinks
960 */
962
963 /** Overwrite existing destination files. */
964 overwrite = 1 << 9,
965
966 /** Preserve uid and gid if allowed and access- and modification-timestamps, i.e. producing a most exact meta-data copy. */
967 preserve_all = 1 << 10,
968
969 /** Ensure data and meta-data file synchronization is performed via ::fsync() after asynchronous copy operations of a file's content. */
970 sync = 1 << 11,
971
972 /** Enable verbosity mode, show error messages on stderr. */
973 verbose = 1 << 15
974 };
976
977 /**
978 * Copy the given source_path to dest_path using copy_options.
979 *
980 * The behavior is similar like POSIX `cp` commandline tooling.
981 *
982 * The following behavior is being followed regarding dest_path:
983 * - If source_path is a directory and copy_options::recursive set
984 * - If dest_path doesn't exist, source_path dir content is copied into the newly created dest_path.
985 * - If dest_path exists as a directory, source_path dir will be copied below the dest_path directory
986 * _if_ copy_options::into_existing_dir is not set. Otherwise its content is copied into the existing dest_path.
987 * - Everything else is considered an error
988 * - If source_path is a file
989 * - If dest_path doesn't exist, source_path file is copied to dest_path as a file.
990 * - If dest_path exists as a directory, source_path file will be copied below the dest_path directory.
991 * - If dest_path exists as a file, copy_options::overwrite must be set to have it overwritten by the source_path file
992 * - Everything else is considered an error
993 *
994 * Implementation either uses ::sendfile() if running under `GNU/Linux`,
995 * otherwise POSIX ::read() and ::write().
996 *
997 * Implementation is most data-race-free (DRF), utilizes following safeguards on recursive directory copy
998 * - utilizing parent directory file descriptor and `openat()` operations against concurrent mutation
999 * - for each entered *directory*
1000 * - new destination directory is create with '.<random_number>' and user-rwx permissions only
1001 * - its file descriptor is being opened
1002 * - its user-read permission is dropped, remains user-wx permissions only
1003 * - its renamed to destination path
1004 * - all copy operations are performed inside
1005 * - at exit, its permissions are restored, etc.
1006 *
1007 * See copy_options for details.
1008 *
1009 * @param source_path
1010 * @param dest_path
1011 * @param copts
1012 * @return true if successful, otherwise false
1013 */
1014 bool copy(const std::string& source_path, const std::string& dest_path, const copy_options copts = copy_options::none) noexcept;
1015
1016 /**
1017 * Rename oldpath to newpath using POSIX `::rename()`, with the following combinations
1018 * - oldpath and newpath refer to the same file, a successful no-operation.
1019 * - oldpath file
1020 * - newpath not-existing file
1021 * - newpath existing file to be atomically replaced
1022 * - oldpath directory
1023 * - newpath not-existing directory
1024 * - newpath existing empty directory
1025 * - oldpath symlink will be renamed
1026 * - newpath symlink will be overwritten
1027 *
1028 * @param oldpath previous path
1029 * @param newpath new path
1030 * @return true only if the rename operation was successful, otherwise false
1031 */
1032 bool rename(const std::string& oldpath, const std::string& newpath) noexcept;
1033
1034 /**
1035 * Synchronizes filesystems, i.e. all pending modifications to filesystem metadata and cached file data will be written to the underlying filesystems.
1036 */
1037 void sync() noexcept;
1038
1039 struct mount_ctx {
1041 std::string target;
1043
1044 mount_ctx(std::string target_, const int loop_device_id_)
1045 : mounted(true), target(std::move(target_)), loop_device_id(loop_device_id_) {}
1046
1048 : mounted(false), target(), loop_device_id(-1) {}
1049 };
1050
1051 /**
1052 * Generic flag bit values for mount() `flags`.
1053 *
1054 * See mount(2) for a detailed description.
1055 */
1056 typedef uint64_t mountflags_t;
1057
1058 /**
1059 * Flag bit values for mount() `flags` under GNU/Linux.
1060 *
1061 * See mount(2) for a detailed description.
1062 */
1064 none = 0,
1072 dirsync = 128,
1073 noatime = 1024,
1075 bind = 4096,
1076 move = 8192,
1077 rec = 16384,
1078 silent = 32768,
1079 posixacl = 1 << 16,
1080 unbindable = 1 << 17,
1081 private_ = 1 << 18,
1082 slave = 1 << 19,
1083 shared = 1 << 20,
1084 relatime = 1 << 21,
1085 kernmount = 1 << 22,
1086 i_version = 1 << 23,
1087 strictatime = 1 << 24,
1088 lazytime = 1 << 25,
1089 active = 1 << 30,
1090 nouser = 1UL << 31
1091 };
1095
1096 /**
1097 * Attach the filesystem image named in `image_path` to `target`
1098 * using an intermediate platform specific filesystem image loop-device.
1099 *
1100 * This method either requires root permissions <br />
1101 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1102 *
1103 * Unmounting shall be done via umount() with mount_ctx argument to ensure
1104 * all intermediate resources are released.
1105 *
1106 * @param image_path path of image source file
1107 * @param target directory where `image_path` filesystem shall be attached to
1108 * @param fs_type type of filesystem, e.g. `squashfs`, `tmpfs`, `iso9660`, etc.
1109 * @param flags filesystem agnostic mount flags, see mountflags_linux.
1110 * @param fs_options comma separated options for the filesystem `fs_type`, see mount(8) for available options for the used filesystem.
1111 * @return mount_ctx structure containing mounted status etc
1112 *
1113 * @see mountflags_t
1114 * @see mountflags_linux
1115 * @see mount()
1116 * @see umount()
1117 */
1118 mount_ctx mount_image(const std::string& image_path, const std::string& target, const std::string& fs_type,
1119 const mountflags_t flags, const std::string& fs_options = "");
1120
1121 /**
1122 * Attach the filesystem named in `source` to `target`
1123 * using the given filesystem source directly.
1124 *
1125 * This method either requires root permissions <br />
1126 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1127 *
1128 * @param source filesystem path for device, directory, file or dummy-string which shall be attached
1129 * @param target directory where `source` filesystem shall be attached to
1130 * @param fs_type type of filesystem, e.g. `squashfs`, `tmpfs`, `iso9660`, etc.
1131 * @param flags filesystem agnostic mount flags, see mountflags_linux.
1132 * @param fs_options comma separated options for the filesystem `fs_type`, see mount(8) for available options for the used filesystem.
1133 * @return mount_ctx structure containing mounted status etc
1134 *
1135 * @see mountflags_t
1136 * @see mountflags_linux
1137 * @see mount_image()
1138 * @see umount()
1139 */
1140 mount_ctx mount(const std::string& source, const std::string& target, const std::string& fs_type,
1141 const mountflags_t flags, const std::string& fs_options = "");
1142
1143 /**
1144 * Generic flag bit values for umount() `flags`.
1145 *
1146 * See umount(2) for a detailed description.
1147 */
1148 typedef int umountflags_t;
1149
1150 /**
1151 * Flag bit values for umount() `flags` under GNU/Linux.
1152 *
1153 * See umount(2) for a detailed description.
1154 */
1162
1163 /**
1164 * Detach the given mount_ctx `context`
1165 *
1166 * This method either requires root permissions <br />
1167 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1168 *
1169 * @param context mount_ctx previously attached via mount_image() or mount()
1170 * @param flags optional umount options, if supported by the system. See umount_options_linux.
1171 * @return true if successful, otherwise false
1172 *
1173 * @see umountflags_t
1174 * @see umountflags_linux
1175 * @see mount()
1176 * @see mount_image()
1177 */
1178 bool umount(const mount_ctx& context, const umountflags_t flags);
1179
1180 /**
1181 * Detach the topmost filesystem mounted on `target`
1182 * optionally using given `umountflags` options if supported.
1183 *
1184 * This method either requires root permissions <br />
1185 * or the following capabilities: `cap_sys_admin`,`cap_setuid`, `cap_setgid`.
1186 *
1187 * @param target directory of previously attached filesystem
1188 * @param flags optional umount options, if supported by the system. See umount_options_linux.
1189 * @return true if successful, otherwise false
1190 *
1191 * @see umountflags_t
1192 * @see umountflags_linux
1193 * @see mount()
1194 * @see mount_image()
1195 */
1196 bool umount(const std::string& target, const umountflags_t flags);
1197
1198 /**@}*/
1199
1200} // namespace jau::io::fs
1201
1202#endif /* JAU_IO_FS_FILE_UTIL_HPP_ */
Class template jau::function is a general-purpose static-polymorphic function wrapper.
Representing a directory item split into dirname() and basename().
std::string path() const noexcept
Returns a full unix path representation combining dirname() and basename().
bool operator!=(const dir_item &rhs) const noexcept
const std::string & dirname() const noexcept
Returns the dirname, shall not be empty and denotes .
const std::string & basename() const noexcept
Return the basename, shall not be empty nor contain a dirname.
dir_item() noexcept
Empty item w/ .
bool empty() const noexcept
Returns true if bot, dirname() and basename() refer to .
std::string toString() const noexcept
Returns a comprehensive string representation of this item.
bool operator==(const dir_item &rhs) const noexcept
Platform agnostic representation of POSIX ::lstat() and ::stat() for a given pathname.
fmode_t mode() const noexcept
Returns the fmode_t, file type and mode.
constexpr bool is_dir() const noexcept
Returns true if entity is a directory, might be in combination with is_link().
constexpr int errno_res() const noexcept
Returns the errno value occurred to produce this instance, or zero for no error.
constexpr bool is_file() const noexcept
Returns true if entity is a file, might be in combination with is_link().
uint64_t size() const noexcept
Returns the size in bytes of this element if is_file(), otherwise zero.
const fraction_timespec & mtime() const noexcept
Returns the last modification time of this element since Unix Epoch.
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,...
std::string path() const noexcept
Returns the unix path representation.
constexpr bool ok() const noexcept
Returns true if no error occurred.
const fraction_timespec & btime() const noexcept
Returns the birth time of this element since Unix Epoch, i.e.
const dir_item & item() const noexcept
Returns the dir_item.
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.
constexpr bool has_access() const noexcept
Returns true if entity allows access to user, exclusive bit.
const fraction_timespec & ctime() const noexcept
Returns the last status change time of this element since Unix Epoch.
file_stats() noexcept
Instantiate an empty file_stats with fmode_t::not_existing set.
field_t
Field identifier which bit-mask indicates field_t fields.
@ type
File type mode bits.
constexpr bool is_char() const noexcept
Returns true if entity is a character device, might be in combination with is_link().
uid_t uid() const noexcept
Returns the user id, owning the element.
constexpr bool is_socket() const noexcept
Returns true if entity is a socket, might be in combination with is_link().
fmode_t type_mode() const noexcept
Returns the type bit portion of fmode_t, i.e.
constexpr bool is_fifo() const noexcept
Returns true if entity is a fifo/pipe, might be in combination with is_link().
constexpr bool is_block() const noexcept
Returns true if entity is a block device, 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(),...
int fd() const noexcept
Returns the file descriptor if has_fd(), otherwise -1 for no file descriptor.
constexpr field_t fields() const noexcept
Returns the retrieved field_t fields.
constexpr bool exists() const noexcept
Returns true if entity does not exist, exclusive bit.
const fraction_timespec & atime() const noexcept
Returns the last access time of this element since Unix Epoch.
constexpr bool has_fd() const noexcept
Returns true if entity has a file descriptor.
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,...
gid_t gid() const noexcept
Returns the group id, owning the element.
#define JAU_MAKE_BITFIELD_ENUM_STRING(type,...)
constexpr bool is_set(const E mask, const E bits) noexcept
bool umount(const mount_ctx &context, const umountflags_t flags)
Detach the given mount_ctx context
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.
mountflags_linux
Flag bit values for mount() flags under GNU/Linux.
std::string absolute(const std::string_view &relpath) noexcept
Returns the absolute path of given relpath if existing, otherwise an empty string.
int from_named_fd(const std::string &named_fd) noexcept
Returns the file descriptor from the given named file descriptor.
traverse_event
Filesystem traverse event used to call path_visitor for path elements from visit().
std::string basename(const std::string_view &path) noexcept
Return stripped leading directory components from given path separated by /.
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 dirname(const std::string_view &path) noexcept
Return stripped last component from given path separated by /, excluding the trailing separator /.
int umountflags_t
Generic flag bit values for umount() flags.
bool isAbsolute(const std::string_view &path) noexcept
Returns true if first character is / or - in case of Windows - \\.
fmode_t
Generic file type and POSIX protection mode bits as used in file_stats, touch(), mkdir() etc.
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...
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.
copy_options
Filesystem copy options used to copy() path elements.
std::string get_cwd() noexcept
Return the current working directory or empty on failure.
Definition file_util.cpp:85
std::string to_string(const fmode_t mask, const bool show_rwx) noexcept
Return the string representation of fmode_t.
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.
traverse_options
Filesystem traverse options used to visit() path elements.
void sync() noexcept
Synchronizes filesystems, i.e.
bool exists(const std::string &path, bool verbose_on_error=false) noexcept
Returns true if path exists and is accessible.
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 chdir(const std::string &path) noexcept
Change working directory.
umountflags_linux
Flag bit values for umount() flags under GNU/Linux.
std::string to_named_fd(const int fd) noexcept
Returns platform dependent named file descriptor of given file descriptor, if supported.
jau::function< void(const dir_item &)> consume_dir_item
void consume_dir_item(const dir_item& item)
JAU_MAKE_BITFIELD_ENUM_STRING2(file_stats::field_t, field_t, type, mode, nlink, uid, gid, atime, mtime, ctime, ino, size, blocks, btime)
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
jau::function< bool(traverse_event, const file_stats &, size_t)> path_visitor
path_visitor jau::FunctionDef definition
uint64_t mountflags_t
Generic flag bit values for mount() flags.
bool get_dir_content(const std::string &path, const consume_dir_item &digest) noexcept
Returns a list of directory elements excluding .
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.
bool rename(const std::string &oldpath, const std::string &newpath) noexcept
Rename oldpath to newpath using POSIX rename(), with the following combinations.
@ 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.
@ 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.
@ 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.
std::string toString(io_result_t v) noexcept
Definition io_util.hpp:67
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
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2024 Gothel Software e.K.
__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