#include "args.h" #include "command.h" #include "lslib.h" #define _X_OPEN_SOURCE 500 #include #include #include #include #include static struct { bool sync_fs; bool sync_data; } flags; static void help (void) { printf("Usage: sync [-df] [FILE]...\n\n"); printf("Write all buffered blocks (in FILEs) to disk\n\n"); printf("\t-d\tAvoid syncing metadata\n"); #ifdef _GNU_SOURCE printf("\t-f\tSync filesystems underlying FILEs\n"); #endif } static int short_arg (char c, char* next) { UNUSED(next); switch (c) { case 'd': flags.sync_data = true; break; #ifdef _GNU_SOURCE case 'f': flags.sync_fs = true; break; #endif default: return ARG_INVALID; } return ARG_UNUSED; } static bool sync_file(char* path) { int fd; int ret; fd = open(path, O_NOCTTY | O_RDONLY | O_NONBLOCK); if (fd < 0) { return false; } if (flags.sync_fs) { #ifdef _GNU_SOURCE ret = syncfs(fd) >= 0; #else ret = 0; #endif } else { ret = flags.sync_data ? fdatasync(fd) : fsync(fd); if (ret < 0) { error_s("failed to sync '%s': %s", path, strerror(errno)); } } close(fd); return ret; } COMMAND(sync_cmd) { int start, i, ret = EXIT_SUCCESS; start = parse_args(argc, argv, help, short_arg, NULL); if (argc - start < 1) { sync(); return EXIT_SUCCESS; } for (i = start; i < argc; i++) { if (!sync_file(argv[i])) ret = EXIT_FAILURE; } return ret; }