summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-05-12 18:35:41 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-05-12 18:35:41 -0400
commitc68d7136feaa17f2ddfd4d56a325aeae8f8eec96 (patch)
tree32d3a2ac655b1a0a16ef6549c117b0fbf4106797
parentchown, chmod (diff)
downloadlazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.tar.gz
lazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.tar.bz2
lazysphere-c68d7136feaa17f2ddfd4d56a325aeae8f8eec96.zip
sync
-rw-r--r--Makefile10
-rw-r--r--command/sync.c85
-rw-r--r--command/tee.c6
-rw-r--r--readme.md3
-rw-r--r--src/command.h3
-rw-r--r--src/main.c6
6 files changed, 105 insertions, 8 deletions
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 <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;
+}
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;