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