29 #include <sys/types.h>
48 jau::fprintf_td(stdout,
"test00: 02: proot02.rel: %s\n", rel_project_root.c_str());
50 REQUIRE( proot_stats_01.
exists() );
51 REQUIRE( proot_stats_02.
exists() );
59 INFO_STR(
"\n\ntest01_cwd: cwd "+cwd+
"\n");
60 REQUIRE( 0 < cwd.size() );
61 const size_t idx = cwd.find(
"/jaulib");
63 REQUIRE( idx < cwd.size() );
64 REQUIRE( idx != std::string::npos );
72 const std::string pathname0 =
"/";
74 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
75 REQUIRE( 0 < pathname1.size() );
76 REQUIRE( pathname1 ==
"/" );
80 const std::string pathname0 =
"lala.txt";
82 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
83 REQUIRE( 0 < pathname1.size() );
84 REQUIRE( pathname1 ==
"." );
87 const std::string pathname0 =
"lala";
89 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
90 REQUIRE( 0 < pathname1.size() );
91 REQUIRE( pathname1 ==
"." );
94 const std::string pathname0 =
"lala/";
96 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
97 REQUIRE( 0 < pathname1.size() );
98 REQUIRE( pathname1 ==
"." );
102 const std::string pathname0 =
"/lala.txt";
104 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
105 REQUIRE( 0 < pathname1.size() );
106 REQUIRE( pathname1 ==
"/" );
109 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
111 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
112 REQUIRE( 0 < pathname1.size() );
113 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
116 const std::string pathname0 =
"blabla/jaulib/test/sub";
118 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
119 REQUIRE( 0 < pathname1.size() );
120 REQUIRE( pathname1 ==
"blabla/jaulib/test" );
123 const std::string pathname0 =
"blabla/jaulib/test/";
125 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
126 REQUIRE( 0 < pathname1.size() );
127 REQUIRE( pathname1 ==
"blabla/jaulib" );
130 const std::string pathname0 =
"blabla/jaulib/test";
132 INFO_STR(
"\n\ntest02_dirname: cwd "+pathname0+
" -> "+pathname1+
"\n");
133 REQUIRE( 0 < pathname1.size() );
134 REQUIRE( pathname1 ==
"blabla/jaulib" );
140 const std::string pathname0 =
"/";
142 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
143 REQUIRE( 0 < pathname1.size() );
144 REQUIRE( pathname1 ==
"/" );
149 const std::string pathname0 =
"lala.txt";
151 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
152 REQUIRE( 0 < pathname1.size() );
153 REQUIRE( pathname1 ==
"lala.txt" );
157 const std::string pathname0 =
"lala";
159 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
160 REQUIRE( 0 < pathname1.size() );
161 REQUIRE( pathname1 ==
"lala" );
165 const std::string pathname0 =
"lala/";
167 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
168 REQUIRE( 0 < pathname1.size() );
169 REQUIRE( pathname1 ==
"lala" );
173 const std::string pathname0 =
"/lala.txt";
175 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
176 REQUIRE( 0 < pathname1.size() );
177 REQUIRE( pathname1 ==
"lala.txt" );
180 const std::string pathname0 =
"blabla/jaulib/test/sub.txt";
182 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
183 REQUIRE( 0 < pathname1.size() );
184 REQUIRE( pathname1 ==
"sub.txt" );
188 const std::string pathname0 =
"blabla/jaulib/test/";
190 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
191 REQUIRE( 0 < pathname1.size() );
192 REQUIRE( pathname1 ==
"test" );
196 const std::string pathname0 =
"blabla/jaulib/test";
198 INFO_STR(
"\n\ntest03_basename: cwd "+pathname0+
" -> "+pathname1+
"\n");
199 REQUIRE( 0 < pathname1.size() );
200 REQUIRE( pathname1 ==
"test" );
209 jau::fprintf_td(stdout,
"test03b_absolute: 01: rel_project_root %s\n", rel_project_root.c_str());
212 REQUIRE(
true == proot_stats.
exists() );
213 REQUIRE(
true == proot_stats.
is_dir() );
215 std::string abs_project_root;
218 jau::fprintf_td(stdout,
"test03b_absolute: 02: %s\n", abs_project_root.c_str());
219 REQUIRE( 0 < abs_project_root.size() );
226 REQUIRE( stats.
exists() );
227 REQUIRE( stats.
is_dir() );
232 jau::fprintf_td(stdout,
"test03b_absolute: 03.0: %s\n", bname0.c_str());
233 jau::fprintf_td(stdout,
"test03b_absolute: 03.1: %s\n", bname1.c_str());
234 REQUIRE( bname0 == bname1 );
243 REQUIRE(
"." == di.
dirname() );
245 REQUIRE(
"." == di.
path() );
246 REQUIRE(
true == di.
empty() );
249 const std::string dirname_;
252 REQUIRE(
"." == di.
dirname() );
254 REQUIRE(
"." == di.
path() );
255 REQUIRE(
true == di.
empty() );
258 const std::string dirname_(
".");
261 REQUIRE(
"." == di.
dirname() );
263 REQUIRE(
"." == di.
path() );
264 REQUIRE(
false == di.
empty() );
267 const std::string dirname_(
"/");
270 REQUIRE(
"/" == di.
dirname() );
272 REQUIRE(
"/" == di.
path() );
273 REQUIRE(
false == di.
empty() );
277 const std::string path1_ =
"lala";
280 REQUIRE(
"." == di.
dirname() );
282 REQUIRE(
"lala" == di.
path() );
283 REQUIRE(
false == di.
empty() );
286 const std::string path1_ =
"lala/";
289 REQUIRE(
"." == di.
dirname() );
291 REQUIRE(
"lala" == di.
path() );
292 REQUIRE(
false == di.
empty() );
296 const std::string path1_ =
"/lala";
299 REQUIRE(
"/" == di.
dirname() );
301 REQUIRE(
"/lala" == di.
path() );
302 REQUIRE(
false == di.
empty() );
306 const std::string path1_ =
"dir0/lala";
309 REQUIRE(
"dir0" == di.
dirname() );
311 REQUIRE(
"dir0/lala" == di.
path() );
314 const std::string path1_ =
"dir0/lala/";
317 REQUIRE(
"dir0" == di.
dirname() );
319 REQUIRE(
"dir0/lala" == di.
path() );
322 const std::string path1_ =
"/dir0/lala";
325 REQUIRE(
"/dir0" == di.
dirname() );
327 REQUIRE(
"/dir0/lala" == di.
path() );
330 const std::string path1_ =
"/dir0/lala/";
333 REQUIRE(
"/dir0" == di.
dirname() );
335 REQUIRE(
"/dir0/lala" == di.
path() );
340 const std::string path1_ =
"/dir0/../lala";
343 REQUIRE(
"/" == di.
dirname() );
345 REQUIRE(
"/lala" == di.
path() );
348 const std::string path1_ =
"dir0/../lala";
351 REQUIRE(
"." == di.
dirname() );
353 REQUIRE(
"lala" == di.
path() );
356 const std::string path1_ =
"../../lala";
359 REQUIRE(
"../.." == di.
dirname() );
361 REQUIRE(
"../../lala" == di.
path() );
364 const std::string path1_ =
"./../lala";
367 REQUIRE(
".." == di.
dirname() );
369 REQUIRE(
"../lala" == di.
path() );
372 const std::string path1_ =
"dir0/../../lala";
375 REQUIRE(
".." == di.
dirname() );
377 REQUIRE(
"../lala" == di.
path() );
381 const std::string path1_ =
"dir0/dir1/../lala";
384 REQUIRE(
"dir0" == di.
dirname() );
386 REQUIRE(
"dir0/lala" == di.
path() );
389 const std::string path1_ =
"/dir0/dir1/../lala/";
392 REQUIRE(
"/dir0" == di.
dirname() );
394 REQUIRE(
"/dir0/lala" == di.
path() );
397 const std::string path1_ =
"dir0/dir1/../bbb/ccc/../lala";
400 REQUIRE(
"dir0/bbb" == di.
dirname() );
402 REQUIRE(
"dir0/bbb/lala" == di.
path() );
405 const std::string path1_ =
"dir0/dir1/bbb/../../lala";
408 REQUIRE(
"dir0" == di.
dirname() );
410 REQUIRE(
"dir0/lala" == di.
path() );
413 const std::string path1_ =
"dir0/dir1/bbb/../../../lala";
416 REQUIRE(
"." == di.
dirname() );
418 REQUIRE(
"lala" == di.
path() );
421 const std::string path1_ =
"dir0/dir1/bbb/../../../../lala";
424 REQUIRE(
".." == di.
dirname() );
426 REQUIRE(
"../lala" == di.
path() );
429 const std::string path1_ =
"dir0/dir1/bbb/../../lala/..";
432 REQUIRE(
"." == di.
dirname() );
434 REQUIRE(
"dir0" == di.
path() );
437 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala";
440 REQUIRE(
"dir0" == di.
dirname() );
442 REQUIRE(
"dir0/lala" == di.
path() );
445 const std::string path1_ =
"dir0/./dir1/./bbb/../.././lala/.";
448 REQUIRE(
"dir0" == di.
dirname() );
450 REQUIRE(
"dir0/lala" == di.
path() );
453 const std::string path1_ =
"./dir0/./dir1/./bbb/../.././lala/.";
456 REQUIRE(
"dir0" == di.
dirname() );
458 REQUIRE(
"dir0/lala" == di.
path() );
461 const std::string path1_ =
"/./dir0/./dir1/./bbb/../.././lala/.";
464 REQUIRE(
"/dir0" == di.
dirname() );
466 REQUIRE(
"/dir0/lala" == di.
path() );
470 const std::string path1_ =
"../../test_data/file_01_slink09R1.txt";
473 REQUIRE(
"../../test_data" == di.
dirname() );
474 REQUIRE(
"file_01_slink09R1.txt" == di.
basename() );
475 REQUIRE( path1_ == di.
path() );
479 const std::string path1_ =
"../../../jaulib/test_data";
482 REQUIRE(
"../../../jaulib" == di.
dirname() );
483 REQUIRE(
"test_data" == di.
basename() );
484 REQUIRE( path1_ == di.
path() );
488 const std::string path1_ =
"../../../../jaulib/test_data";
491 REQUIRE(
"../../../../jaulib" == di.
dirname() );
492 REQUIRE(
"test_data" == di.
basename() );
493 REQUIRE( path1_ == di.
path() );
497 const std::string path1_ =
"././././jaulib/test_data";
500 REQUIRE(
"jaulib" == di.
dirname() );
501 REQUIRE(
"test_data" == di.
basename() );
502 REQUIRE(
"jaulib/test_data" == di.
path() );
505 const std::string path1_ =
"a/././././jaulib/test_data";
508 REQUIRE(
"a/jaulib" == di.
dirname() );
509 REQUIRE(
"test_data" == di.
basename() );
510 REQUIRE(
"a/jaulib/test_data" == di.
path() );
515 const std::string path1_ =
"/../lala";
518 REQUIRE(
"/.." == di.
dirname() );
520 REQUIRE(
"/../lala" == di.
path() );
532 REQUIRE(
false == stats.
exists() );
538 REQUIRE(
false == stats.
exists() );
546 REQUIRE( !stats.
is_dir() );
549 REQUIRE( 15 == stats.
size() );
556 REQUIRE(
true == proot_stats.
exists() );
557 REQUIRE(
true == proot_stats.
is_dir() );
562 REQUIRE( stats.
exists() );
564 REQUIRE( !stats.
is_dir() );
567 REQUIRE( 15 == stats.
size() );
571 jau::fprintf_td(stdout,
"test05_file_stat: 12: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
572 REQUIRE( 0 == link_count );
573 REQUIRE( final_target == &stats );
577 REQUIRE( stats2.
exists() );
579 REQUIRE( !stats2.
is_dir() );
582 REQUIRE( 15 == stats2.
size() );
583 REQUIRE( stats == stats2 );
587 REQUIRE( stats2.
exists() );
589 REQUIRE( !stats2.
is_dir() );
592 REQUIRE( stats != stats2 );
599 REQUIRE( stats.
exists() );
601 REQUIRE( stats.
is_dir() );
604 REQUIRE( 0 == stats.
size() );
608 jau::fprintf_td(stdout,
"test05_file_stat: 13: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
609 REQUIRE( 0 == link_count );
610 REQUIRE( final_target == &stats );
616 REQUIRE( !stats.
exists() );
618 REQUIRE( !stats.
is_dir() );
621 REQUIRE( 0 == stats.
size() );
625 jau::fprintf_td(stdout,
"test05_file_stat: 14: final_target (%zu link count): %s\n", link_count, final_target->
to_string().c_str());
626 REQUIRE( 0 == link_count );
627 REQUIRE( final_target == &stats );
633 INFO_STR(
"\n\ntest06_file_stat_symlinks\n");
636 REQUIRE(
true == proot_stats.
exists() );
637 REQUIRE(
true == proot_stats.
is_dir() );
642 REQUIRE( stats.
exists() );
644 REQUIRE( !stats.
is_dir() );
647 REQUIRE( 15 == stats.
size() );
654 REQUIRE( 1 == link_count );
655 REQUIRE( final_target != &stats );
656 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
660 REQUIRE(
nullptr != link_target );
662 REQUIRE( final_target == link_target );
663 REQUIRE( !link_target->
is_dir() );
664 REQUIRE( link_target->
is_file() );
665 REQUIRE( !link_target->
is_link() );
673 REQUIRE( stats.
exists() );
675 REQUIRE( !stats.
is_dir() );
678 REQUIRE( 20 < stats.
size() );
685 REQUIRE( 1 == link_count );
686 REQUIRE( final_target != &stats );
687 REQUIRE(
"/etc/fstab" == final_target->
path() );
691 REQUIRE(
nullptr != link_target );
693 REQUIRE( final_target == link_target );
694 REQUIRE( !link_target->
is_dir() );
695 REQUIRE( link_target->
is_file() );
696 REQUIRE( !link_target->
is_link() );
704 REQUIRE( stats.
exists() );
706 REQUIRE( !stats.
is_dir() );
709 REQUIRE( 15 == stats.
size() );
716 REQUIRE( 3 == link_count );
717 REQUIRE( final_target != &stats );
718 REQUIRE( proot_stats.
path()+
"/file_01.txt" == final_target->
path() );
723 REQUIRE( final_target != link_target1 );
724 REQUIRE( proot_stats.
path()+
"/file_01_slink09R1.txt" == link_target1->
path() );
725 REQUIRE( 15 == link_target1->
size() );
726 REQUIRE( !link_target1->
is_dir() );
727 REQUIRE( link_target1->
is_file() );
728 REQUIRE( link_target1->
is_link() );
733 REQUIRE(
nullptr != link_target2 );
735 REQUIRE( final_target != link_target2 );
736 REQUIRE( link_target1 != link_target2 );
737 REQUIRE( proot_stats.
path()+
"/file_01_slink01.txt" == link_target2->
path() );
738 REQUIRE( 15 == link_target2->
size() );
739 REQUIRE( !link_target2->
is_dir() );
740 REQUIRE( link_target2->
is_file() );
741 REQUIRE( link_target2->
is_link() );
746 REQUIRE(
nullptr != link_target3 );
748 REQUIRE( final_target == link_target3 );
749 REQUIRE( link_target1 != link_target3 );
750 REQUIRE( link_target2 != link_target3 );
751 REQUIRE( 15 == link_target3->
size() );
752 REQUIRE( !link_target3->
is_dir() );
753 REQUIRE( link_target3->
is_file() );
754 REQUIRE( !link_target3->
is_link() );
763 REQUIRE( !stats.
exists() );
765 REQUIRE( !stats.
is_dir() );
768 REQUIRE( 0 == stats.
size() );
776 REQUIRE( 0 == link_count );
777 REQUIRE( final_target == &stats );
783 REQUIRE( !stats.
exists() );
785 REQUIRE( !stats.
is_dir() );
788 REQUIRE( 0 == stats.
size() );
796 REQUIRE( 0 == link_count );
797 REQUIRE( *final_target == stats );
798 REQUIRE( final_target == &stats );
803 jau::fprintf_td(stdout,
"test_file_stat_fd_item: expect '%s', fd %d, name_fd1 '%s', make_fd_link '%s'\n",
810 REQUIRE( stats.
exists() );
814 REQUIRE( !stats.
is_dir() );
818 REQUIRE( stats.
has_fd() );
819 REQUIRE( fd == stats.
fd() );
821 REQUIRE( 0 == stats.
size() );
825 if( !named_fd1.empty() ) {
827 jau::fprintf_td(stdout,
"test_file_stat_fd_item.2: expect '%s', fd %d, name_fd1 '%s'\n",
831 REQUIRE( stats.
exists() );
835 REQUIRE( !stats.
is_dir() );
839 REQUIRE( stats.
has_fd() );
840 REQUIRE( fd == stats.
fd() );
842 REQUIRE( 0 == stats.
size() );
846 if( !named_fd_link.empty() ) {
848 jau::fprintf_td(stdout,
"test_file_stat_fd_item.3: expect '%s', fd %d, make_fd_link '%s'\n",
852 REQUIRE( stats.
exists() );
856 REQUIRE( !stats.
is_dir() );
860 REQUIRE( stats.
has_fd() );
861 REQUIRE( fd == stats.
fd() );
863 REQUIRE( 0 == stats.
size() );
868 REQUIRE(
nullptr != final_target );
870 REQUIRE( 1 <= link_count );
871 REQUIRE( 2 >= link_count );
879 const std::string fd_stdin_1 =
"/dev/fd/0";
880 const std::string fd_stdout_1 =
"/dev/fd/1";
881 const std::string fd_stderr_1 =
"/dev/fd/2";
883 const std::string fd_stdin_l =
"/dev/stdin";
884 const std::string fd_stdout_l =
"/dev/stdout";
885 const std::string fd_stderr_l =
"/dev/stderr";
891 int fd = ::open(
"test07_file_stat_fd_tmp", O_CREAT|O_WRONLY|O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP );
898 REQUIRE( 0 == ::pipe(pipe_fds) );
901 ::close(pipe_fds[0]);
902 ::close(pipe_fds[1]);
907 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.";
916 REQUIRE( 0 == ::pipe(pipe_fds) );
917 ::pid_t pid = ::fork();
921 ::close(pipe_fds[0]);
922 const int new_stdout = pipe_fds[1];
927 if( !stats_stdout.
exists() || !stats_stdout.
has_fd() || new_stdout != stats_stdout.
fd() ) {
929 ::_exit(EXIT_FAILURE);
934 ::_exit(EXIT_FAILURE);
938 const size_t max_chunck = 64;
953 ::close(pipe_fds[1]);
955 if( outfile.
fail() ) {
957 ::_exit(EXIT_FAILURE);
960 ::_exit(EXIT_SUCCESS);
962 }
else if( 0 < pid ) {
964 ::close(pipe_fds[1]);
965 const int new_stdin = pipe_fds[0];
970 REQUIRE( stats_stdin.
exists() );
974 REQUIRE( !stats_stdin.
is_dir() );
975 REQUIRE( !stats_stdin.
is_file() );
976 const bool fifo_or_char = stats_stdin.
is_fifo() || stats_stdin.
is_char();
977 REQUIRE(
true == fifo_or_char );
978 REQUIRE( stats_stdin.
has_fd() );
979 REQUIRE( new_stdin == stats_stdin.
fd() );
980 REQUIRE( 0 == stats_stdin.
size() );
985 REQUIRE( !infile.
fail() );
988 ::bzero(buffer,
sizeof(buffer));
989 size_t total_read = 0;
991 while( infile.
good() && total_read <
sizeof(buffer) ) {
992 const size_t got = infile.
read(buffer+total_read,
sizeof(buffer)-total_read);
994 REQUIRE( !infile.
fail() );
1001 ::close(pipe_fds[0]);
1003 REQUIRE( !infile.
fail() );
1012 ::pid_t child_pid = ::waitpid(pid, &pid_status, 0);
1013 if( 0 > child_pid ) {
1014 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) failed: child_pid %d\n", pid, child_pid);
1017 if( child_pid != pid ) {
1018 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated child_pid pid %d\n", pid, child_pid);
1019 REQUIRE(child_pid == pid);
1021 if( !WIFEXITED(pid_status) ) {
1022 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) terminated abnormally child_pid %d, pid_status %d\n", pid, child_pid, pid_status);
1023 REQUIRE(
true == WIFEXITED(pid_status));
1025 if( EXIT_SUCCESS != WEXITSTATUS(pid_status) ) {
1026 jau::fprintf_td(stdout,
"Parent: Error: wait(%d) exit with failure child_pid %d, exit_code %d\n", pid, child_pid, WEXITSTATUS(pid_status));
1027 REQUIRE(EXIT_SUCCESS == WEXITSTATUS(pid_status));
1032 jau::fprintf_td(stdout,
"fork failed %d, %s\n", errno, ::strerror(errno));
1047 REQUIRE( !root_stats.
exists() );
1049 REQUIRE( !root_stats.
is_dir() );
1050 REQUIRE( !root_stats.
is_file() );
1051 REQUIRE( !root_stats.
is_link() );
1057 REQUIRE( root_stats.
exists() );
1059 REQUIRE( root_stats.
is_dir() );
1060 REQUIRE( !root_stats.
is_file() );
1061 REQUIRE( !root_stats.
is_link() );
1071 const std::string file_01 =
temp_root+
"/data01.txt";
1072 const std::string file_02 =
temp_root+
"/data02.txt";
1077 REQUIRE( root_stats.
exists() );
1079 REQUIRE( root_stats.
is_dir() );
1080 REQUIRE( !root_stats.
is_file() );
1081 REQUIRE( !root_stats.
is_link() );
1100 REQUIRE( file_stats.
exists() );
1102 REQUIRE( !file_stats.
is_dir() );
1103 REQUIRE( file_stats.
is_file() );
1104 REQUIRE( !file_stats.
is_link() );
1106 REQUIRE( td_1s >= atime_td );
1109 REQUIRE( td_1s >= mtime_td );
1129 REQUIRE( td_1s >= atime_td );
1132 REQUIRE( td_1s >= mtime_td );
1149 REQUIRE( file_stats_post.
exists() );
1151 REQUIRE( !file_stats_post.
is_dir() );
1152 REQUIRE( file_stats_post.
is_file() );
1153 REQUIRE( !file_stats_post.
is_link() );
1155 REQUIRE( atime_set == file_stats_post.
atime() );
1158 REQUIRE( mtime_set == file_stats_post.
mtime() );
1168 INFO_STR(
"\n\ntest21_visit_error\n");
1174 std::string sub_dir1 =
temp_root+
"/sub1";
1175 std::string sub_dir2 =
temp_root+
"/sub2";
1176 std::string sub_dir3 =
temp_root+
"/sub1/sub3";
1200 stats_R_FSL_PDL.
add(element_stats);
1213 REQUIRE( 4 == stats_R_FSL_PDL.
dirs_real );
1227 stats_ptr->
add(element_stats);
1232 REQUIRE( stats_R_FSL_PDL == stats_R_FSL );
1239 INFO_STR(
"\n\ntest22_visit_symlinks\n");
1242 REQUIRE(
true == proot_stats.
exists() );
1253 stats.
add(element_stats);
1280 stats.
add(element_stats);
1310 stats.
add(element_stats);
1329 INFO_STR(
"\n\ntest30_copy_file2dir\n");
1332 REQUIRE(
true == root_orig_stats.
exists() );
1334 const std::string root_copy =
temp_root+
"_copy_test30";
1342 REQUIRE(
true == stats.
exists() );
1343 REQUIRE(
true == stats.
ok() );
1344 REQUIRE(
true == stats.
is_dir() );
1350 REQUIRE(
true == source1_stats.
exists() );
1351 REQUIRE(
true == source1_stats.
ok() );
1352 REQUIRE(
true == source1_stats.
is_file() );
1361 REQUIRE(
false == dest_stats.
exists() );
1367 REQUIRE(
true == dest_stats.
exists() );
1368 REQUIRE(
true == dest_stats.
ok() );
1369 REQUIRE(
true == dest_stats.
is_file() );
1370 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1371 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1381 REQUIRE(
true == dest_stats.
exists() );
1382 REQUIRE(
true == dest_stats.
ok() );
1383 REQUIRE(
true == dest_stats.
is_file() );
1397 REQUIRE(
true == dest_stats.
exists() );
1398 REQUIRE(
true == dest_stats.
ok() );
1399 REQUIRE(
true == dest_stats.
is_file() );
1400 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1401 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1407 REQUIRE(
true == dest_stats.
exists() );
1408 REQUIRE(
true == dest_stats.
ok() );
1409 REQUIRE(
true == dest_stats.
is_file() );
1410 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1411 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1420 INFO_STR(
"\n\ntest31_copy_file2file\n");
1423 REQUIRE(
true == root_orig_stats.
exists() );
1425 const std::string root_copy =
temp_root+
"_copy_test31";
1433 REQUIRE(
true == stats.
exists() );
1434 REQUIRE(
true == stats.
ok() );
1435 REQUIRE(
true == stats.
is_dir() );
1441 REQUIRE(
true == source1_stats.
exists() );
1442 REQUIRE(
true == source1_stats.
ok() );
1443 REQUIRE(
true == source1_stats.
is_file() );
1448 REQUIRE(
true == source2_stats.
exists() );
1449 REQUIRE(
true == source2_stats.
ok() );
1450 REQUIRE(
true == source2_stats.
is_file() );
1451 REQUIRE(
true == source2_stats.
is_link() );
1460 REQUIRE(
false == dest_stats.
exists() );
1462 REQUIRE(
true ==
jau::fs::copy(source1_stats.
path(), root_copy+
"/file_10.txt", copts) );
1467 REQUIRE(
true == dest_stats.
exists() );
1468 REQUIRE(
true == dest_stats.
ok() );
1469 REQUIRE(
true == dest_stats.
is_file() );
1470 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1471 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1481 REQUIRE(
true == dest_stats.
exists() );
1482 REQUIRE(
true == dest_stats.
ok() );
1483 REQUIRE(
true == dest_stats.
is_file() );
1485 REQUIRE(
false ==
jau::fs::copy(source1_stats.
path(), root_copy+
"/file_10.txt", copts) );
1498 REQUIRE(
true == dest_stats.
exists() );
1499 REQUIRE(
true == dest_stats.
ok() );
1500 REQUIRE(
true == dest_stats.
is_file() );
1501 REQUIRE( source1_stats.
size() == dest_stats.
size() );
1502 REQUIRE( source1_stats.
mode() == dest_stats.
mode() );
1504 REQUIRE(
true ==
jau::fs::copy(source2_stats.
path(), root_copy+
"/file_10.txt", copts) );
1509 REQUIRE(
true == dest_stats.
exists() );
1510 REQUIRE(
true == dest_stats.
ok() );
1511 REQUIRE(
true == dest_stats.
is_file() );
1512 REQUIRE(
false == dest_stats.
is_link() );
1513 REQUIRE( source2_stats.
size() == dest_stats.
size() );
1523 INFO_STR(
"\n\ntest40_copy_ext_r_p\n");
1526 REQUIRE(
true == root_orig_stats.
exists() );
1532 const std::string root_copy =
temp_root+
"_copy_test40";
1534 testxx_copy_r_p(
"test40_copy_ext_r_p", root_orig_stats, 0 , root_copy, copts,
false );
1539 INFO_STR(
"\n\ntest41_copy_ext_r_p_below\n");
1542 REQUIRE(
true == root_orig_stats.
exists() );
1548 const std::string root_copy_parent =
temp_root+
"_copy_test41_parent";
1551 testxx_copy_r_p(
"test41_copy_ext_r_p_below", root_orig_stats, 0 , root_copy_parent, copts,
false );
1556 INFO_STR(
"\n\ntest41_copy_ext_r_p_into\n");
1559 REQUIRE(
true == root_orig_stats.
exists() );
1566 const std::string root_copy =
temp_root+
"_copy_test42_into";
1569 testxx_copy_r_p(
"test42_copy_ext_r_p_into", root_orig_stats, 0 , root_copy, copts,
false );
1574 INFO_STR(
"\n\ntest43_copy_ext_r_p_over\n");
1577 REQUIRE(
true == root_orig_stats.
exists() );
1583 const std::string root_copy =
temp_root+
"_copy_test43_over";
1586 const std::string root_copy_sub = root_copy+
"/"+root_orig_stats.
item().
basename();
1588 testxx_copy_r_p(
"test43_copy_ext_r_p_over", root_orig_stats, 0 , root_copy, copts,
false );
1593 INFO_STR(
"\n\ntest49_copy_ext_r_p_vfat\n");
1597 if( !dest_fs_vfat_stats.
is_dir() ) {
1598 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());
1601 const std::string dest_vfat_parent =
dest_fs_vfat+
"/test49_data_sink";
1604 jau::fprintf_td(stdout,
"test49_copy_ext_r_p_vfat: Skipped, couldn't create vfat dest folder %s\n", dest_vfat_parent.c_str());
1610 REQUIRE(
true == root_orig_stats.
exists() );
1617 const std::string dest_vfat_dir = dest_vfat_parent+
"/"+
temp_root;
1618 testxx_copy_r_p(
"test49_copy_ext_r_p_vfat", root_orig_stats, 0 , dest_vfat_dir, copts,
true );
1624 INFO_STR(
"\n\ntest50_copy_ext_r_p_fsl\n");
1627 REQUIRE(
true == root_orig_stats.
exists() );
1629 const std::string root_copy =
temp_root+
"_copy_test50";
1641 REQUIRE(
true == root_copy_stats.
exists() );
1642 REQUIRE(
true == root_copy_stats.
ok() );
1643 REQUIRE(
true == root_copy_stats.
is_dir() );
1649 stats_ptr->
add(element_stats);
1663 REQUIRE(
true ==
jau::fs::visit(root_orig_stats, topts_orig, pv_orig) );
1664 REQUIRE(
true ==
jau::fs::visit(root_copy_stats, topts_copy, pv_copy) );
1666 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: copy %s, traverse_orig %s, traverse_copy %s\n",
1670 jau::fprintf_td(stdout,
"test50_copy_ext_r_p_fsl: destination visitor stats\n%s\n", stats_copy.
to_string().c_str());
1695 const std::string root_copy_renamed =
temp_root+
"_copy_test50_renamed";
1700 REQUIRE(
false == root_copy_stats2.
exists() );
1703 REQUIRE(
true == root_copy_renamed_stats.
exists() );
1704 REQUIRE(
true == root_copy_renamed_stats.
ok() );
1705 REQUIRE(
true == root_copy_renamed_stats.
is_dir() );
1712 REQUIRE(
true ==
jau::fs::visit(root_copy_renamed_stats, topts_copy, pv_copy) );
#define REQUIRE_MSG(MSG,...)
std::string executable_path
The main argv[0] test executable path.
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.
Class template jau::function is a general-purpose static-polymorphic function wrapper.
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 alphabet &v) 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.
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.
constexpr bool is_set(const fmode_t mask, const fmode_t bits) noexcept
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().
std::string to_string(const fmode_t mask, const bool show_rwx=false) noexcept
Return the string representation of fmode_t.
@ 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 min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
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() 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)