busybox/coreutils/sync.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Mini sync implementation for busybox
   4 *
   5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
   6 * Copyright (C) 2015 by Ari Sundholm <ari@tuxera.com>
   7 *
   8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   9 */
  10//config:config SYNC
  11//config:       bool "sync (3.8 kb)"
  12//config:       default y
  13//config:       help
  14//config:       sync is used to flush filesystem buffers.
  15//config:config FEATURE_SYNC_FANCY
  16//config:       bool "Enable -d and -f flags (requires syncfs(2) in libc)"
  17//config:       default y
  18//config:       depends on SYNC
  19//config:       help
  20//config:       sync -d FILE... executes fdatasync() on each FILE.
  21//config:       sync -f FILE... executes syncfs() on each FILE.
  22
  23//applet:IF_SYNC(APPLET_NOFORK(sync, sync, BB_DIR_BIN, BB_SUID_DROP, sync))
  24
  25//kbuild:lib-$(CONFIG_SYNC) += sync.o
  26
  27/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
  28
  29//usage:#define sync_trivial_usage
  30//usage:       ""IF_FEATURE_SYNC_FANCY("[-df] [FILE]...")
  31//usage:#define sync_full_usage "\n\n"
  32//usage:    IF_NOT_FEATURE_SYNC_FANCY(
  33//usage:       "Write all buffered blocks to disk"
  34//usage:    )
  35//usage:    IF_FEATURE_SYNC_FANCY(
  36//usage:       "Write all buffered blocks (in FILEs) to disk"
  37//usage:     "\n        -d      Avoid syncing metadata"
  38//usage:     "\n        -f      Sync filesystems underlying FILEs"
  39//usage:    )
  40
  41#include "libbb.h"
  42
  43/* This is a NOFORK applet. Be very careful! */
  44
  45int sync_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  46int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
  47{
  48#if !ENABLE_FEATURE_SYNC_FANCY
  49        /* coreutils-6.9 compat */
  50        bb_warn_ignoring_args(argv[1]);
  51        sync();
  52        return EXIT_SUCCESS;
  53#else
  54        unsigned opts;
  55        int ret = EXIT_SUCCESS;
  56
  57        enum {
  58                OPT_DATASYNC = (1 << 0),
  59                OPT_SYNCFS   = (1 << 1),
  60        };
  61
  62        opts = getopt32(argv, "^" "df" "\0" "d--f:f--d");
  63        argv += optind;
  64
  65        /* Handle the no-argument case. */
  66        if (!argv[0])
  67                sync();
  68
  69        while (*argv) {
  70                int fd = open_or_warn(*argv, O_RDONLY);
  71
  72                if (fd < 0) {
  73                        ret = EXIT_FAILURE;
  74                        goto next;
  75                }
  76                if (opts & OPT_DATASYNC) {
  77                        if (fdatasync(fd))
  78                                goto err;
  79                        goto do_close;
  80                }
  81                if (opts & OPT_SYNCFS) {
  82                        /*
  83                         * syncfs is documented to only fail with EBADF,
  84                         * which can't happen here. So, no error checks.
  85                         */
  86                        syncfs(fd);
  87                        goto do_close;
  88                }
  89                if (fsync(fd)) {
  90 err:
  91                        bb_simple_perror_msg(*argv);
  92                        ret = EXIT_FAILURE;
  93                }
  94 do_close:
  95                close(fd);
  96 next:
  97                ++argv;
  98        }
  99
 100        return ret;
 101#endif
 102}
 103