diff options
Diffstat (limited to 'coreutils/sync.c')
-rw-r--r-- | coreutils/sync.c | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/coreutils/sync.c b/coreutils/sync.c index 7d98a1e..974e904 100644 --- a/coreutils/sync.c +++ b/coreutils/sync.c @@ -3,16 +3,39 @@ * Mini sync implementation for busybox * * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. + * Copyright (C) 2015 by Ari Sundholm <ari@tuxera.com> * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ +//config:config SYNC +//config: bool "sync" +//config: default y +//config: help +//config: sync is used to flush filesystem buffers. +//config:config FEATURE_SYNC_FANCY +//config: bool "Enable -d and -f flags (requres syncfs(2) in libc)" +//config: default y +//config: depends on SYNC +//config: help +//config: sync -d FILE... executes fdatasync() on each FILE. +//config: sync -f FILE... executes syncfs() on each FILE. + +//kbuild:lib-$(CONFIG_SYNC) += sync.o +//applet:IF_SYNC(APPLET_NOFORK(sync, sync, BB_DIR_BIN, BB_SUID_DROP, sync)) //usage:#define sync_trivial_usage -//usage: "" +//usage: ""IF_FEATURE_SYNC_FANCY("[-df] [FILE]...") //usage:#define sync_full_usage "\n\n" +//usage: IF_NOT_FEATURE_SYNC_FANCY( //usage: "Write all buffered blocks to disk" +//usage: ) +//usage: IF_FEATURE_SYNC_FANCY( +//usage: "Write all buffered blocks (in FILEs) to disk" +//usage: "\n -d Avoid syncing metadata" +//usage: "\n -f Sync filesystems underlying FILEs" +//usage: ) #include "libbb.h" @@ -21,10 +44,59 @@ int sync_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) { +#if !ENABLE_FEATURE_SYNC_FANCY /* coreutils-6.9 compat */ bb_warn_ignoring_args(argv[1]); - sync(); - return EXIT_SUCCESS; +#else + unsigned opts; + int ret = EXIT_SUCCESS; + + enum { + OPT_DATASYNC = (1 << 0), + OPT_SYNCFS = (1 << 1), + }; + + opt_complementary = "d--f:f--d"; + opts = getopt32(argv, "df"); + argv += optind; + + /* Handle the no-argument case. */ + if (!argv[0]) + sync(); + + while (*argv) { + int fd = open_or_warn(*argv, O_RDONLY); + + if (fd < 0) { + ret = EXIT_FAILURE; + goto next; + } + if (opts & OPT_DATASYNC) { + if (fdatasync(fd)) + goto err; + goto do_close; + } + if (opts & OPT_SYNCFS) { + /* + * syncfs is documented to only fail with EBADF, + * which can't happen here. So, no error checks. + */ + syncfs(fd); + goto do_close; + } + if (fsync(fd)) { + err: + bb_simple_perror_msg(*argv); + ret = EXIT_FAILURE; + } + do_close: + close(fd); + next: + ++argv; + } + + return ret; +#endif } |