31 #include <sys/types.h>
50 jau::fprintf_td(stdout,
"test00: 02: proot02.rel: %s\n", rel_project_root.c_str());
52 REQUIRE( proot_stats_01.
exists() );
53 REQUIRE( proot_stats_02.
exists() );
61 INFO_STR(
"\n\ntest01_cwd: cwd "+cwd+
"\n");
62 REQUIRE( 0 < cwd.size() );
63 const size_t idx = cwd.find(
"/jaulib");
65 REQUIRE( idx < cwd.size() );
66 REQUIRE( idx != std::string::npos );
74 const std::string pathname0 =
"/";
76 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
77 REQUIRE( 0 < pathname1.size() );
78 REQUIRE( pathname1 ==
"/" );
82 const std::string pathname0 =
"lala.txt";
84 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
85 REQUIRE( 0 < pathname1.size() );
86 REQUIRE( pathname1 ==
"." );
89 const std::string pathname0 =
"lala";
91 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
92 REQUIRE( 0 < pathname1.size() );
93 REQUIRE( pathname1 ==
"." );
96 const std::string pathname0 =
"lala/";
98 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
99 REQUIRE( 0 < pathname1.size() );
100 REQUIRE( pathname1 ==
"." );
104 const std::string pathname0 =
"/lala.txt";
106 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
107 REQUIRE( 0 < pathname1.size() );
108 REQUIRE( pathname1 ==
"/" );
111 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
113 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
114 REQUIRE( 0 < pathname1.size() );
115 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
118 const std::string pathname0 =
"blabla/jaulib/test/sub";
120 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
121 REQUIRE( 0 < pathname1.size() );
122 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
125 const std::string pathname0 =
"blabla/jaulib/test/";
127 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
128 REQUIRE( 0 < pathname1.size() );
129 REQUIRE( pathname1 ==
"blabla/jaulib" );
132 const std::string pathname0 =
"blabla/jaulib/test";
134 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
135 REQUIRE( 0 < pathname1.size() );
136 REQUIRE( pathname1 ==
"blabla/jaulib" );
142 const std::string pathname0 =
"/";
144 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
145 REQUIRE( 0 < pathname1.size() );
146 REQUIRE( pathname1 ==
"/" );
151 const std::string pathname0 =
"lala.txt";
153 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
154 REQUIRE( 0 < pathname1.size() );
155 REQUIRE( pathname1 ==
"lala.txt" );
159 const std::string pathname0 =
"lala";
161 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
162 REQUIRE( 0 < pathname1.size() );
163 REQUIRE( pathname1 ==
"lala" );
167 const std::string pathname0 =
"lala/";
169 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
170 REQUIRE( 0 < pathname1.size() );
171 REQUIRE( pathname1 ==
"lala" );
175 const std::string pathname0 =
"/lala.txt";
177 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
178 REQUIRE( 0 < pathname1.size() );
179 REQUIRE( pathname1 ==
"lala.txt" );
182 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
184 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
185 REQUIRE( 0 < pathname1.size() );
186 REQUIRE( pathname1 ==
"sub.txt" );
190 const std::string pathname0 =
"blabla/jaulib/test/";
192 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
193 REQUIRE( 0 < pathname1.size() );
194 REQUIRE( pathname1 ==
"test" );
198 const std::string pathname0 =
"blabla/jaulib/test";
200 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
201 REQUIRE( 0 < pathname1.size() );
202 REQUIRE( pathname1 ==
"test" );
211 jau::fprintf_td(stdout,
"test03b_absolute: 01: rel_project_root %s\n", rel_project_root.c_str());
214 REQUIRE(
true == proot_stats.
exists() );
215 REQUIRE(
true == proot_stats.
is_dir() );
217 std::string abs_project_root;
220 jau::fprintf_td(stdout,
"test03b_absolute: 02: %s\n", abs_project_root.c_str());
221 REQUIRE( 0 < abs_project_root.size() );
228 REQUIRE( stats.
exists() );
229 REQUIRE( stats.
is_dir() );
234 jau::fprintf_td(stdout,
"test03b_absolute: 03.0: %s\n", bname0.c_str());
235 jau::fprintf_td(stdout,
"test03b_absolute: 03.1: %s\n", bname1.c_str());
236 REQUIRE( bname0 == bname1 );
244 INFO_STR(
"\n\ntest04_dir_item: 00 "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
245 REQUIRE(
"." == di.
dirname() );
247 REQUIRE(
"." == di.
path() );
248 REQUIRE(
true == di.
empty() );
251 const std::string dirname_;
253 INFO_STR(
"\n\ntest04_dir_item: 01 '"+dirname_+
"' -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
254 REQUIRE(
"." == di.
dirname() );
256 REQUIRE(
"." == di.
path() );
257 REQUIRE(
true == di.
empty() );
260 const std::string dirname_(
".");
262 INFO_STR(
"\n\ntest04_dir_item: 02 '"+dirname_+
"' -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
263 REQUIRE(
"." == di.
dirname() );
265 REQUIRE(
"." == di.
path() );
266 REQUIRE(
false == di.
empty() );
269 const std::string dirname_(
"/");
271 INFO_STR(
"\n\ntest04_dir_item: 03 '"+dirname_+
"' -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
272 REQUIRE(
"/" == di.
dirname() );
274 REQUIRE(
"/" == di.
path() );
275 REQUIRE(
false == di.
empty() );
279 const std::string path1_ =
"lala";
281 INFO_STR(
"\n\ntest04_dir_item: 10 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
282 REQUIRE(
"." == di.
dirname() );
284 REQUIRE(
"lala" == di.
path() );
285 REQUIRE(
false == di.
empty() );
288 const std::string path1_ =
"lala/";
290 INFO_STR(
"\n\ntest04_dir_item: 11 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
291 REQUIRE(
"." == di.
dirname() );
293 REQUIRE(
"lala" == di.
path() );
294 REQUIRE(
false == di.
empty() );
298 const std::string path1_ =
"/lala";
300 INFO_STR(
"\n\ntest04_dir_item: 12 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
301 REQUIRE(
"/" == di.
dirname() );
303 REQUIRE(
"/lala" == di.
path() );
304 REQUIRE(
false == di.
empty() );
308 const std::string path1_ =
"dir0/lala";
310 INFO_STR(
"\n\ntest04_dir_item: 20 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
311 REQUIRE(
"dir0" == di.
dirname() );
313 REQUIRE(
"dir0/lala" == di.
path() );
316 const std::string path1_ =
"dir0/lala/";
318 INFO_STR(
"\n\ntest04_dir_item: 21 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
319 REQUIRE(
"dir0" == di.
dirname() );
321 REQUIRE(
"dir0/lala" == di.
path() );
324 const std::string path1_ =
"/dir0/lala";
326 INFO_STR(
"\n\ntest04_dir_item: 22 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
327 REQUIRE(
"/dir0" == di.
dirname() );
329 REQUIRE(
"/dir0/lala" == di.
path() );
332 const std::string path1_ =
"/dir0/lala/";
334 INFO_STR(
"\n\ntest04_dir_item: 23 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
335 REQUIRE(
"/dir0" == di.
dirname() );
337 REQUIRE(
"/dir0/lala" == di.
path() );
342 const std::string path1_ =
"/dir0/../lala";
344 INFO_STR(
"\n\ntest04_dir_item: 30 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
345 REQUIRE(
"/" == di.
dirname() );
347 REQUIRE(
"/lala" == di.
path() );
350 const std::string path1_ =
"dir0/../lala";
352 INFO_STR(
"\n\ntest04_dir_item: 31 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
353 REQUIRE(
"." == di.
dirname() );
355 REQUIRE(
"lala" == di.
path() );
358 const std::string path1_ =
"../../lala";
360 INFO_STR(
"\n\ntest04_dir_item: 32 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
361 REQUIRE(
"../.." == di.
dirname() );
363 REQUIRE(
"../../lala" == di.
path() );
366 const std::string path1_ =
"./../lala";
368 INFO_STR(
"\n\ntest04_dir_item: 33 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
369 REQUIRE(
".." == di.
dirname() );
371 REQUIRE(
"../lala" == di.
path() );
374 const std::string path1_ =
"dir0/../../lala";
376 INFO_STR(
"\n\ntest04_dir_item: 34 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
377 REQUIRE(
".." == di.
dirname() );
379 REQUIRE(
"../lala" == di.
path() );
383 const std::string path1_ =
"dir0/dir1/../lala";
385 INFO_STR(
"\n\ntest04_dir_item: 40 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
386 REQUIRE(
"dir0" == di.
dirname() );
388 REQUIRE(
"dir0/lala" == di.
path() );
391 const std::string path1_ =
"/dir0/dir1/../lala/";
393 INFO_STR(
"\n\ntest04_dir_item: 41 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
394 REQUIRE(
"/dir0" == di.
dirname() );
396 REQUIRE(
"/dir0/lala" == di.
path() );
399 const std::string path1_ =
"dir0/dir1/../bbb/ccc/../lala";
401 INFO_STR(
"\n\ntest04_dir_item: 42 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
402 REQUIRE(
"dir0/bbb" == di.
dirname() );
404 REQUIRE(
"dir0/bbb/lala" == di.
path() );
407 const std::string path1_ =
"dir0/dir1/bbb/../../lala";
409 INFO_STR(
"\n\ntest04_dir_item: 43 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
410 REQUIRE(
"dir0" == di.
dirname() );
412 REQUIRE(
"dir0/lala" == di.
path() );
415 const std::string path1_ =
"dir0/dir1/bbb/../../../lala";
417 INFO_STR(
"\n\ntest04_dir_item: 44 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
418 REQUIRE(
"." == di.
dirname() );
420 REQUIRE(
"lala" == di.
path() );
423 const std::string path1_ =
"dir0/dir1/bbb/../../../../lala";
425 INFO_STR(
"\n\ntest04_dir_item: 45 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
426 REQUIRE(
".." == di.
dirname() );
428 REQUIRE(
"../lala" == di.
path() );
431 const std::string path1_ =
"dir0/dir1/bbb/../../lala/..";
433 INFO_STR(
"\n\ntest04_dir_item: 46 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
434 REQUIRE(
"." == di.
dirname() );
436 REQUIRE(
"dir0" == di.
path() );
439 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala";
441 INFO_STR(
"\n\ntest04_dir_item: 50 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
442 REQUIRE(
"dir0" == di.
dirname() );
444 REQUIRE(
"dir0/lala" == di.
path() );
447 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala/.";
449 INFO_STR(
"\n\ntest04_dir_item: 51 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
450 REQUIRE(
"dir0" == di.
dirname() );
452 REQUIRE(
"dir0/lala" == di.
path() );
455 const std::string path1_ =
"./dir0/./dir1/./bbb/../.././lala/.";
457 INFO_STR(
"\n\ntest04_dir_item: 51 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
458 REQUIRE(
"dir0" == di.
dirname() );
460 REQUIRE(
"dir0/lala" == di.
path() );
463 const std::string path1_ =
"/./dir0/./dir1/./bbb/../.././lala/.";
465 INFO_STR(
"\n\ntest04_dir_item: 52 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
466 REQUIRE(
"/dir0" == di.
dirname() );
468 REQUIRE(
"/dir0/lala" == di.
path() );
472 const std::string path1_ =
"../../test_data/file_01_slink09R1.txt";
474 INFO_STR(
"\n\ntest04_dir_item: 60 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
475 REQUIRE(
"../../test_data" == di.
dirname() );
476 REQUIRE(
"file_01_slink09R1.txt" == di.
basename() );
477 REQUIRE( path1_ == di.
path() );
481 const std::string path1_ =
"../../../jaulib/test_data";
483 INFO_STR(
"\n\ntest04_dir_item: 61 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
484 REQUIRE(
"../../../jaulib" == di.
dirname() );
485 REQUIRE(
"test_data" == di.
basename() );
486 REQUIRE( path1_ == di.
path() );
490 const std::string path1_ =
"../../../../jaulib/test_data";
492 INFO_STR(
"\n\ntest04_dir_item: 62 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
493 REQUIRE(
"../../../../jaulib" == di.
dirname() );
494 REQUIRE(
"test_data" == di.
basename() );
495 REQUIRE( path1_ == di.
path() );
499 const std::string path1_ =
"././././jaulib/test_data";
501 INFO_STR(
"\n\ntest04_dir_item: 63 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
502 REQUIRE(
"jaulib" == di.
dirname() );
503 REQUIRE(
"test_data" == di.
basename() );
504 REQUIRE(
"jaulib/test_data" == di.
path() );
507 const std::string path1_ =
"a/././././jaulib/test_data";
509 INFO_STR(
"\n\ntest04_dir_item: 64 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
510 REQUIRE(
"a/jaulib" == di.
dirname() );
511 REQUIRE(
"test_data" == di.
basename() );
512 REQUIRE(
"a/jaulib/test_data" == di.
path() );
517 const std::string path1_ =
"/../lala";
519 INFO_STR(
"\n\ntest04_dir_item: 99 '"+path1_+
" -> "+di.
to_string()+
" -> '"+di.
path()+
"'\n");
520 REQUIRE(
"/.." == di.
dirname() );
522 REQUIRE(
"/../lala" == di.
path() );
528 INFO_STR(
"\n\ntest05_file_stat\n");
534 REQUIRE(
false == stats.
exists() );
540 REQUIRE(
false == stats.
exists() );
548 REQUIRE( !stats.
is_dir() );
551 REQUIRE( 15 == stats.
size() );
558 REQUIRE(
true == proot_stats.
exists() );
559 REQUIRE(
true == proot_stats.
is_dir() );
564 REQUIRE( stats.
exists() );
566 REQUIRE( !stats.
is_dir() );
569 REQUIRE( 15 == stats.
size() );
573 jau::fprintf_td(stdout,
"test05_file_stat: 12: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
574 REQUIRE( 0 == link_count );
575 REQUIRE( final_target == &stats );
579 REQUIRE( stats2.
exists() );
581 REQUIRE( !stats2.
is_dir() );
584 REQUIRE( 15 == stats2.
size() );
585 REQUIRE( stats == stats2 );
589 REQUIRE( stats2.
exists() );
591 REQUIRE( !stats2.
is_dir() );
594 REQUIRE( stats != stats2 );
601 REQUIRE( stats.
exists() );
603 REQUIRE( stats.
is_dir() );
606 REQUIRE( 0 == stats.
size() );
610 jau::fprintf_td(stdout,
"test05_file_stat: 13: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
611 REQUIRE( 0 == link_count );
612 REQUIRE( final_target == &stats );
618 REQUIRE( !stats.
exists() );
620 REQUIRE( !stats.
is_dir() );
623 REQUIRE( 0 == stats.
size() );
627 jau::fprintf_td(stdout,
"test05_file_stat: 14: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
628 REQUIRE( 0 == link_count );
629 REQUIRE( final_target == &stats );
635 INFO_STR(
"\n\ntest06_file_stat_symlinks\n");
638 REQUIRE(
true == proot_stats.
exists() );
639 REQUIRE(
true == proot_stats.
is_dir() );
644 REQUIRE( stats.
exists() );
646 REQUIRE( !stats.
is_dir() );
649 REQUIRE( 15 == stats.
size() );
656 REQUIRE( 1 == link_count );
657 REQUIRE( final_target != &stats );
658 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
662 REQUIRE(
nullptr != link_target );
664 REQUIRE( final_target == link_target );
665 REQUIRE( !link_target->
is_dir() );
666 REQUIRE( link_target->
is_file() );
667 REQUIRE( !link_target->
is_link() );
675 REQUIRE( stats.
exists() );
677 REQUIRE( !stats.
is_dir() );
680 REQUIRE( 20 < stats.
size() );
687 REQUIRE( 1 == link_count );
688 REQUIRE( final_target != &stats );
689 REQUIRE(
"/etc/fstab" == final_target->
path() );
693 REQUIRE(
nullptr != link_target );
695 REQUIRE( final_target == link_target );
696 REQUIRE( !link_target->
is_dir() );
697 REQUIRE( link_target->
is_file() );
698 REQUIRE( !link_target->
is_link() );
706 REQUIRE( stats.
exists() );
708 REQUIRE( !stats.
is_dir() );
711 REQUIRE( 15 == stats.
size() );
718 REQUIRE( 3 == link_count );
719 REQUIRE( final_target != &stats );
720 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
725 REQUIRE( final_target != link_target1 );
726 REQUIRE( proot_stats.
path()+
"/file_01_slink09R1.txt" == link_target1->
path() );
727 REQUIRE( 15 == link_target1->
size() );
728 REQUIRE( !link_target1->
is_dir() );
729 REQUIRE( link_target1->
is_file() );
730 REQUIRE( link_target1->
is_link() );
735 REQUIRE(
nullptr != link_target2 );
737 REQUIRE( final_target != link_target2 );
738 REQUIRE( link_target1 != link_target2 );
739 REQUIRE( proot_stats.
path()+
"/file_01_slink01.txt" == link_target2->
path() );
740 REQUIRE( 15 == link_target2->
size() );
741 REQUIRE( !link_target2->
is_dir() );
742 REQUIRE( link_target2->
is_file() );
743 REQUIRE( link_target2->
is_link() );
748 REQUIRE(
nullptr != link_target3 );
750 REQUIRE( final_target == link_target3 );
751 REQUIRE( link_target1 != link_target3 );
752 REQUIRE( link_target2 != link_target3 );
753 REQUIRE( 15 == link_target3->
size() );
754 REQUIRE( !link_target3->
is_dir() );
755 REQUIRE( link_target3->
is_file() );
756 REQUIRE( !link_target3->
is_link() );
765 REQUIRE( !stats.
exists() );
767 REQUIRE( !stats.
is_dir() );
770 REQUIRE( 0 == stats.
size() );
778 REQUIRE( 0 == link_count );
779 REQUIRE( final_target == &stats );
785 REQUIRE( !stats.
exists() );
787 REQUIRE( !stats.
is_dir() );
790 REQUIRE( 0 == stats.
size() );
798 REQUIRE( 0 == link_count );
799 REQUIRE( *final_target == stats );
800 REQUIRE( final_target == &stats );
805 jau::fprintf_td(stdout,
"test_file_stat_fd_item: expect '%s', fd %d, name_fd1 '%s', make_fd_link '%s'\n",
812 REQUIRE( stats.
exists() );
816 REQUIRE( !stats.
is_dir() );
820 REQUIRE( stats.
has_fd() );
821 REQUIRE( fd == stats.
fd() );
823 REQUIRE( 0 == stats.
size() );
827 if( !named_fd1.empty() ) {
829 jau::fprintf_td(stdout,
"test_file_stat_fd_item.2: expect '%s', fd %d, name_fd1 '%s'\n",
833 REQUIRE( stats.
exists() );
837 REQUIRE( !stats.
is_dir() );
841 REQUIRE( stats.
has_fd() );
842 REQUIRE( fd == stats.
fd() );
844 REQUIRE( 0 == stats.
size() );
848 if( !named_fd_link.empty() ) {
850 jau::fprintf_td(stdout,
"test_file_stat_fd_item.3: expect '%s', fd %d, make_fd_link '%s'\n",
854 REQUIRE( stats.
exists() );
858 REQUIRE( !stats.
is_dir() );
862 REQUIRE( stats.
has_fd() );
863 REQUIRE( fd == stats.
fd() );
865 REQUIRE( 0 == stats.
size() );
870 REQUIRE(
nullptr != final_target );
872 REQUIRE( 1 <= link_count );
873 REQUIRE( 2 >= link_count );
881 const std::string fd_stdin_1 =
"/dev/fd/0";
882 const std::string fd_stdout_1 =
"/dev/fd/1";
883 const std::string fd_stderr_1 =
"/dev/fd/2";
885 const std::string fd_stdin_l =
"/dev/stdin";
886 const std::string fd_stdout_l =
"/dev/stdout";
887 const std::string fd_stderr_l =
"/dev/stderr";
893 int fd = ::open(
"test07_file_stat_fd_tmp", O_CREAT|O_WRONLY|O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP );
900 REQUIRE( 0 == ::pipe(pipe_fds) );
903 ::close(pipe_fds[0]);
904 ::close(pipe_fds[1]);
909 static constexpr const char*
pipe_msg =
"Therefore I say unto you, Take no thought for your life, what ye shall eat, or what ye shall drink; nor yet for your body, what.";
918 REQUIRE( 0 == ::pipe(pipe_fds) );
919 ::pid_t pid = ::fork();
923 ::close(pipe_fds[0]);
924 const int new_stdout = pipe_fds[1];
929 if( !stats_stdout.
exists() || !stats_stdout.
has_fd() || new_stdout != stats_stdout.
fd() ) {
931 ::_exit(EXIT_FAILURE);
936 ::_exit(EXIT_FAILURE);
940 const size_t max_chunck = 64;
944 const size_t chunck_sz = std::min(max_chunck,
pipe_msg_len-sent);
955 ::close(pipe_fds[1]);
957 if( outfile.
fail() ) {
959 ::_exit(EXIT_FAILURE);
962 ::_exit(EXIT_SUCCESS);
964 }
else if( 0 < pid ) {
966 ::close(pipe_fds[1]);
967 const int new_stdin = pipe_fds[0];
972 REQUIRE( stats_stdin.
exists() );
976 REQUIRE( !stats_stdin.
is_dir() );
977 REQUIRE( !stats_stdin.
is_file() );
978 const bool fifo_or_char = stats_stdin.
is_fifo() || stats_stdin.
is_char();
979 REQUIRE(
true == fifo_or_char );
980 REQUIRE( stats_stdin.
has_fd() );
981 REQUIRE( new_stdin == stats_stdin.
fd() );
982 REQUIRE( 0 == stats_stdin.
size() );
987 REQUIRE( !infile.
fail() );
991 size_t total_read = 0;
993 while( infile.
good() && total_read <
sizeof(buffer) ) {
994 const size_t got = infile.
read(buffer+total_read,
sizeof(buffer)-total_read);
996 REQUIRE( !infile.
fail() );
1003 ::close(pipe_fds[0]);
1005 REQUIRE( !infile.
fail() );
1014 ::pid_t child_pid = ::waitpid(pid, &pid_status, 0);
1015 if( 0 > child_pid ) {
1016 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) failed: child_pid %d\n", pid, child_pid);
1017 REQUIRE_MSG(
"wait for child failed",
false);
1019 if( child_pid != pid ) {
1020 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated child_pid pid %d\n", pid, child_pid);
1021 REQUIRE(child_pid == pid);
1023 if( !WIFEXITED(pid_status) ) {
1024 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated abnormally child_pid %d, pid_status %d\n", pid, child_pid, pid_status);
1025 REQUIRE(
true == WIFEXITED(pid_status));
1027 if( EXIT_SUCCESS != WEXITSTATUS(pid_status) ) {
1028 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) exit with failure child_pid %d, exit_code %d\n", pid, child_pid, WEXITSTATUS(pid_status));
1029 REQUIRE(EXIT_SUCCESS == WEXITSTATUS(pid_status));
1034 jau::fprintf_td(stdout,
"fork failed %d, %s\n", errno, ::strerror(errno));
1035 REQUIRE_MSG(
"fork failed",
false );
1043 INFO_STR(
"\n\ntest10_mkdir\n");
1048 INFO_STR(
"root_stats.pre: "+root_stats.
to_string()+
"\n");
1049 REQUIRE( !root_stats.
exists() );
1051 REQUIRE( !root_stats.
is_dir() );
1052 REQUIRE( !root_stats.
is_file() );
1053 REQUIRE( !root_stats.
is_link() );
1058 INFO_STR(
"root_stats.post: "+root_stats.
to_string()+
"\n");
1059 REQUIRE( root_stats.
exists() );
1061 REQUIRE( root_stats.
is_dir() );
1062 REQUIRE( !root_stats.
is_file() );
1063 REQUIRE( !root_stats.
is_link() );
1072 INFO_STR(
"\n\ntest11_touch\n");
1073 const std::string file_01 =
temp_root+
"/data01.txt";
1074 const std::string file_02 =
temp_root+
"/data02.txt";
1079 REQUIRE( root_stats.
exists() );
1081 REQUIRE( root_stats.
is_dir() );
1082 REQUIRE( !root_stats.
is_file() );
1083 REQUIRE( !root_stats.
is_link() );
1102 REQUIRE( file_stats.
exists() );
1104 REQUIRE( !file_stats.
is_dir() );
1105 REQUIRE( file_stats.
is_file() );
1106 REQUIRE( !file_stats.
is_link() );
1108 REQUIRE( td_1s >= atime_td );
1111 REQUIRE( td_1s >= mtime_td );
1131 REQUIRE( td_1s >= atime_td );
1134 REQUIRE( td_1s >= mtime_td );
1151 REQUIRE( file_stats_post.
exists() );
1153 REQUIRE( !file_stats_post.
is_dir() );
1154 REQUIRE( file_stats_post.
is_file() );
1155 REQUIRE( !file_stats_post.
is_link() );
1157 REQUIRE( atime_set == file_stats_post.
atime() );
1160 REQUIRE( mtime_set == file_stats_post.
mtime() );
1170 INFO_STR(
"\n\ntest21_visit_error\n");
1174 INFO_STR(
"\n\ntest20_visit\n");
1176 std::string sub_dir1 =
temp_root+
"/sub1";
1177 std::string sub_dir2 =
temp_root+
"/sub2";
1178 std::string sub_dir3 =
temp_root+
"/sub1/sub3";
1202 stats_R_FSL_PDL.
add(element_stats);
1215 REQUIRE( 4 == stats_R_FSL_PDL.
dirs_real );
1229 stats_ptr->
add(element_stats);
1234 REQUIRE( stats_R_FSL_PDL == stats_R_FSL );
1241 INFO_STR(
"\n\ntest22_visit_symlinks\n");
1244 REQUIRE(
true == proot_stats.
exists() );
1255 stats.
add(element_stats);
1282 stats.
add(element_stats);
1312 stats.
add(element_stats);
1331 INFO_STR(
"\n\ntest30_copy_file2dir\n");
1334 REQUIRE(
true == root_orig_stats.
exists() );
1336 const std::string root_copy =
temp_root+
"_copy_test30";
1344 REQUIRE(
true == stats.
exists() );
1345 REQUIRE(
true == stats.
ok() );
1346 REQUIRE(
true == stats.
is_dir() );
1352 REQUIRE(
true == source1_stats.
exists() );
1353 REQUIRE(
true == source1_stats.
ok() );
1354 REQUIRE(
true == source1_stats.
is_file() );
1363 REQUIRE(
false == dest_stats.
exists() );
1369 REQUIRE(
true == dest_stats.
exists() );
1370 REQUIRE(
true == dest_stats.
ok() );
1371 REQUIRE(
true == dest_stats.
is_file() );
1372 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1373 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1383 REQUIRE(
true == dest_stats.
exists() );
1384 REQUIRE(
true == dest_stats.
ok() );
1385 REQUIRE(
true == dest_stats.
is_file() );
1399 REQUIRE(
true == dest_stats.
exists() );
1400 REQUIRE(
true == dest_stats.
ok() );
1401 REQUIRE(
true == dest_stats.
is_file() );
1402 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1403 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1409 REQUIRE(
true == dest_stats.
exists() );
1410 REQUIRE(
true == dest_stats.
ok() );
1411 REQUIRE(
true == dest_stats.
is_file() );
1412 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1413 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1422 INFO_STR(
"\n\ntest31_copy_file2file\n");
1425 REQUIRE(
true == root_orig_stats.
exists() );
1427 const std::string root_copy =
temp_root+
"_copy_test31";
1435 REQUIRE(
true == stats.
exists() );
1436 REQUIRE(
true == stats.
ok() );
1437 REQUIRE(
true == stats.
is_dir() );
1443 REQUIRE(
true == source1_stats.
exists() );
1444 REQUIRE(
true == source1_stats.
ok() );
1445 REQUIRE(
true == source1_stats.
is_file() );
1450 REQUIRE(
true == source2_stats.
exists() );
1451 REQUIRE(
true == source2_stats.
ok() );
1452 REQUIRE(
true == source2_stats.
is_file() );
1453 REQUIRE(
true == source2_stats.
is_link() );
1462 REQUIRE(
false == dest_stats.
exists() );
1464 REQUIRE(
true ==
jau::fs::copy(source1_stats.
path(), root_copy+
"/file_10.txt", copts) );
1469 REQUIRE(
true == dest_stats.
exists() );
1470 REQUIRE(
true == dest_stats.
ok() );
1471 REQUIRE(
true == dest_stats.
is_file() );
1472 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1473 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1483 REQUIRE(
true == dest_stats.
exists() );
1484 REQUIRE(
true == dest_stats.
ok() );
1485 REQUIRE(
true == dest_stats.
is_file() );
1487 REQUIRE(
false ==
jau::fs::copy(source1_stats.
path(), root_copy+
"/file_10.txt", copts) );
1500 REQUIRE(
true == dest_stats.
exists() );
1501 REQUIRE(
true == dest_stats.
ok() );
1502 REQUIRE(
true == dest_stats.
is_file() );
1503 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1504 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1506 REQUIRE(
true ==
jau::fs::copy(source2_stats.
path(), root_copy+
"/file_10.txt", copts) );
1511 REQUIRE(
true == dest_stats.
exists() );
1512 REQUIRE(
true == dest_stats.
ok() );
1513 REQUIRE(
true == dest_stats.
is_file() );
1514 REQUIRE(
false == dest_stats.
is_link() );
1515 REQUIRE( source2_stats.
size() == dest_stats.
size() );
1525 INFO_STR(
"\n\ntest40_copy_ext_r_p\n");
1528 REQUIRE(
true == root_orig_stats.
exists() );
1534 const std::string root_copy =
temp_root+
"_copy_test40";
1536 testxx_copy_r_p(
"test40_copy_ext_r_p", root_orig_stats, 0 , root_copy, copts,
false );
1541 INFO_STR(
"\n\ntest41_copy_ext_r_p_below\n");
1544 REQUIRE(
true == root_orig_stats.
exists() );
1550 const std::string root_copy_parent =
temp_root+
"_copy_test41_parent";
1553 testxx_copy_r_p(
"test41_copy_ext_r_p_below", root_orig_stats, 0 , root_copy_parent, copts,
false );
1558 INFO_STR(
"\n\ntest41_copy_ext_r_p_into\n");
1561 REQUIRE(
true == root_orig_stats.
exists() );
1568 const std::string root_copy =
temp_root+
"_copy_test42_into";
1571 testxx_copy_r_p(
"test42_copy_ext_r_p_into", root_orig_stats, 0 , root_copy, copts,
false );
1576 INFO_STR(
"\n\ntest43_copy_ext_r_p_over\n");
1579 REQUIRE(
true == root_orig_stats.
exists() );
1585 const std::string root_copy =
temp_root+
"_copy_test43_over";
1588 const std::string root_copy_sub = root_copy+
"/"+root_orig_stats.
item().
basename();
1590 testxx_copy_r_p(
"test43_copy_ext_r_p_over", root_orig_stats, 0 , root_copy, copts,
false );
1595 INFO_STR(
"\n\ntest49_copy_ext_r_p_vfat\n");
1599 if( !dest_fs_vfat_stats.
is_dir() ) {
1600 jau::fprintf_td(stdout,
"test49_copy_ext_r_p_vfat: Skipped, no vfat dest-dir %s\n", dest_fs_vfat_stats.
to_string().c_str());
1603 const std::string dest_vfat_parent =
dest_fs_vfat+
"/test49_data_sink";
1606 jau::fprintf_td(stdout,
"test49_copy_ext_r_p_vfat: Skipped, couldn't create vfat dest folder %s\n", dest_vfat_parent.c_str());
1612 REQUIRE(
true == root_orig_stats.
exists() );
1619 const std::string dest_vfat_dir = dest_vfat_parent+
"/"+
temp_root;
1620 testxx_copy_r_p(
"test49_copy_ext_r_p_vfat", root_orig_stats, 0 , dest_vfat_dir, copts,
true );
1626 INFO_STR(
"\n\ntest50_copy_ext_r_p_fsl\n");
1629 REQUIRE(
true == root_orig_stats.
exists() );
1631 const std::string root_copy =
temp_root+
"_copy_test50";
1643 REQUIRE(
true == root_copy_stats.
exists() );
1644 REQUIRE(
true == root_copy_stats.
ok() );
1645 REQUIRE(
true == root_copy_stats.
is_dir() );
1651 stats_ptr->
add(element_stats);
1665 REQUIRE(
true ==
jau::fs::visit(root_orig_stats, topts_orig, pv_orig) );
1666 REQUIRE(
true ==
jau::fs::visit(root_copy_stats, topts_copy, pv_copy) );
1668 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: copy %s, traverse_orig %s, traverse_copy %s\n",
1672 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: destination visitor stats\n%s\n", stats_copy.
to_string().c_str());
1697 const std::string root_copy_renamed =
temp_root+
"_copy_test50_renamed";
1702 REQUIRE(
false == root_copy_stats2.
exists() );
1705 REQUIRE(
true == root_copy_renamed_stats.
exists() );
1706 REQUIRE(
true == root_copy_renamed_stats.
ok() );
1707 REQUIRE(
true == root_copy_renamed_stats.
is_dir() );
1714 REQUIRE(
true ==
jau::fs::visit(root_copy_renamed_stats, topts_copy, pv_copy) );
void test06_file_stat_symlinks()
void test40_copy_ext_r_p()
void test22_visit_symlinks()
static void test_file_stat_fd_item(const jau::fs::fmode_t exp_type, const int fd, const std::string &named_fd1, const std::string &named_fd_link)
void test30_copy_file2dir()
static const size_t pipe_msg_count
void test50_copy_ext_r_p_fsl()
static const size_t pipe_msg_len
void test21_visit_error()
void test49_copy_ext_r_p_vfat()
void test31_copy_file2file()
void test43_copy_ext_r_p_over()
void test07_file_stat_fd()
void test42_copy_ext_r_p_into()
void test41_copy_ext_r_p_below()
static constexpr const char * pipe_msg
jau::fs::file_stats getTestDataImageFile(const std::string &test_exe_path) noexcept
const std::string temp_root
const std::string dest_fs_vfat
std::string getTestDataRelDir(const std::string &test_exe_path) noexcept
jau::fs::file_stats getTestDataDirStats(const std::string &test_exe_path) noexcept
const std::string project_root_ext
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 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.
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 file_stats * final_target(size_t *link_count=nullptr) const noexcept
Returns the final target element, either a pointer to this instance if not a symbolic-link or the fin...
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.
bool has(const field_t fields) const noexcept
Returns true if the given field_t fields were retrieved, otherwise false.
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.
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,...
std::string to_string() const noexcept
Returns a comprehensive string representation of this element.
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.
File based byte input stream, including named file descriptor.
std::string to_string() const noexcept override
void close() noexcept override
Close the stream if supported by the underlying mechanism.
size_t read(void *, size_t) noexcept override
Read from the source.
File based byte output stream, including named file descriptor.
void close() noexcept override
Close the stream if supported by the underlying mechanism.
size_t write(const void *, size_t) noexcept override
Write to the data sink.
std::string to_string() const noexcept override
bool is_open() const noexcept override
Checks if the stream has an associated file.
bool fail() const noexcept
Checks if an error has occurred.
bool good() const noexcept
Checks if no error nor eof() has occurred i.e.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr bool is_set(const E mask, const E bits) noexcept
bool mkdir(const std::string &path, const fmode_t mode=jau::fs::fmode_t::def_dir_prot, const bool verbose=false) noexcept
Create directory.
std::string to_named_fd(const int fd) noexcept
Returns platform dependent named file descriptor of given file descriptor, if supported.
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 /.
std::string get_cwd() noexcept
Return the current working directory or empty on failure.
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.
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 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.
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.
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().
jau::function< bool(traverse_event, const file_stats &, size_t)> path_visitor
path_visitor jau::FunctionDef definition
@ def_file_prot
Default file protection bit: Safe default: POSIX S_IRUSR | S_IWUSR | S_IRGRP or read_usr | write_usr ...
@ chr
Type: Entity is a character device, might be in combination with link.
@ file
Type: Entity is a file, might be in combination with link.
@ fifo
Type: Entity is a fifo/pipe, might be in combination with link.
@ def_dir_prot
Default directory protection bit: Safe default: POSIX S_IRWXU | S_IRGRP | S_IXGRP or rwx_usr | read_g...
@ ignore_symlink_errors
Ignore errors from erroneous symlinks, e.g.
@ verbose
Enable verbosity mode, show error messages on stderr.
@ follow_symlinks
Copy referenced symbolic linked files or directories instead of just the symbolic link with property ...
@ sync
Ensure data and meta-data file synchronization is performed via ::fsync() after asynchronous copy ope...
@ 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...
@ recursive
Traverse through directories, i.e.
@ 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,...
@ dir_check_entry
Call path_visitor at directory entry, allowing path_visitor to skip traversal of this directory if re...
@ dir_entry
Call path_visitor at directory entry.
@ dir_exit
Call path_visitor at directory exit.
@ recursive
Traverse through directories, i.e.
@ dir_check_entry
Visiting a directory on entry, see traverse_options::dir_check_entry.
fraction_timespec getWallClockTime() noexcept
Returns current wall-clock real-time since Unix Epoch 00:00:00 UTC on 1970-01-01.
jau::function< R(A...)> bind_capref(I *data_ptr, R(*func)(I *, A...)) noexcept
Bind given data by passing the captured reference (pointer) to the value and non-void function to an ...
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
void zero_bytes_sec(void *s, size_t n) noexcept __attrdecl_no_optimize__
Wrapper to ::explicit_bzero(), ::bzero() or ::memset(), whichever is available in that order.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
std::string to_string() const noexcept
Return simple string representation in seconds and nanoseconds.
std::string to_iso8601_string(bool space_separator=false, bool muteTime=false) const noexcept
Convenience string conversion interpreted since Unix Epoch in UTC to ISO 8601 YYYY-mm-ddTHH:MM:SS....
std::string to_string() const noexcept
int total_sym_links_not_existing
int total_sym_links_existing
void add(const jau::fs::file_stats &element_stats)
METHOD_AS_TEST_CASE(TestFileUtil01::test00_testfiles, "Test TestFileUtil01 - test00_testfiles")
static constexpr const bool _remove_target_test_dir
void testxx_copy_r_p(const std::string &title, const jau::fs::file_stats &source, const int source_added_dead_links, const std::string &dest, const jau::fs::copy_options copts, const bool dest_is_vfat)