1 #include "compat-util.h"
6 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
7 static int have_fdatasync
= 1;
9 static int have_fdatasync
;
12 /* TODO: sync_file_range() if on Linux */
14 static int usage(const char * argv0
)
16 fprintf(stderr
, "Usage: %s [-d] [-D] FILE...\n", argv0
);
20 #define FN_NOT_FOUND ((void *)(1))
22 static int fs_sync(const char *path
)
25 #if defined(__linux__) && defined(RTLD_NEXT)
26 static int (*syncfs_fn
)(int);
28 if (syncfs_fn
== NULL
) {
29 syncfs_fn
= dlsym(RTLD_DEFAULT
, "syncfs");
30 if (syncfs_fn
== NULL
|| dlerror())
31 syncfs_fn
= FN_NOT_FOUND
;
33 if (syncfs_fn
!= NULL
&& syncfs_fn
!= FN_NOT_FOUND
) {
34 int fd
= open(path
, O_RDONLY
|O_NOATIME
);
43 * if glibc has syncfs(2) but we're running an
44 * old kernel, fall back to sync(2) below
51 #endif /* ! __linux__ */
56 static int do_sync(const char *path
, int data_only
, int directory
)
59 const char *errfunc
= "";
61 if ((fd
= open(path
, O_RDWR
|O_NOATIME
)) < 0) {
62 if (errno
== EISDIR
) {
70 if (data_only
&& have_fdatasync
) {
71 if (fdatasync(fd
) < 0) {
72 errfunc
= "fdatasync";
92 if (!(dpath
= strdup(path
))){
96 if (!(dir
= opendir(dirname(dpath
)))) {
100 if (fsync(dirfd(dir
)) < 0) {
101 errfunc
= "(directory) fsync";
104 if (closedir(dir
) < 0) {
105 errfunc
= "closedir";
113 fprintf(stderr
, "%s: %s(): %s\n", path
, errfunc
, strerror(errno
));
117 int main(int argc
, char * const argv
[])
125 while ((opt
= getopt(argc
, argv
, "dDf")) != -1) {
138 return usage(argv
[0]);
143 return usage(argv
[0]);
145 for (; argi
< argc
; ++argi
) {
147 if (fs_sync(argv
[argi
]) < 0)
150 if (do_sync(argv
[argi
], data_only
, directory
) < 0)