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 | */ |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 10 | //config:config SYNC |
Denys Vlasenko | b097a84 | 2018-12-28 03:20:17 +0100 | [diff] [blame] | 11 | //config: bool "sync (3.8 kb)" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 12 | //config: default y |
| 13 | //config: help |
Denys Vlasenko | 72089cf | 2017-07-21 09:50:55 +0200 | [diff] [blame] | 14 | //config: sync is used to flush filesystem buffers. |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 15 | //config:config FEATURE_SYNC_FANCY |
Denys Vlasenko | e695ac9 | 2016-07-19 17:48:55 +0200 | [diff] [blame] | 16 | //config: bool "Enable -d and -f flags (requires syncfs(2) in libc)" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 17 | //config: default y |
| 18 | //config: depends on SYNC |
| 19 | //config: help |
Denys Vlasenko | 72089cf | 2017-07-21 09:50:55 +0200 | [diff] [blame] | 20 | //config: sync -d FILE... executes fdatasync() on each FILE. |
| 21 | //config: sync -f FILE... executes syncfs() on each FILE. |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 22 | |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 23 | // APPLET_NOFORK:name main location suid_type help |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 24 | //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] | 25 | |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 26 | //kbuild:lib-$(CONFIG_SYNC) += sync.o |
| 27 | |
| 28 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
| 29 | |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 30 | //usage:#define sync_trivial_usage |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 31 | //usage: ""IF_FEATURE_SYNC_FANCY("[-df] [FILE]...") |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 32 | //usage:#define sync_full_usage "\n\n" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 33 | //usage: IF_NOT_FEATURE_SYNC_FANCY( |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 34 | //usage: "Write all buffered blocks to disk" |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 35 | //usage: ) |
| 36 | //usage: IF_FEATURE_SYNC_FANCY( |
| 37 | //usage: "Write all buffered blocks (in FILEs) to disk" |
| 38 | //usage: "\n -d Avoid syncing metadata" |
| 39 | //usage: "\n -f Sync filesystems underlying FILEs" |
| 40 | //usage: ) |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 41 | |
Denis Vlasenko | b6adbf1 | 2007-05-26 19:00:18 +0000 | [diff] [blame] | 42 | #include "libbb.h" |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 43 | |
Denis Vlasenko | 99912ca | 2007-04-10 15:43:37 +0000 | [diff] [blame] | 44 | /* This is a NOFORK applet. Be very careful! */ |
| 45 | |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 46 | #if ENABLE_FEATURE_SYNC_FANCY || ENABLE_FSYNC |
| 47 | static int sync_common(int opts, char **argv) |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 48 | { |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 49 | int ret; |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 50 | enum { |
| 51 | OPT_DATASYNC = (1 << 0), |
| 52 | OPT_SYNCFS = (1 << 1), |
| 53 | }; |
| 54 | |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 55 | ret = EXIT_SUCCESS; |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 56 | do { |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 57 | /* GNU "sync FILE" uses O_NONBLOCK open */ |
| 58 | int fd = open_or_warn(*argv, /*O_NOATIME |*/ O_NOCTTY | O_RDONLY | O_NONBLOCK); |
| 59 | /* open(NOATIME) can only be used by owner or root, don't use NOATIME here */ |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 60 | |
| 61 | if (fd < 0) { |
| 62 | ret = EXIT_FAILURE; |
| 63 | goto next; |
| 64 | } |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 65 | # if ENABLE_FEATURE_SYNC_FANCY |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 66 | if (opts & OPT_SYNCFS) { |
| 67 | /* |
| 68 | * syncfs is documented to only fail with EBADF, |
| 69 | * which can't happen here. So, no error checks. |
| 70 | */ |
| 71 | syncfs(fd); |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 72 | } else |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 73 | # endif |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 74 | if (((opts & OPT_DATASYNC) ? fdatasync(fd) : fsync(fd)) != 0) { |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 75 | bb_simple_perror_msg(*argv); |
| 76 | ret = EXIT_FAILURE; |
| 77 | } |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 78 | close(fd); |
| 79 | next: |
Denys Vlasenko | 4f74bb6 | 2019-04-02 14:39:56 +0200 | [diff] [blame] | 80 | argv++; |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 81 | } while (*argv); |
Denys Vlasenko | 35ae2cc | 2015-07-21 19:50:48 +0200 | [diff] [blame] | 82 | |
| 83 | return ret; |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 84 | } |
Denys Vlasenko | 2f28b2b | 2019-04-02 14:54:56 +0200 | [diff] [blame] | 85 | #endif |
| 86 | |
| 87 | #if ENABLE_SYNC |
| 88 | int sync_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 89 | int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) |
| 90 | { |
| 91 | # if !ENABLE_FEATURE_SYNC_FANCY |
| 92 | /* coreutils-6.9 compat */ |
| 93 | bb_warn_ignoring_args(argv[1]); |
| 94 | sync(); |
| 95 | return EXIT_SUCCESS; |
| 96 | # else |
| 97 | unsigned opts = getopt32(argv, "^" "df" "\0" "d--f:f--d"); |
| 98 | argv += optind; |
| 99 | if (!argv[0]) { |
| 100 | sync(); |
| 101 | return EXIT_SUCCESS; |
| 102 | } |
| 103 | return sync_common(opts, argv); |
| 104 | # endif |
| 105 | } |
| 106 | #endif |
| 107 | |
| 108 | /* |
| 109 | * Mini fsync implementation for busybox |
| 110 | * |
| 111 | * Copyright (C) 2008 Nokia Corporation. All rights reserved. |
| 112 | * |
| 113 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
| 114 | */ |
| 115 | //config:config FSYNC |
| 116 | //config: bool "fsync (3.6 kb)" |
| 117 | //config: default y |
| 118 | //config: help |
| 119 | //config: fsync is used to flush file-related cached blocks to disk. |
| 120 | |
| 121 | // APPLET_NOFORK:name main location suid_type help |
| 122 | //applet:IF_FSYNC(APPLET_NOFORK(fsync, fsync, BB_DIR_BIN, BB_SUID_DROP, fsync)) |
| 123 | |
| 124 | //kbuild:lib-$(CONFIG_FSYNC) += sync.o |
| 125 | |
| 126 | //usage:#define fsync_trivial_usage |
| 127 | //usage: "[-d] FILE..." |
| 128 | //usage:#define fsync_full_usage "\n\n" |
| 129 | //usage: "Write all buffered blocks in FILEs to disk\n" |
| 130 | //usage: "\n -d Avoid syncing metadata" |
| 131 | |
| 132 | #if ENABLE_FSYNC |
| 133 | int fsync_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 134 | int fsync_main(int argc UNUSED_PARAM, char **argv) |
| 135 | { |
| 136 | int opts = getopt32(argv, "^" "d" "\0" "-1"/*min 1 arg*/); |
| 137 | argv += optind; |
| 138 | return sync_common(opts, argv); |
| 139 | } |
| 140 | #endif |