2 * / \ (C) Copyright 2009 Parliament Hill Computers Ltd.
3 * \ / All rights reserved.
5 * . Author: Alain Williams, <addw@phcomp.co.uk> 2009
7 * . SCCS: @(#)fsync.c 1.3 11/14/11 22:46:01
15 #include <sys/types.h>
27 char* progname; /* What this program is called - name of binary */
28 int exit_c; /* Exit status to return to O/S */
29 int datasync; /* Use fdatasync */
30 int quiet; /* Do not report errors */
31 int verbose; /* Chatty mode */
32 char* flushname; /* Name of how we flush */
33 int (*flushfn)(int); /* Pointer to system call to use */
38 "Ensure that named files are flushed to disk",
39 "Usage: %s [options] file ...",
40 "-d do not flush metadata (fdatasync())",
41 "-q do not report errors (eg file open fails), still set exit code",
44 "Version: 1.3 11/14/11",
45 (char*)NULL /* Must end the list */
48 /* Functions defined in this module, in alphabetic order */
49 void read_opts(int argc, char* argv[]);
50 void usage(int exitc);
51 void process(const char* file);
53 int main(int argc, char* argv[])
55 read_opts(argc, argv);
57 flushname = datasync ? "fdatasync" : "fsync";
58 flushfn = datasync ? fdatasync : fsync;
67 /* Interpret '-' arguments -options.
68 * If there is an error in the arguments, print the options list and exit.
70 void read_opts(int argc, char* argv[])
78 while((c = getopt(argc, argv, "dqvx")) != EOF)
80 case 'd': /* Use fdatasync() */
86 case 'v': /* Verbose */
89 case 'x': /* eXplain */
101 /* Output a usage message and end with exit status exitc.
103 void usage(int exitc)
107 for(mes = usagem; *mes != (char*)NULL; mes++) {
108 (void) fprintf(stderr, *mes, progname);
116 /* Flush the named file to disk -- use the fsync or fdatasync system call
118 void process(const char* file)
123 fprintf(stderr, "%s: about to %s '%s'\n", progname,
126 /* Need to open read/write for fsync to work.
127 * But we can't open directories to write to, so try to open one read only.
128 * Linux (2.6.18 anyway) doesn't seem to check that the fd to fsync is for
129 * writing - but that is what the manual says it must be.
131 if((fd = open(file, O_WRONLY)) == -1 &&
132 (errno == EISDIR && (fd = open(file, O_RDONLY)) == -1)) {
134 fprintf(stderr, "%s: Cannot open '%s' as: %s\n", progname, file,
140 if((*flushfn)(fd) == -1) {
142 fprintf(stderr, "%s: Cannot %s '%s' as: %s\n", progname, flushname, file,
149 fprintf(stderr, "%s: Error on close of '%s' as: %s\n", progname, file,