32 #include <sys/types.h>
51 jau::fprintf_td(stdout,
"test00: 02: proot02.rel: %s\n", rel_project_root.c_str());
53 REQUIRE( proot_stats_01.
exists() );
54 REQUIRE( proot_stats_02.
exists() );
62 INFO_STR(
"\n\ntest01_cwd: cwd "+cwd+
"\n");
63 REQUIRE( 0 < cwd.size() );
64 const size_t idx = cwd.find(
"/jaulib");
66 REQUIRE( idx < cwd.size() );
67 REQUIRE( idx != std::string::npos );
75 const std::string pathname0 =
"/";
77 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
78 REQUIRE( 0 < pathname1.size() );
79 REQUIRE( pathname1 ==
"/" );
83 const std::string pathname0 =
"lala.txt";
85 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
86 REQUIRE( 0 < pathname1.size() );
87 REQUIRE( pathname1 ==
"." );
90 const std::string pathname0 =
"lala";
92 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
93 REQUIRE( 0 < pathname1.size() );
94 REQUIRE( pathname1 ==
"." );
97 const std::string pathname0 =
"lala/";
99 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
100 REQUIRE( 0 < pathname1.size() );
101 REQUIRE( pathname1 ==
"." );
105 const std::string pathname0 =
"/lala.txt";
107 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
108 REQUIRE( 0 < pathname1.size() );
109 REQUIRE( pathname1 ==
"/" );
112 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
114 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
115 REQUIRE( 0 < pathname1.size() );
116 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
119 const std::string pathname0 =
"blabla/jaulib/test/sub";
121 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
122 REQUIRE( 0 < pathname1.size() );
123 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
126 const std::string pathname0 =
"blabla/jaulib/test/";
128 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
129 REQUIRE( 0 < pathname1.size() );
130 REQUIRE( pathname1 ==
"blabla/jaulib" );
133 const std::string pathname0 =
"blabla/jaulib/test";
135 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
136 REQUIRE( 0 < pathname1.size() );
137 REQUIRE( pathname1 ==
"blabla/jaulib" );
143 const std::string pathname0 =
"/";
145 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
146 REQUIRE( 0 < pathname1.size() );
147 REQUIRE( pathname1 ==
"/" );
152 const std::string pathname0 =
"lala.txt";
154 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
155 REQUIRE( 0 < pathname1.size() );
156 REQUIRE( pathname1 ==
"lala.txt" );
160 const std::string pathname0 =
"lala";
162 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
163 REQUIRE( 0 < pathname1.size() );
164 REQUIRE( pathname1 ==
"lala" );
168 const std::string pathname0 =
"lala/";
170 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
171 REQUIRE( 0 < pathname1.size() );
172 REQUIRE( pathname1 ==
"lala" );
176 const std::string pathname0 =
"/lala.txt";
178 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
179 REQUIRE( 0 < pathname1.size() );
180 REQUIRE( pathname1 ==
"lala.txt" );
183 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
185 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
186 REQUIRE( 0 < pathname1.size() );
187 REQUIRE( pathname1 ==
"sub.txt" );
191 const std::string pathname0 =
"blabla/jaulib/test/";
193 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
194 REQUIRE( 0 < pathname1.size() );
195 REQUIRE( pathname1 ==
"test" );
199 const std::string pathname0 =
"blabla/jaulib/test";
201 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
202 REQUIRE( 0 < pathname1.size() );
203 REQUIRE( pathname1 ==
"test" );
212 jau::fprintf_td(stdout,
"test03b_absolute: 01: rel_project_root %s\n", rel_project_root.c_str());
215 REQUIRE(
true == proot_stats.
exists() );
216 REQUIRE(
true == proot_stats.
is_dir() );
218 std::string abs_project_root;
221 jau::fprintf_td(stdout,
"test03b_absolute: 02: %s\n", abs_project_root.c_str());
222 REQUIRE( 0 < abs_project_root.size() );
229 REQUIRE( stats.
exists() );
230 REQUIRE( stats.
is_dir() );
235 jau::fprintf_td(stdout,
"test03b_absolute: 03.0: %s\n", bname0.c_str());
236 jau::fprintf_td(stdout,
"test03b_absolute: 03.1: %s\n", bname1.c_str());
237 REQUIRE( bname0 == bname1 );
245 INFO_STR(
"\n\ntest04_dir_item: 00 "+di.
toString()+
" -> '"+di.
path()+
"'\n");
246 REQUIRE(
"." == di.
dirname() );
248 REQUIRE(
"." == di.
path() );
249 REQUIRE(
true == di.
empty() );
252 const std::string dirname_;
254 INFO_STR(
"\n\ntest04_dir_item: 01 '"+dirname_+
"' -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
255 REQUIRE(
"." == di.
dirname() );
257 REQUIRE(
"." == di.
path() );
258 REQUIRE(
true == di.
empty() );
261 const std::string dirname_(
".");
263 INFO_STR(
"\n\ntest04_dir_item: 02 '"+dirname_+
"' -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
264 REQUIRE(
"." == di.
dirname() );
266 REQUIRE(
"." == di.
path() );
267 REQUIRE(
false == di.
empty() );
270 const std::string dirname_(
"/");
272 INFO_STR(
"\n\ntest04_dir_item: 03 '"+dirname_+
"' -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
273 REQUIRE(
"/" == di.
dirname() );
275 REQUIRE(
"/" == di.
path() );
276 REQUIRE(
false == di.
empty() );
280 const std::string path1_ =
"lala";
282 INFO_STR(
"\n\ntest04_dir_item: 10 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
283 REQUIRE(
"." == di.
dirname() );
285 REQUIRE(
"lala" == di.
path() );
286 REQUIRE(
false == di.
empty() );
289 const std::string path1_ =
"lala/";
291 INFO_STR(
"\n\ntest04_dir_item: 11 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
292 REQUIRE(
"." == di.
dirname() );
294 REQUIRE(
"lala" == di.
path() );
295 REQUIRE(
false == di.
empty() );
299 const std::string path1_ =
"/lala";
301 INFO_STR(
"\n\ntest04_dir_item: 12 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
302 REQUIRE(
"/" == di.
dirname() );
304 REQUIRE(
"/lala" == di.
path() );
305 REQUIRE(
false == di.
empty() );
309 const std::string path1_ =
"dir0/lala";
311 INFO_STR(
"\n\ntest04_dir_item: 20 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
312 REQUIRE(
"dir0" == di.
dirname() );
314 REQUIRE(
"dir0/lala" == di.
path() );
317 const std::string path1_ =
"dir0/lala/";
319 INFO_STR(
"\n\ntest04_dir_item: 21 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
320 REQUIRE(
"dir0" == di.
dirname() );
322 REQUIRE(
"dir0/lala" == di.
path() );
325 const std::string path1_ =
"/dir0/lala";
327 INFO_STR(
"\n\ntest04_dir_item: 22 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
328 REQUIRE(
"/dir0" == di.
dirname() );
330 REQUIRE(
"/dir0/lala" == di.
path() );
333 const std::string path1_ =
"/dir0/lala/";
335 INFO_STR(
"\n\ntest04_dir_item: 23 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
336 REQUIRE(
"/dir0" == di.
dirname() );
338 REQUIRE(
"/dir0/lala" == di.
path() );
343 const std::string path1_ =
"/dir0/../lala";
345 INFO_STR(
"\n\ntest04_dir_item: 30 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
346 REQUIRE(
"/" == di.
dirname() );
348 REQUIRE(
"/lala" == di.
path() );
351 const std::string path1_ =
"dir0/../lala";
353 INFO_STR(
"\n\ntest04_dir_item: 31 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
354 REQUIRE(
"." == di.
dirname() );
356 REQUIRE(
"lala" == di.
path() );
359 const std::string path1_ =
"../../lala";
361 INFO_STR(
"\n\ntest04_dir_item: 32 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
362 REQUIRE(
"../.." == di.
dirname() );
364 REQUIRE(
"../../lala" == di.
path() );
367 const std::string path1_ =
"./../lala";
369 INFO_STR(
"\n\ntest04_dir_item: 33 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
370 REQUIRE(
".." == di.
dirname() );
372 REQUIRE(
"../lala" == di.
path() );
375 const std::string path1_ =
"dir0/../../lala";
377 INFO_STR(
"\n\ntest04_dir_item: 34 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
378 REQUIRE(
".." == di.
dirname() );
380 REQUIRE(
"../lala" == di.
path() );
384 const std::string path1_ =
"dir0/dir1/../lala";
386 INFO_STR(
"\n\ntest04_dir_item: 40 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
387 REQUIRE(
"dir0" == di.
dirname() );
389 REQUIRE(
"dir0/lala" == di.
path() );
392 const std::string path1_ =
"/dir0/dir1/../lala/";
394 INFO_STR(
"\n\ntest04_dir_item: 41 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
395 REQUIRE(
"/dir0" == di.
dirname() );
397 REQUIRE(
"/dir0/lala" == di.
path() );
400 const std::string path1_ =
"dir0/dir1/../bbb/ccc/../lala";
402 INFO_STR(
"\n\ntest04_dir_item: 42 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
403 REQUIRE(
"dir0/bbb" == di.
dirname() );
405 REQUIRE(
"dir0/bbb/lala" == di.
path() );
408 const std::string path1_ =
"dir0/dir1/bbb/../../lala";
410 INFO_STR(
"\n\ntest04_dir_item: 43 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
411 REQUIRE(
"dir0" == di.
dirname() );
413 REQUIRE(
"dir0/lala" == di.
path() );
416 const std::string path1_ =
"dir0/dir1/bbb/../../../lala";
418 INFO_STR(
"\n\ntest04_dir_item: 44 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
419 REQUIRE(
"." == di.
dirname() );
421 REQUIRE(
"lala" == di.
path() );
424 const std::string path1_ =
"dir0/dir1/bbb/../../../../lala";
426 INFO_STR(
"\n\ntest04_dir_item: 45 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
427 REQUIRE(
".." == di.
dirname() );
429 REQUIRE(
"../lala" == di.
path() );
432 const std::string path1_ =
"dir0/dir1/bbb/../../lala/..";
434 INFO_STR(
"\n\ntest04_dir_item: 46 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
435 REQUIRE(
"." == di.
dirname() );
437 REQUIRE(
"dir0" == di.
path() );
440 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala";
442 INFO_STR(
"\n\ntest04_dir_item: 50 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
443 REQUIRE(
"dir0" == di.
dirname() );
445 REQUIRE(
"dir0/lala" == di.
path() );
448 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala/.";
450 INFO_STR(
"\n\ntest04_dir_item: 51 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
451 REQUIRE(
"dir0" == di.
dirname() );
453 REQUIRE(
"dir0/lala" == di.
path() );
456 const std::string path1_ =
"./dir0/./dir1/./bbb/../.././lala/.";
458 INFO_STR(
"\n\ntest04_dir_item: 51 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
459 REQUIRE(
"dir0" == di.
dirname() );
461 REQUIRE(
"dir0/lala" == di.
path() );
464 const std::string path1_ =
"/./dir0/./dir1/./bbb/../.././lala/.";
466 INFO_STR(
"\n\ntest04_dir_item: 52 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
467 REQUIRE(
"/dir0" == di.
dirname() );
469 REQUIRE(
"/dir0/lala" == di.
path() );
473 const std::string path1_ =
"../../test_data/file_01_slink09R1.txt";
475 INFO_STR(
"\n\ntest04_dir_item: 60 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
476 REQUIRE(
"../../test_data" == di.
dirname() );
477 REQUIRE(
"file_01_slink09R1.txt" == di.
basename() );
478 REQUIRE( path1_ == di.
path() );
482 const std::string path1_ =
"../../../jaulib/test_data";
484 INFO_STR(
"\n\ntest04_dir_item: 61 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
485 REQUIRE(
"../../../jaulib" == di.
dirname() );
486 REQUIRE(
"test_data" == di.
basename() );
487 REQUIRE( path1_ == di.
path() );
491 const std::string path1_ =
"../../../../jaulib/test_data";
493 INFO_STR(
"\n\ntest04_dir_item: 62 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
494 REQUIRE(
"../../../../jaulib" == di.
dirname() );
495 REQUIRE(
"test_data" == di.
basename() );
496 REQUIRE( path1_ == di.
path() );
500 const std::string path1_ =
"././././jaulib/test_data";
502 INFO_STR(
"\n\ntest04_dir_item: 63 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
503 REQUIRE(
"jaulib" == di.
dirname() );
504 REQUIRE(
"test_data" == di.
basename() );
505 REQUIRE(
"jaulib/test_data" == di.
path() );
508 const std::string path1_ =
"a/././././jaulib/test_data";
510 INFO_STR(
"\n\ntest04_dir_item: 64 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
511 REQUIRE(
"a/jaulib" == di.
dirname() );
512 REQUIRE(
"test_data" == di.
basename() );
513 REQUIRE(
"a/jaulib/test_data" == di.
path() );
518 const std::string path1_ =
"/../lala";
520 INFO_STR(
"\n\ntest04_dir_item: 99 '"+path1_+
" -> "+di.
toString()+
" -> '"+di.
path()+
"'\n");
521 REQUIRE(
"/.." == di.
dirname() );
523 REQUIRE(
"/../lala" == di.
path() );
529 INFO_STR(
"\n\ntest05_file_stat\n");
535 REQUIRE(
false == stats.
exists() );
541 REQUIRE(
false == stats.
exists() );
549 REQUIRE( !stats.
is_dir() );
552 REQUIRE( 15 == stats.
size() );
559 REQUIRE(
true == proot_stats.
exists() );
560 REQUIRE(
true == proot_stats.
is_dir() );
565 REQUIRE( stats.
exists() );
567 REQUIRE( !stats.
is_dir() );
570 REQUIRE( 15 == stats.
size() );
574 jau::fprintf_td(stdout,
"test05_file_stat: 12: final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
575 REQUIRE( 0 == link_count );
576 REQUIRE( final_target == &stats );
580 REQUIRE( stats2.
exists() );
582 REQUIRE( !stats2.
is_dir() );
585 REQUIRE( 15 == stats2.
size() );
586 REQUIRE( stats == stats2 );
590 REQUIRE( stats2.
exists() );
592 REQUIRE( !stats2.
is_dir() );
595 REQUIRE( stats != stats2 );
602 REQUIRE( stats.
exists() );
604 REQUIRE( stats.
is_dir() );
607 REQUIRE( 0 == stats.
size() );
611 jau::fprintf_td(stdout,
"test05_file_stat: 13: final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
612 REQUIRE( 0 == link_count );
613 REQUIRE( final_target == &stats );
619 REQUIRE( !stats.
exists() );
621 REQUIRE( !stats.
is_dir() );
624 REQUIRE( 0 == stats.
size() );
628 jau::fprintf_td(stdout,
"test05_file_stat: 14: final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
629 REQUIRE( 0 == link_count );
630 REQUIRE( final_target == &stats );
636 INFO_STR(
"\n\ntest06_file_stat_symlinks\n");
639 REQUIRE(
true == proot_stats.
exists() );
640 REQUIRE(
true == proot_stats.
is_dir() );
645 REQUIRE( stats.
exists() );
647 REQUIRE( !stats.
is_dir() );
650 REQUIRE( 15 == stats.
size() );
656 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
657 REQUIRE( 1 == link_count );
658 REQUIRE( final_target != &stats );
659 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
663 REQUIRE(
nullptr != link_target );
665 REQUIRE( final_target == link_target );
666 REQUIRE( !link_target->
is_dir() );
667 REQUIRE( link_target->
is_file() );
668 REQUIRE( !link_target->
is_link() );
676 REQUIRE( stats.
exists() );
678 REQUIRE( !stats.
is_dir() );
681 REQUIRE( 20 < stats.
size() );
687 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
688 REQUIRE( 1 == link_count );
689 REQUIRE( final_target != &stats );
690 REQUIRE(
"/etc/fstab" == final_target->
path() );
694 REQUIRE(
nullptr != link_target );
696 REQUIRE( final_target == link_target );
697 REQUIRE( !link_target->
is_dir() );
698 REQUIRE( link_target->
is_file() );
699 REQUIRE( !link_target->
is_link() );
707 REQUIRE( stats.
exists() );
709 REQUIRE( !stats.
is_dir() );
712 REQUIRE( 15 == stats.
size() );
718 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
719 REQUIRE( 3 == link_count );
720 REQUIRE( final_target != &stats );
721 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
726 REQUIRE( final_target != link_target1 );
727 REQUIRE( proot_stats.
path()+
"/file_01_slink09R1.txt" == link_target1->
path() );
728 REQUIRE( 15 == link_target1->
size() );
729 REQUIRE( !link_target1->
is_dir() );
730 REQUIRE( link_target1->
is_file() );
731 REQUIRE( link_target1->
is_link() );
736 REQUIRE(
nullptr != link_target2 );
738 REQUIRE( final_target != link_target2 );
739 REQUIRE( link_target1 != link_target2 );
740 REQUIRE( proot_stats.
path()+
"/file_01_slink01.txt" == link_target2->
path() );
741 REQUIRE( 15 == link_target2->
size() );
742 REQUIRE( !link_target2->
is_dir() );
743 REQUIRE( link_target2->
is_file() );
744 REQUIRE( link_target2->
is_link() );
749 REQUIRE(
nullptr != link_target3 );
751 REQUIRE( final_target == link_target3 );
752 REQUIRE( link_target1 != link_target3 );
753 REQUIRE( link_target2 != link_target3 );
754 REQUIRE( 15 == link_target3->
size() );
755 REQUIRE( !link_target3->
is_dir() );
756 REQUIRE( link_target3->
is_file() );
757 REQUIRE( !link_target3->
is_link() );
766 REQUIRE( !stats.
exists() );
768 REQUIRE( !stats.
is_dir() );
771 REQUIRE( 0 == stats.
size() );
778 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
779 REQUIRE( 0 == link_count );
780 REQUIRE( final_target == &stats );
786 REQUIRE( !stats.
exists() );
788 REQUIRE( !stats.
is_dir() );
791 REQUIRE( 0 == stats.
size() );
798 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
799 REQUIRE( 0 == link_count );
800 REQUIRE( *final_target == stats );
801 REQUIRE( final_target == &stats );
806 jau::fprintf_td(stdout,
"test_file_stat_fd_item: expect '%s', fd %d, name_fd1 '%s', make_fd_link '%s'\n",
813 REQUIRE( stats.
exists() );
817 REQUIRE( !stats.
is_dir() );
821 REQUIRE( stats.
has_fd() );
822 REQUIRE( fd == stats.
fd() );
824 REQUIRE( 0 == stats.
size() );
828 if( !named_fd1.empty() ) {
830 jau::fprintf_td(stdout,
"test_file_stat_fd_item.2: expect '%s', fd %d, name_fd1 '%s'\n",
834 REQUIRE( stats.
exists() );
838 REQUIRE( !stats.
is_dir() );
842 REQUIRE( stats.
has_fd() );
843 REQUIRE( fd == stats.
fd() );
845 REQUIRE( 0 == stats.
size() );
849 if( !named_fd_link.empty() ) {
851 jau::fprintf_td(stdout,
"test_file_stat_fd_item.3: expect '%s', fd %d, make_fd_link '%s'\n",
855 REQUIRE( stats.
exists() );
859 REQUIRE( !stats.
is_dir() );
863 REQUIRE( stats.
has_fd() );
864 REQUIRE( fd == stats.
fd() );
866 REQUIRE( 0 == stats.
size() );
871 REQUIRE(
nullptr != final_target );
872 jau::fprintf_td(stdout,
"- final_target (%zu link count): %s\n", link_count, final_target->
toString().c_str());
873 REQUIRE( 1 <= link_count );
874 REQUIRE( 2 >= link_count );
882 const std::string fd_stdin_1 =
"/dev/fd/0";
883 const std::string fd_stdout_1 =
"/dev/fd/1";
884 const std::string fd_stderr_1 =
"/dev/fd/2";
886 const std::string fd_stdin_l =
"/dev/stdin";
887 const std::string fd_stdout_l =
"/dev/stdout";
888 const std::string fd_stderr_l =
"/dev/stderr";
894 int fd = ::open(
"test07_file_stat_fd_tmp", O_CREAT|O_WRONLY|O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP );
901 REQUIRE( 0 == ::pipe(pipe_fds) );
904 ::close(pipe_fds[0]);
905 ::close(pipe_fds[1]);
910 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.";
919 REQUIRE( 0 == ::pipe(pipe_fds) );
920 ::pid_t pid = ::fork();
924 ::close(pipe_fds[0]);
925 const int new_stdout = pipe_fds[1];
930 if( !stats_stdout.
exists() || !stats_stdout.
has_fd() || new_stdout != stats_stdout.
fd() ) {
932 ::_exit(EXIT_FAILURE);
937 ::_exit(EXIT_FAILURE);
941 const size_t max_chunck = 64;
945 const size_t chunck_sz = std::min(max_chunck,
pipe_msg_len-sent);
956 ::close(pipe_fds[1]);
958 if( outfile.
fail() ) {
960 ::_exit(EXIT_FAILURE);
963 ::_exit(EXIT_SUCCESS);
965 }
else if( 0 < pid ) {
967 ::close(pipe_fds[1]);
968 const int new_stdin = pipe_fds[0];
973 REQUIRE( stats_stdin.
exists() );
977 REQUIRE( !stats_stdin.
is_dir() );
978 REQUIRE( !stats_stdin.
is_file() );
979 const bool fifo_or_char = stats_stdin.
is_fifo() || stats_stdin.
is_char();
980 REQUIRE(
true == fifo_or_char );
981 REQUIRE( stats_stdin.
has_fd() );
982 REQUIRE( new_stdin == stats_stdin.
fd() );
983 REQUIRE( 0 == stats_stdin.
size() );
988 REQUIRE( !infile.
fail() );
992 size_t total_read = 0;
994 while( infile.
good() && total_read <
sizeof(buffer) ) {
995 const size_t got = infile.
read(buffer+total_read,
sizeof(buffer)-total_read);
997 REQUIRE( !infile.
fail() );
1004 ::close(pipe_fds[0]);
1006 REQUIRE( !infile.
fail() );
1015 ::pid_t child_pid = ::waitpid(pid, &pid_status, 0);
1016 if( 0 > child_pid ) {
1017 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) failed: child_pid %d\n", pid, child_pid);
1018 REQUIRE_MSG(
"wait for child failed",
false);
1020 if( child_pid != pid ) {
1021 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated child_pid pid %d\n", pid, child_pid);
1022 REQUIRE(child_pid == pid);
1024 if( !WIFEXITED(pid_status) ) {
1025 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated abnormally child_pid %d, pid_status %d\n", pid, child_pid, pid_status);
1026 REQUIRE(
true == WIFEXITED(pid_status));
1028 if( EXIT_SUCCESS != WEXITSTATUS(pid_status) ) {
1029 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) exit with failure child_pid %d, exit_code %d\n", pid, child_pid, WEXITSTATUS(pid_status));
1030 REQUIRE(EXIT_SUCCESS == WEXITSTATUS(pid_status));
1035 jau::fprintf_td(stdout,
"fork failed %d, %s\n", errno, ::strerror(errno));
1036 REQUIRE_MSG(
"fork failed",
false );
1044 INFO_STR(
"\n\ntest10_mkdir\n");
1049 INFO_STR(
"root_stats.pre: "+root_stats.
toString()+
"\n");
1050 REQUIRE( !root_stats.
exists() );
1052 REQUIRE( !root_stats.
is_dir() );
1053 REQUIRE( !root_stats.
is_file() );
1054 REQUIRE( !root_stats.
is_link() );
1059 INFO_STR(
"root_stats.post: "+root_stats.
toString()+
"\n");
1060 REQUIRE( root_stats.
exists() );
1062 REQUIRE( root_stats.
is_dir() );
1063 REQUIRE( !root_stats.
is_file() );
1064 REQUIRE( !root_stats.
is_link() );
1073 INFO_STR(
"\n\ntest11_touch\n");
1074 const std::string file_01 =
temp_root+
"/data01.txt";
1075 const std::string file_02 =
temp_root+
"/data02.txt";
1080 REQUIRE( root_stats.
exists() );
1082 REQUIRE( root_stats.
is_dir() );
1083 REQUIRE( !root_stats.
is_file() );
1084 REQUIRE( !root_stats.
is_link() );
1103 REQUIRE( file_stats.
exists() );
1105 REQUIRE( !file_stats.
is_dir() );
1106 REQUIRE( file_stats.
is_file() );
1107 REQUIRE( !file_stats.
is_link() );
1109 REQUIRE( td_1s >= atime_td );
1112 REQUIRE( td_1s >= mtime_td );
1132 REQUIRE( td_1s >= atime_td );
1135 REQUIRE( td_1s >= mtime_td );
1152 REQUIRE( file_stats_post.
exists() );
1154 REQUIRE( !file_stats_post.
is_dir() );
1155 REQUIRE( file_stats_post.
is_file() );
1156 REQUIRE( !file_stats_post.
is_link() );
1158 REQUIRE( atime_set == file_stats_post.
atime() );
1161 REQUIRE( mtime_set == file_stats_post.
mtime() );
1171 INFO_STR(
"\n\ntest21_visit_error\n");
1175 INFO_STR(
"\n\ntest20_visit\n");
1177 std::string sub_dir1 =
temp_root+
"/sub1";
1178 std::string sub_dir2 =
temp_root+
"/sub2";
1179 std::string sub_dir3 =
temp_root+
"/sub1/sub3";
1203 stats_R_FSL_PDL.
add(element_stats);
1216 REQUIRE( 4 == stats_R_FSL_PDL.
dirs_real );
1230 stats_ptr->
add(element_stats);
1235 REQUIRE( stats_R_FSL_PDL == stats_R_FSL );
1242 INFO_STR(
"\n\ntest22_visit_symlinks\n");
1245 REQUIRE(
true == proot_stats.
exists() );
1256 stats.
add(element_stats);
1283 stats.
add(element_stats);
1313 stats.
add(element_stats);
1332 INFO_STR(
"\n\ntest30_copy_file2dir\n");
1335 REQUIRE(
true == root_orig_stats.
exists() );
1337 const std::string root_copy =
temp_root+
"_copy_test30";
1345 REQUIRE(
true == stats.
exists() );
1346 REQUIRE(
true == stats.
ok() );
1347 REQUIRE(
true == stats.
is_dir() );
1353 REQUIRE(
true == source1_stats.
exists() );
1354 REQUIRE(
true == source1_stats.
ok() );
1355 REQUIRE(
true == source1_stats.
is_file() );
1364 REQUIRE(
false == dest_stats.
exists() );
1370 REQUIRE(
true == dest_stats.
exists() );
1371 REQUIRE(
true == dest_stats.
ok() );
1372 REQUIRE(
true == dest_stats.
is_file() );
1373 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1374 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1384 REQUIRE(
true == dest_stats.
exists() );
1385 REQUIRE(
true == dest_stats.
ok() );
1386 REQUIRE(
true == dest_stats.
is_file() );
1400 REQUIRE(
true == dest_stats.
exists() );
1401 REQUIRE(
true == dest_stats.
ok() );
1402 REQUIRE(
true == dest_stats.
is_file() );
1403 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1404 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1410 REQUIRE(
true == dest_stats.
exists() );
1411 REQUIRE(
true == dest_stats.
ok() );
1412 REQUIRE(
true == dest_stats.
is_file() );
1413 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1414 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1423 INFO_STR(
"\n\ntest31_copy_file2file\n");
1426 REQUIRE(
true == root_orig_stats.
exists() );
1428 const std::string root_copy =
temp_root+
"_copy_test31";
1436 REQUIRE(
true == stats.
exists() );
1437 REQUIRE(
true == stats.
ok() );
1438 REQUIRE(
true == stats.
is_dir() );
1444 REQUIRE(
true == source1_stats.
exists() );
1445 REQUIRE(
true == source1_stats.
ok() );
1446 REQUIRE(
true == source1_stats.
is_file() );
1451 REQUIRE(
true == source2_stats.
exists() );
1452 REQUIRE(
true == source2_stats.
ok() );
1453 REQUIRE(
true == source2_stats.
is_file() );
1454 REQUIRE(
true == source2_stats.
is_link() );
1463 REQUIRE(
false == dest_stats.
exists() );
1470 REQUIRE(
true == dest_stats.
exists() );
1471 REQUIRE(
true == dest_stats.
ok() );
1472 REQUIRE(
true == dest_stats.
is_file() );
1473 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1474 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1484 REQUIRE(
true == dest_stats.
exists() );
1485 REQUIRE(
true == dest_stats.
ok() );
1486 REQUIRE(
true == dest_stats.
is_file() );
1501 REQUIRE(
true == dest_stats.
exists() );
1502 REQUIRE(
true == dest_stats.
ok() );
1503 REQUIRE(
true == dest_stats.
is_file() );
1504 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1505 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1512 REQUIRE(
true == dest_stats.
exists() );
1513 REQUIRE(
true == dest_stats.
ok() );
1514 REQUIRE(
true == dest_stats.
is_file() );
1515 REQUIRE(
false == dest_stats.
is_link() );
1516 REQUIRE( source2_stats.
size() == dest_stats.
size() );
1526 INFO_STR(
"\n\ntest40_copy_ext_r_p\n");
1529 REQUIRE(
true == root_orig_stats.
exists() );
1535 const std::string root_copy =
temp_root+
"_copy_test40";
1537 testxx_copy_r_p(
"test40_copy_ext_r_p", root_orig_stats, 0 , root_copy, copts,
false );
1542 INFO_STR(
"\n\ntest41_copy_ext_r_p_below\n");
1545 REQUIRE(
true == root_orig_stats.
exists() );
1551 const std::string root_copy_parent =
temp_root+
"_copy_test41_parent";
1554 testxx_copy_r_p(
"test41_copy_ext_r_p_below", root_orig_stats, 0 , root_copy_parent, copts,
false );
1559 INFO_STR(
"\n\ntest41_copy_ext_r_p_into\n");
1562 REQUIRE(
true == root_orig_stats.
exists() );
1569 const std::string root_copy =
temp_root+
"_copy_test42_into";
1572 testxx_copy_r_p(
"test42_copy_ext_r_p_into", root_orig_stats, 0 , root_copy, copts,
false );
1577 INFO_STR(
"\n\ntest43_copy_ext_r_p_over\n");
1580 REQUIRE(
true == root_orig_stats.
exists() );
1586 const std::string root_copy =
temp_root+
"_copy_test43_over";
1589 const std::string root_copy_sub = root_copy+
"/"+root_orig_stats.
item().
basename();
1591 testxx_copy_r_p(
"test43_copy_ext_r_p_over", root_orig_stats, 0 , root_copy, copts,
false );
1596 INFO_STR(
"\n\ntest49_copy_ext_r_p_vfat\n");
1600 if( !dest_fs_vfat_stats.
is_dir() ) {
1601 jau::fprintf_td(stdout,
"test49_copy_ext_r_p_vfat: Skipped, no vfat dest-dir %s\n", dest_fs_vfat_stats.
toString().c_str());
1604 const std::string dest_vfat_parent =
dest_fs_vfat+
"/test49_data_sink";
1607 jau::fprintf_td(stdout,
"test49_copy_ext_r_p_vfat: Skipped, couldn't create vfat dest folder %s\n", dest_vfat_parent.c_str());
1613 REQUIRE(
true == root_orig_stats.
exists() );
1620 const std::string dest_vfat_dir = dest_vfat_parent+
"/"+
temp_root;
1621 testxx_copy_r_p(
"test49_copy_ext_r_p_vfat", root_orig_stats, 0 , dest_vfat_dir, copts,
true );
1627 INFO_STR(
"\n\ntest50_copy_ext_r_p_fsl\n");
1630 REQUIRE(
true == root_orig_stats.
exists() );
1632 const std::string root_copy =
temp_root+
"_copy_test50";
1644 REQUIRE(
true == root_copy_stats.
exists() );
1645 REQUIRE(
true == root_copy_stats.
ok() );
1646 REQUIRE(
true == root_copy_stats.
is_dir() );
1652 stats_ptr->
add(element_stats);
1669 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: copy %s, traverse_orig %s, traverse_copy %s\n",
1673 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: destination visitor stats\n%s\n", stats_copy.
toString().c_str());
1698 const std::string root_copy_renamed =
temp_root+
"_copy_test50_renamed";
1703 REQUIRE(
false == root_copy_stats2.
exists() );
1706 REQUIRE(
true == root_copy_renamed_stats.
exists() );
1707 REQUIRE(
true == root_copy_renamed_stats.
ok() );
1708 REQUIRE(
true == root_copy_renamed_stats.
is_dir() );
1719 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: renamed: visitor stats\n%s\n", stats_copy.
toString().c_str());
void test06_file_stat_symlinks()
void test40_copy_ext_r_p()
void test22_visit_symlinks()
static void test_file_stat_fd_item(const jau::io::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
const std::string temp_root
jau::io::fs::file_stats getTestDataDirStats(const std::string &test_exe_path) noexcept
jau::io::fs::file_stats getTestDataImageFile(const std::string &test_exe_path) noexcept
const std::string dest_fs_vfat
std::string getTestDataRelDir(const std::string &test_exe_path) noexcept
const std::string project_root_ext
File based byte input stream, including named file descriptor.
void close() noexcept override
Close the stream if supported by the underlying mechanism.
bool isOpen() const noexcept override
Checks if the stream has an associated file.
size_t write(const void *, size_t) noexcept override
Write to the data sink.
std::string toString() const noexcept override
size_t read(void *, size_t) noexcept override
Read from the source.
bool fail() const noexcept
Checks if an error has occurred.
bool good() const noexcept
Checks if no error nor eof() has occurred i.e.
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 & dirname() const noexcept
Returns the dirname, shall not be empty and denotes .
const std::string & basename() const noexcept
Return the basename, shall not be empty nor contain a dirname.
bool empty() const noexcept
Returns true if bot, dirname() and basename() refer to .
std::string toString() const noexcept
Returns a comprehensive string representation of this item.
Platform agnostic representation of POSIX ::lstat() and ::stat() for a given pathname.
fmode_t mode() const noexcept
Returns the fmode_t, file type and mode.
constexpr bool is_dir() const noexcept
Returns true if entity is a directory, might be in combination with is_link().
constexpr bool is_file() const noexcept
Returns true if entity is a file, might be in combination with is_link().
uint64_t size() const noexcept
Returns the size in bytes of this element if is_file(), otherwise zero.
const fraction_timespec & mtime() const noexcept
Returns the last modification time of this element since Unix Epoch.
const std::shared_ptr< file_stats > & link_target() const noexcept
Returns the link-target this symbolic-link points to if instance is a symbolic-link,...
std::string path() const noexcept
Returns the unix path representation.
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 ok() const noexcept
Returns true if no error occurred.
const fraction_timespec & btime() const noexcept
Returns the birth time of this element since Unix Epoch, i.e.
const dir_item & item() const noexcept
Returns the dir_item.
bool has(const field_t fields) const noexcept
Returns true if the given field_t fields were retrieved, otherwise false.
fmode_t prot_mode() const noexcept
Returns the POSIX protection bit portion of fmode_t, i.e.
constexpr bool has_access() const noexcept
Returns true if entity allows access to user, exclusive bit.
constexpr bool is_char() const noexcept
Returns true if entity is a character device, might be in combination with is_link().
constexpr bool is_socket() const noexcept
Returns true if entity is a socket, might be in combination with is_link().
fmode_t type_mode() const noexcept
Returns the type bit portion of fmode_t, i.e.
constexpr bool is_fifo() const noexcept
Returns true if entity is a fifo/pipe, might be in combination with is_link().
constexpr bool is_block() const noexcept
Returns true if entity is a block device, might be in combination with is_link().
std::string toString() const noexcept
Returns a comprehensive string representation of this element.
constexpr bool is_link() const noexcept
Returns true if entity is a symbolic link, might be in combination with is_file(),...
int fd() const noexcept
Returns the file descriptor if has_fd(), otherwise -1 for no file descriptor.
constexpr field_t fields() const noexcept
Returns the retrieved field_t fields.
constexpr bool exists() const noexcept
Returns true if entity does not exist, exclusive bit.
const fraction_timespec & atime() const noexcept
Returns the last access time of this element since Unix Epoch.
constexpr bool has_fd() const noexcept
Returns true if entity has a file descriptor.
const std::shared_ptr< std::string > & link_target_path() const noexcept
Returns the stored link-target path this symbolic-link points to if instance is a symbolic-link,...
constexpr bool is_set(const E mask, const E bits) noexcept
std::string absolute(const std::string_view &relpath) noexcept
Returns the absolute path of given relpath if existing, otherwise an empty string.
traverse_event
Filesystem traverse event used to call path_visitor for path elements from visit().
std::string basename(const std::string_view &path) noexcept
Return stripped leading directory components from given path separated by /.
bool visit(const std::string &path, const traverse_options topts, const path_visitor &visitor, std::vector< int > *dirfds=nullptr) noexcept
Visit element(s) of a given path, see traverse_options for detailed settings.
std::string dirname(const std::string_view &path) noexcept
Return stripped last component from given path separated by /, excluding the trailing separator /.
bool touch(const std::string &path, const jau::fraction_timespec &atime, const jau::fraction_timespec &mtime, const fmode_t mode=fmode_t::def_file_prot) noexcept
Touch the file with given atime and mtime and create file if not existing yet.
bool isAbsolute(const std::string_view &path) noexcept
Returns true if first character is / or - in case of Windows - \\.
fmode_t
Generic file type and POSIX protection mode bits as used in file_stats, touch(), mkdir() etc.
bool copy(const std::string &source_path, const std::string &dest_path, const copy_options copts=copy_options::none) noexcept
Copy the given source_path to dest_path using copy_options.
copy_options
Filesystem copy options used to copy() path elements.
std::string get_cwd() noexcept
Return the current working directory or empty on failure.
std::string to_string(const fmode_t mask, const bool show_rwx) noexcept
Return the string representation of fmode_t.
traverse_options
Filesystem traverse options used to visit() path elements.
void sync() noexcept
Synchronizes filesystems, i.e.
bool mkdir(const std::string &path, const fmode_t mode=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.
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
jau::function< bool(traverse_event, const file_stats &, size_t)> path_visitor
path_visitor jau::FunctionDef definition
bool rename(const std::string &oldpath, const std::string &newpath) noexcept
Rename oldpath to newpath using POSIX rename(), with the following combinations.
@ dir_check_entry
Visiting a directory on entry, see traverse_options::dir_check_entry.
@ 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.
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 ...
@ write
Write capabilities.
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.
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.
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 toISO8601String(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 toString() const noexcept
Return simple string representation in seconds and nanoseconds.
void add(const jau::io::fs::file_stats &element_stats)
int total_sym_links_not_existing
int total_sym_links_existing
std::string toString() const noexcept
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::io::fs::file_stats &source, const int source_added_dead_links, const std::string &dest, const jau::io::fs::copy_options copts, const bool dest_is_vfat)