]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-fs-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
10 #include "id128-util.h"
13 #include "path-util.h"
15 #include "stdio-util.h"
16 #include "string-util.h"
18 #include "user-util.h"
21 static void test_chase_symlinks ( void ) {
22 _cleanup_free_
char * result
= NULL
;
23 char temp
[] = "/tmp/test-chase.XXXXXX" ;
24 const char * top
, * p
, * pslash
, * q
, * qslash
;
27 assert_se ( mkdtemp ( temp
));
29 top
= strjoina ( temp
, "/top" );
30 assert_se ( mkdir ( top
, 0700 ) >= 0 );
32 p
= strjoina ( top
, "/dot" );
33 assert_se ( symlink ( "." , p
) >= 0 );
35 p
= strjoina ( top
, "/dotdot" );
36 assert_se ( symlink ( ".." , p
) >= 0 );
38 p
= strjoina ( top
, "/dotdota" );
39 assert_se ( symlink ( "../a" , p
) >= 0 );
41 p
= strjoina ( temp
, "/a" );
42 assert_se ( symlink ( "b" , p
) >= 0 );
44 p
= strjoina ( temp
, "/b" );
45 assert_se ( symlink ( "/usr" , p
) >= 0 );
47 p
= strjoina ( temp
, "/start" );
48 assert_se ( symlink ( "top/dot/dotdota" , p
) >= 0 );
50 /* Paths that use symlinks underneath the "root" */
52 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
54 assert_se ( path_equal ( result
, "/usr" ));
55 result
= mfree ( result
);
57 pslash
= strjoina ( p
, "/" );
58 r
= chase_symlinks ( pslash
, NULL
, 0 , & result
);
60 assert_se ( path_equal ( result
, "/usr/" ));
61 result
= mfree ( result
);
63 r
= chase_symlinks ( p
, temp
, 0 , & result
);
64 assert_se ( r
== - ENOENT
);
66 r
= chase_symlinks ( pslash
, temp
, 0 , & result
);
67 assert_se ( r
== - ENOENT
);
69 q
= strjoina ( temp
, "/usr" );
71 r
= chase_symlinks ( p
, temp
, CHASE_NONEXISTENT
, & result
);
73 assert_se ( path_equal ( result
, q
));
74 result
= mfree ( result
);
76 qslash
= strjoina ( q
, "/" );
78 r
= chase_symlinks ( pslash
, temp
, CHASE_NONEXISTENT
, & result
);
80 assert_se ( path_equal ( result
, qslash
));
81 result
= mfree ( result
);
83 assert_se ( mkdir ( q
, 0700 ) >= 0 );
85 r
= chase_symlinks ( p
, temp
, 0 , & result
);
87 assert_se ( path_equal ( result
, q
));
88 result
= mfree ( result
);
90 r
= chase_symlinks ( pslash
, temp
, 0 , & result
);
92 assert_se ( path_equal ( result
, qslash
));
93 result
= mfree ( result
);
95 p
= strjoina ( temp
, "/slash" );
96 assert_se ( symlink ( "/" , p
) >= 0 );
98 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
100 assert_se ( path_equal ( result
, "/" ));
101 result
= mfree ( result
);
103 r
= chase_symlinks ( p
, temp
, 0 , & result
);
105 assert_se ( path_equal ( result
, temp
));
106 result
= mfree ( result
);
108 /* Paths that would "escape" outside of the "root" */
110 p
= strjoina ( temp
, "/6dots" );
111 assert_se ( symlink ( "../../.." , p
) >= 0 );
113 r
= chase_symlinks ( p
, temp
, 0 , & result
);
114 assert_se ( r
> 0 && path_equal ( result
, temp
));
115 result
= mfree ( result
);
117 p
= strjoina ( temp
, "/6dotsusr" );
118 assert_se ( symlink ( "../../../usr" , p
) >= 0 );
120 r
= chase_symlinks ( p
, temp
, 0 , & result
);
121 assert_se ( r
> 0 && path_equal ( result
, q
));
122 result
= mfree ( result
);
124 p
= strjoina ( temp
, "/top/8dotsusr" );
125 assert_se ( symlink ( "../../../../usr" , p
) >= 0 );
127 r
= chase_symlinks ( p
, temp
, 0 , & result
);
128 assert_se ( r
> 0 && path_equal ( result
, q
));
129 result
= mfree ( result
);
131 /* Paths that contain repeated slashes */
133 p
= strjoina ( temp
, "/slashslash" );
134 assert_se ( symlink ( "///usr///" , p
) >= 0 );
136 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
138 assert_se ( path_equal ( result
, "/usr" ));
139 result
= mfree ( result
);
141 r
= chase_symlinks ( p
, temp
, 0 , & result
);
143 assert_se ( path_equal ( result
, q
));
144 result
= mfree ( result
);
148 r
= chase_symlinks ( "/etc/./.././" , NULL
, 0 , & result
);
150 assert_se ( path_equal ( result
, "/" ));
151 result
= mfree ( result
);
153 r
= chase_symlinks ( "/etc/./.././" , "/etc" , 0 , & result
);
154 assert_se ( r
> 0 && path_equal ( result
, "/etc" ));
155 result
= mfree ( result
);
157 r
= chase_symlinks ( "/../.././//../../etc" , NULL
, 0 , & result
);
159 assert_se ( streq ( result
, "/etc" ));
160 result
= mfree ( result
);
162 r
= chase_symlinks ( "/../.././//../../test-chase.fsldajfl" , NULL
, CHASE_NONEXISTENT
, & result
);
164 assert_se ( streq ( result
, "/test-chase.fsldajfl" ));
165 result
= mfree ( result
);
167 r
= chase_symlinks ( "/../.././//../../etc" , "/" , CHASE_PREFIX_ROOT
, & result
);
169 assert_se ( streq ( result
, "/etc" ));
170 result
= mfree ( result
);
172 r
= chase_symlinks ( "/../.././//../../test-chase.fsldajfl" , "/" , CHASE_PREFIX_ROOT
| CHASE_NONEXISTENT
, & result
);
174 assert_se ( streq ( result
, "/test-chase.fsldajfl" ));
175 result
= mfree ( result
);
177 r
= chase_symlinks ( "/etc/machine-id/foo" , NULL
, 0 , & result
);
178 assert_se ( r
== - ENOTDIR
);
179 result
= mfree ( result
);
181 /* Path that loops back to self */
183 p
= strjoina ( temp
, "/recursive-symlink" );
184 assert_se ( symlink ( "recursive-symlink" , p
) >= 0 );
185 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
186 assert_se ( r
== - ELOOP
);
188 /* Path which doesn't exist */
190 p
= strjoina ( temp
, "/idontexist" );
191 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
192 assert_se ( r
== - ENOENT
);
194 r
= chase_symlinks ( p
, NULL
, CHASE_NONEXISTENT
, & result
);
196 assert_se ( path_equal ( result
, p
));
197 result
= mfree ( result
);
199 p
= strjoina ( temp
, "/idontexist/meneither" );
200 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
201 assert_se ( r
== - ENOENT
);
203 r
= chase_symlinks ( p
, NULL
, CHASE_NONEXISTENT
, & result
);
205 assert_se ( path_equal ( result
, p
));
206 result
= mfree ( result
);
208 /* Path which doesn't exist, but contains weird stuff */
210 p
= strjoina ( temp
, "/idontexist/.." );
211 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
212 assert_se ( r
== - ENOENT
);
214 r
= chase_symlinks ( p
, NULL
, CHASE_NONEXISTENT
, & result
);
215 assert_se ( r
== - ENOENT
);
217 p
= strjoina ( temp
, "/target" );
218 q
= strjoina ( temp
, "/top" );
219 assert_se ( symlink ( q
, p
) >= 0 );
220 p
= strjoina ( temp
, "/target/idontexist" );
221 r
= chase_symlinks ( p
, NULL
, 0 , & result
);
222 assert_se ( r
== - ENOENT
);
224 if ( geteuid () == 0 ) {
225 p
= strjoina ( temp
, "/priv1" );
226 assert_se ( mkdir ( p
, 0755 ) >= 0 );
228 q
= strjoina ( p
, "/priv2" );
229 assert_se ( mkdir ( q
, 0755 ) >= 0 );
231 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) >= 0 );
233 assert_se ( chown ( q
, UID_NOBODY
, GID_NOBODY
) >= 0 );
234 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) >= 0 );
236 assert_se ( chown ( p
, UID_NOBODY
, GID_NOBODY
) >= 0 );
237 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) >= 0 );
239 assert_se ( chown ( q
, 0 , 0 ) >= 0 );
240 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) == - EPERM
);
242 assert_se ( rmdir ( q
) >= 0 );
243 assert_se ( symlink ( "/etc/passwd" , q
) >= 0 );
244 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) == - EPERM
);
246 assert_se ( chown ( p
, 0 , 0 ) >= 0 );
247 assert_se ( chase_symlinks ( q
, NULL
, CHASE_SAFE
, NULL
) >= 0 );
250 p
= strjoina ( temp
, "/machine-id-test" );
251 assert_se ( symlink ( "/usr/../etc/./machine-id" , p
) >= 0 );
253 pfd
= chase_symlinks ( p
, NULL
, CHASE_OPEN
, NULL
);
254 if ( pfd
!= - ENOENT
) {
255 _cleanup_close_
int fd
= - 1 ;
260 fd
= fd_reopen ( pfd
, O_RDONLY
| O_CLOEXEC
);
264 assert_se ( id128_read_fd ( fd
, ID128_PLAIN
, & a
) >= 0 );
265 assert_se ( sd_id128_get_machine (& b
) >= 0 );
266 assert_se ( sd_id128_equal ( a
, b
));
271 p
= strjoina ( temp
, "/start" );
272 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
274 p
= strjoina ( temp
, "/top/dot/dotdota" );
275 assert_se ( streq ( p
, result
));
276 result
= mfree ( result
);
278 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
280 p
= strjoina ( temp
, "/top/./dotdota" );
281 assert_se ( streq ( p
, result
));
282 result
= mfree ( result
);
284 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
286 p
= strjoina ( temp
, "/top/../a" );
287 assert_se ( streq ( p
, result
));
288 result
= mfree ( result
);
290 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
292 p
= strjoina ( temp
, "/a" );
293 assert_se ( streq ( p
, result
));
294 result
= mfree ( result
);
296 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
298 p
= strjoina ( temp
, "/b" );
299 assert_se ( streq ( p
, result
));
300 result
= mfree ( result
);
302 r
= chase_symlinks ( p
, NULL
, CHASE_STEP
, & result
);
304 assert_se ( streq ( "/usr" , result
));
305 result
= mfree ( result
);
307 r
= chase_symlinks ( "/usr" , NULL
, CHASE_STEP
, & result
);
309 assert_se ( streq ( "/usr" , result
));
310 result
= mfree ( result
);
312 assert_se ( rm_rf ( temp
, REMOVE_ROOT
| REMOVE_PHYSICAL
) >= 0 );
315 static void test_unlink_noerrno ( void ) {
316 char name
[] = "/tmp/test-close_nointr.XXXXXX" ;
319 fd
= mkostemp_safe ( name
);
321 assert_se ( close_nointr ( fd
) >= 0 );
326 assert_se ( unlink_noerrno ( name
) >= 0 );
327 assert_se ( errno
== - 42 );
328 assert_se ( unlink_noerrno ( name
) < 0 );
329 assert_se ( errno
== - 42 );
333 static void test_readlink_and_make_absolute ( void ) {
334 char tempdir
[] = "/tmp/test-readlink_and_make_absolute" ;
335 char name
[] = "/tmp/test-readlink_and_make_absolute/original" ;
336 char name2
[] = "test-readlink_and_make_absolute/original" ;
337 char name_alias
[] = "/tmp/test-readlink_and_make_absolute-alias" ;
339 _cleanup_free_
char * pwd
= NULL
;
341 assert_se ( mkdir_safe ( tempdir
, 0755 , getuid (), getgid (), MKDIR_WARN_MODE
) >= 0 );
342 assert_se ( touch ( name
) >= 0 );
344 assert_se ( symlink ( name
, name_alias
) >= 0 );
345 assert_se ( readlink_and_make_absolute ( name_alias
, & r
) >= 0 );
346 assert_se ( streq ( r
, name
));
348 assert_se ( unlink ( name_alias
) >= 0 );
350 assert_se ( safe_getcwd (& pwd
) >= 0 );
352 assert_se ( chdir ( tempdir
) >= 0 );
353 assert_se ( symlink ( name2
, name_alias
) >= 0 );
354 assert_se ( readlink_and_make_absolute ( name_alias
, & r
) >= 0 );
355 assert_se ( streq ( r
, name
));
357 assert_se ( unlink ( name_alias
) >= 0 );
359 assert_se ( chdir ( pwd
) >= 0 );
361 assert_se ( rm_rf ( tempdir
, REMOVE_ROOT
| REMOVE_PHYSICAL
) >= 0 );
364 static void test_get_files_in_directory ( void ) {
365 _cleanup_strv_free_
char ** l
= NULL
, ** t
= NULL
;
367 assert_se ( get_files_in_directory ( "/tmp" , & l
) >= 0 );
368 assert_se ( get_files_in_directory ( "." , & t
) >= 0 );
369 assert_se ( get_files_in_directory ( "." , NULL
) >= 0 );
372 static void test_var_tmp ( void ) {
373 _cleanup_free_
char * tmpdir_backup
= NULL
, * temp_backup
= NULL
, * tmp_backup
= NULL
;
374 const char * tmp_dir
= NULL
, * t
;
376 t
= getenv ( "TMPDIR" );
378 tmpdir_backup
= strdup ( t
);
379 assert_se ( tmpdir_backup
);
384 temp_backup
= strdup ( t
);
385 assert_se ( temp_backup
);
390 tmp_backup
= strdup ( t
);
391 assert_se ( tmp_backup
);
394 assert_se ( unsetenv ( "TMPDIR" ) >= 0 );
395 assert_se ( unsetenv ( "TEMP" ) >= 0 );
396 assert_se ( unsetenv ( "TMP" ) >= 0 );
398 assert_se ( var_tmp_dir (& tmp_dir
) >= 0 );
399 assert_se ( streq ( tmp_dir
, "/var/tmp" ));
401 assert_se ( setenv ( "TMPDIR" , "/tmp" , true ) >= 0 );
402 assert_se ( streq ( getenv ( "TMPDIR" ), "/tmp" ));
404 assert_se ( var_tmp_dir (& tmp_dir
) >= 0 );
405 assert_se ( streq ( tmp_dir
, "/tmp" ));
407 assert_se ( setenv ( "TMPDIR" , "/88_does_not_exist_88" , true ) >= 0 );
408 assert_se ( streq ( getenv ( "TMPDIR" ), "/88_does_not_exist_88" ));
410 assert_se ( var_tmp_dir (& tmp_dir
) >= 0 );
411 assert_se ( streq ( tmp_dir
, "/var/tmp" ));
414 assert_se ( setenv ( "TMPDIR" , tmpdir_backup
, true ) >= 0 );
415 assert_se ( streq ( getenv ( "TMPDIR" ), tmpdir_backup
));
419 assert_se ( setenv ( "TEMP" , temp_backup
, true ) >= 0 );
420 assert_se ( streq ( getenv ( "TEMP" ), temp_backup
));
424 assert_se ( setenv ( "TMP" , tmp_backup
, true ) >= 0 );
425 assert_se ( streq ( getenv ( "TMP" ), tmp_backup
));
429 static void test_dot_or_dot_dot ( void ) {
430 assert_se (! dot_or_dot_dot ( NULL
));
431 assert_se (! dot_or_dot_dot ( "" ));
432 assert_se (! dot_or_dot_dot ( "xxx" ));
433 assert_se ( dot_or_dot_dot ( "." ));
434 assert_se ( dot_or_dot_dot ( ".." ));
435 assert_se (! dot_or_dot_dot ( ".foo" ));
436 assert_se (! dot_or_dot_dot ( "..foo" ));
439 static void test_access_fd ( void ) {
440 _cleanup_ ( rmdir_and_freep
) char * p
= NULL
;
441 _cleanup_close_
int fd
= - 1 ;
443 assert_se ( mkdtemp_malloc ( "/tmp/access-fd.XXXXXX" , & p
) >= 0 );
445 fd
= open ( p
, O_RDONLY
| O_DIRECTORY
| O_CLOEXEC
);
448 assert_se ( access_fd ( fd
, R_OK
) >= 0 );
449 assert_se ( access_fd ( fd
, F_OK
) >= 0 );
450 assert_se ( access_fd ( fd
, W_OK
) >= 0 );
452 assert_se ( fchmod ( fd
, 0000 ) >= 0 );
454 assert_se ( access_fd ( fd
, F_OK
) >= 0 );
456 if ( geteuid () == 0 ) {
457 assert_se ( access_fd ( fd
, R_OK
) >= 0 );
458 assert_se ( access_fd ( fd
, W_OK
) >= 0 );
460 assert_se ( access_fd ( fd
, R_OK
) == - EACCES
);
461 assert_se ( access_fd ( fd
, W_OK
) == - EACCES
);
465 static void test_touch_file ( void ) {
466 uid_t test_uid
, test_gid
;
467 _cleanup_ ( rm_rf_physical_and_freep
) char * p
= NULL
;
472 test_uid
= geteuid () == 0 ? 65534 : getuid ();
473 test_gid
= geteuid () == 0 ? 65534 : getgid ();
475 test_mtime
= usec_sub_unsigned ( now ( CLOCK_REALTIME
), USEC_PER_WEEK
);
477 assert_se ( mkdtemp_malloc ( "/dev/shm/touch-file-XXXXXX" , & p
) >= 0 );
479 a
= strjoina ( p
, "/regular" );
480 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
481 assert_se ( lstat ( a
, & st
) >= 0 );
482 assert_se ( st
. st_uid
== test_uid
);
483 assert_se ( st
. st_gid
== test_gid
);
484 assert_se ( S_ISREG ( st
. st_mode
));
485 assert_se (( st
. st_mode
& 0777 ) == 0640 );
486 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
488 a
= strjoina ( p
, "/dir" );
489 assert_se ( mkdir ( a
, 0775 ) >= 0 );
490 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
491 assert_se ( lstat ( a
, & st
) >= 0 );
492 assert_se ( st
. st_uid
== test_uid
);
493 assert_se ( st
. st_gid
== test_gid
);
494 assert_se ( S_ISDIR ( st
. st_mode
));
495 assert_se (( st
. st_mode
& 0777 ) == 0640 );
496 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
498 a
= strjoina ( p
, "/fifo" );
499 assert_se ( mkfifo ( a
, 0775 ) >= 0 );
500 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
501 assert_se ( lstat ( a
, & st
) >= 0 );
502 assert_se ( st
. st_uid
== test_uid
);
503 assert_se ( st
. st_gid
== test_gid
);
504 assert_se ( S_ISFIFO ( st
. st_mode
));
505 assert_se (( st
. st_mode
& 0777 ) == 0640 );
506 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
508 a
= strjoina ( p
, "/sock" );
509 assert_se ( mknod ( a
, 0775 | S_IFSOCK
, 0 ) >= 0 );
510 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
511 assert_se ( lstat ( a
, & st
) >= 0 );
512 assert_se ( st
. st_uid
== test_uid
);
513 assert_se ( st
. st_gid
== test_gid
);
514 assert_se ( S_ISSOCK ( st
. st_mode
));
515 assert_se (( st
. st_mode
& 0777 ) == 0640 );
516 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
518 if ( geteuid () == 0 ) {
519 a
= strjoina ( p
, "/cdev" );
520 assert_se ( mknod ( a
, 0775 | S_IFCHR
, makedev ( 0 , 0 )) >= 0 );
521 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
522 assert_se ( lstat ( a
, & st
) >= 0 );
523 assert_se ( st
. st_uid
== test_uid
);
524 assert_se ( st
. st_gid
== test_gid
);
525 assert_se ( S_ISCHR ( st
. st_mode
));
526 assert_se (( st
. st_mode
& 0777 ) == 0640 );
527 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
529 a
= strjoina ( p
, "/bdev" );
530 assert_se ( mknod ( a
, 0775 | S_IFBLK
, makedev ( 0 , 0 )) >= 0 );
531 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
532 assert_se ( lstat ( a
, & st
) >= 0 );
533 assert_se ( st
. st_uid
== test_uid
);
534 assert_se ( st
. st_gid
== test_gid
);
535 assert_se ( S_ISBLK ( st
. st_mode
));
536 assert_se (( st
. st_mode
& 0777 ) == 0640 );
537 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
540 a
= strjoina ( p
, "/lnk" );
541 assert_se ( symlink ( "target" , a
) >= 0 );
542 assert_se ( touch_file ( a
, false , test_mtime
, test_uid
, test_gid
, 0640 ) >= 0 );
543 assert_se ( lstat ( a
, & st
) >= 0 );
544 assert_se ( st
. st_uid
== test_uid
);
545 assert_se ( st
. st_gid
== test_gid
);
546 assert_se ( S_ISLNK ( st
. st_mode
));
547 assert_se (( st
. st_mode
& 0777 ) == 0640 );
548 assert_se ( timespec_load (& st
. st_mtim
) == test_mtime
);
551 static void test_unlinkat_deallocate ( void ) {
552 _cleanup_free_
char * p
= NULL
;
553 _cleanup_close_
int fd
= - 1 ;
556 assert_se ( tempfn_random_child ( NULL
, "unlink-deallocation" , & p
) >= 0 );
558 fd
= open ( p
, O_WRONLY
| O_CLOEXEC
| O_CREAT
| O_EXCL
, 0600 );
561 assert_se ( write ( fd
, "hallo \n " , 6 ) == 6 );
563 assert_se ( fstat ( fd
, & st
) >= 0 );
564 assert_se ( st
. st_size
== 6 );
565 assert_se ( st
. st_blocks
> 0 );
566 assert_se ( st
. st_nlink
== 1 );
568 assert_se ( unlinkat_deallocate ( AT_FDCWD
, p
, 0 ) >= 0 );
570 assert_se ( fstat ( fd
, & st
) >= 0 );
571 assert_se ( IN_SET ( st
. st_size
, 0 , 6 )); /* depending on whether hole punching worked the size will be 6 (it worked) or 0 (we had to resort to truncation) */
572 assert_se ( st
. st_blocks
== 0 );
573 assert_se ( st
. st_nlink
== 0 );
576 static void test_fsync_directory_of_file ( void ) {
577 _cleanup_close_
int fd
= - 1 ;
579 fd
= open_tmpfile_unlinkable ( NULL
, O_RDWR
);
582 assert_se ( fsync_directory_of_file ( fd
) >= 0 );
585 int main ( int argc
, char * argv
[]) {
586 test_unlink_noerrno ();
587 test_get_files_in_directory ();
588 test_readlink_and_make_absolute ();
590 test_chase_symlinks ();
591 test_dot_or_dot_dot ();
594 test_unlinkat_deallocate ();
595 test_fsync_directory_of_file ();