diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-12 18:35:41 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-12 18:35:41 -0400 |
commit | c68d7136feaa17f2ddfd4d56a325aeae8f8eec96 (patch) | |
tree | 32d3a2ac655b1a0a16ef6549c117b0fbf4106797 /command/sync.c | |
parent | chown, chmod (diff) | |
download | lazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.tar.gz lazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.tar.bz2 lazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.zip |
sync
Diffstat (limited to 'command/sync.c')
-rw-r--r-- | command/sync.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/command/sync.c b/command/sync.c new file mode 100644 index 0000000..797d7a5 --- /dev/null +++ b/command/sync.c @@ -0,0 +1,85 @@ +#include "args.h" +#include "command.h" +#include "lslib.h" + +#define _X_OPEN_SOURCE 500 +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +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; +} |