From c68d7136feaa17f2ddfd4d56a325aeae8f8eec96 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Fri, 12 May 2023 18:35:41 -0400 Subject: [PATCH] sync --- Makefile | 10 +++++- command/sync.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ command/tee.c | 6 ++-- readme.md | 3 +- src/command.h | 3 +- src/main.c | 6 ++-- 6 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 command/sync.c diff --git a/Makefile b/Makefile index 07ffbf4..24c88a5 100644 --- a/Makefile +++ b/Makefile @@ -11,12 +11,20 @@ PATCH = 1 INCFLAGS = $(shell echo $(SOURCE) | xargs printf -- '-I%s ') CCFLAGS = -std=c89 -Wall -Wextra -pedantic -O2 -CCFLAGS += -D_DEFAULT_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH) -DCHECK_LINK +CCFLAGS += -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH) -DCHECK_LINK CCFLAGS += $(INCFLAGS) LDFLAGS = -s LDFLAGS += $(INCFLAGS) +UNAME := $(shell uname) + +ifeq ($(UNAME), Linux) +CCFLAGS += -D_GNU_SOURCE +else +CCFLAGS += -D_DEFAULT_SOURCE +endif + BIN = bin APP = $(BIN)/app SRC = $(shell find $(SOURCE) -name "*.c") 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 +#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; +} diff --git a/command/tee.c b/command/tee.c index 0462517..364a13d 100644 --- a/command/tee.c +++ b/command/tee.c @@ -12,8 +12,8 @@ static struct { static void help(void) { printf("Usage: tee [-ai] [FILE]...\n\n"); printf("Copy stdin to each FILE, and also to stdout\n\n"); - printf("\t-a Append to the given FILEs, don't overwrite\n"); - printf("\t-i Ignore interrupt signals (SIGINT)\n"); + printf("\t-a\tAppend to the given FILEs, don't overwrite\n"); + printf("\t-i\tIgnore interrupt signals (SIGINT)\n"); exit(EXIT_SUCCESS); } @@ -52,7 +52,7 @@ static int short_arg(char c, char* next) { return ARG_UNUSED; } -COMMAND(tee) { +COMMAND(tee_cmd) { int start, i; FILE** files; diff --git a/readme.md b/readme.md index 6eed372..3e34252 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,8 @@ A terrible busybox/gnu coreutils clone. Currently the only supported commands are: -`dd`, `cat`, `yes`, `echo`, `printf`, `id`, `groups`, `ls`, `tail`, `head`, `ed`, `tee`, `true`, `false`, `tee`, `whoami`, `wc`, `xargs`, `tac`, `rm`, `cp`, `mkdir`, `mv`, `grep`, `chown`, `chmod` +`dd`, `cat`, `yes`, `echo`, `printf`, `id`, `groups`, `ls`, `tail`, `head`, `ed`, `tee`, `true`, `false`, `tee`, `whoami`, +`wc`, `xargs`, `tac`, `rm`, `cp`, `mkdir`, `mv`, `grep`, `chown`, `chmod`, `sync` ## How to diff --git a/src/command.h b/src/command.h index fa8b00c..7827174 100644 --- a/src/command.h +++ b/src/command.h @@ -16,7 +16,7 @@ COMMAND(ls); COMMAND(tail); COMMAND(head); COMMAND(ed); -COMMAND(tee); +COMMAND(tee_cmd); COMMAND(whoami); COMMAND(wc); COMMAND(xargs); @@ -28,5 +28,6 @@ COMMAND(mv); COMMAND(grep); COMMAND(chown_cmd); COMMAND(chmod_cmd); +COMMAND(sync_cmd); #endif diff --git a/src/main.c b/src/main.c index 2718041..1897f5c 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,7 @@ int main (ARGUMENTS) { if (argc < 2) { printf("usage: lazysphere [function [arguments]...]\n\n"); printf("currently defined functions:\n"); - printf("\tdd, cat, yes, echo, printf, id, groups, ls, tail, head, ed, tee, true, false, tee, whoami, wc, xargs, tac, rm, cp, mkdir, mv, grep, chown, chmod\n"); + printf("\tdd, cat, yes, echo, printf, id, groups, ls, tail, head, ed, tee, true, false, tee, whoami, wc, xargs, tac, rm, cp, mkdir, mv, grep, chown, chmod, sync\n"); return EXIT_SUCCESS; } argc--; @@ -62,7 +62,7 @@ int main (ARGUMENTS) { } else if (streql(cmd, "ed")) { return ed(NEXT_ARGS); } else if (streql(cmd, "tee")) { - return tee(NEXT_ARGS); + return tee_cmd(NEXT_ARGS); } else if (streql(cmd, "true")) { return EXIT_SUCCESS; } else if (streql(cmd, "false")) { @@ -89,6 +89,8 @@ int main (ARGUMENTS) { return chown_cmd(NEXT_ARGS); } else if (streql(cmd, "chmod")) { return chmod_cmd(NEXT_ARGS); + } else if (streql(cmd, "sync")) { + return sync_cmd(NEXT_ARGS); } else { fprintf(stderr, "lazysphere: invalid command %s\n", cmd); return EXIT_FAILURE;