Erik Andersen | e49d5ec | 2000-02-08 19:58:47 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
Eric Andersen | c499601 | 1999-10-20 22:08:37 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Mini sync implementation for busybox |
| 4 | * |
Eric Andersen | c499601 | 1999-10-20 22:08:37 +0000 | [diff] [blame] | 5 | * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 6 | * Copyright (C) 2015 by Ari Sundholm <ari@tuxera.com> |
Eric Andersen | c499601 | 1999-10-20 22:08:37 +0000 | [diff] [blame] | 7 | * |
Denys Vlasenko | 0ef64bd | 2010-08-16 20:14:46 +0200 | [diff] [blame] | 8 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
Eric Andersen | c499601 | 1999-10-20 22:08:37 +0000 | [diff] [blame] | 9 | */ |
| 10 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 11 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 12 | //config:config SYNC |
| 13 | //config: bool "sync" |
| 14 | //config: default y |
| 15 | //config: help |
| 16 | //config: sync is used to flush filesystem buffers. |
| 17 | //config:config FEATURE_SYNC_FANCY |
| 18 | //config: bool "Enable -d and -f flags (requres syncfs(2) in libc)" |
| 19 | //config: default y |
| 20 | //config: depends on SYNC |
| 21 | //config: help |
| 22 | //config: sync -d FILE... executes fdatasync() on each FILE. |
| 23 | //config: sync -f FILE... executes syncfs() on each FILE. |
| 24 | |
| 25 | //kbuild:lib-$(CONFIG_SYNC) += sync.o |
| 26 | //applet:IF_SYNC(APPLET_NOFORK(sync, sync, BB_DIR_BIN, BB_SUID_DROP, sync)) |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 27 | |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 28 | //usage:#define sync_trivial_usage |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 29 | //usage: ""IF_FEATURE_SYNC_FANCY("[-df] [FILE]...") |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 30 | //usage:#define sync_full_usage "\n\n" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 31 | //usage: IF_NOT_FEATURE_SYNC_FANCY( |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 32 | //usage: "Write all buffered blocks to disk" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 33 | //usage: ) |
| 34 | //usage: IF_FEATURE_SYNC_FANCY( |
| 35 | //usage: "Write all buffered blocks (in FILEs) to disk" |
| 36 | //usage: "\n -d Avoid syncing metadata" |
| 37 | //usage: "\n -f Sync filesystems underlying FILEs" |
| 38 | //usage: ) |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 39 | |
Denis Vlasenko | b6adbf1 | 2007-05-26 19:00:18 +0000 | [diff] [blame] | 40 | #include "libbb.h" |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 41 | |
Denis Vlasenko | 99912ca | 2007-04-10 15:43:37 +0000 | [diff] [blame] | 42 | /* This is a NOFORK applet. Be very careful! */ |
| 43 | |
Denis Vlasenko | 9b49a5e | 2007-10-11 10:05:36 +0000 | [diff] [blame] | 44 | int sync_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
Denys Vlasenko | bb16f57 | 2010-01-13 22:43:13 +0100 | [diff] [blame] | 45 | int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 46 | { |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 47 | #if !ENABLE_FEATURE_SYNC_FANCY |
Denis Vlasenko | 68404f1 | 2008-03-17 09:00:54 +0000 | [diff] [blame] | 48 | /* coreutils-6.9 compat */ |
Denys Vlasenko | a355da0 | 2010-01-04 13:16:08 +0100 | [diff] [blame] | 49 | bb_warn_ignoring_args(argv[1]); |
Glenn L McGrath | a9c6976 | 2001-02-16 10:21:35 +0000 | [diff] [blame] | 50 | sync(); |
Denis Vlasenko | 079f8af | 2006-11-27 16:49:31 +0000 | [diff] [blame] | 51 | return EXIT_SUCCESS; |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame^] | 52 | #else |
| 53 | unsigned opts; |
| 54 | int ret = EXIT_SUCCESS; |
| 55 | |
| 56 | enum { |
| 57 | OPT_DATASYNC = (1 << 0), |
| 58 | OPT_SYNCFS = (1 << 1), |
| 59 | }; |
| 60 | |
| 61 | opt_complementary = "d--f:f--d"; |
| 62 | opts = getopt32(argv, "df"); |
| 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 |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 102 | } |