diff options
author | Thomas Voss <mail@thomasvoss.com> | 2023-12-10 00:39:16 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2023-12-10 00:39:37 +0100 |
commit | 03f8544691a8de9f77a803fd8cd2eeadb919ec03 (patch) | |
tree | 4d3431d678b892cb057af72a982ac73d313d60f9 /c |
Genesis commit
Diffstat (limited to 'c')
-rw-r--r-- | c/.gitignore | 3 | ||||
-rw-r--r-- | c/base.mk | 4 | ||||
-rw-r--r-- | c/cat/.gitignore | 1 | ||||
-rw-r--r-- | c/cat/Makefile | 8 | ||||
-rw-r--r-- | c/cat/cat.c | 102 | ||||
-rw-r--r-- | c/sigfd/.gitignore | 1 | ||||
-rw-r--r-- | c/sigfd/Makefile | 8 | ||||
-rw-r--r-- | c/sigfd/main.c | 42 | ||||
-rw-r--r-- | c/timer/.gitignore | 1 | ||||
-rw-r--r-- | c/timer/Makefile | 11 | ||||
-rw-r--r-- | c/timer/main.c | 48 |
11 files changed, 229 insertions, 0 deletions
diff --git a/c/.gitignore b/c/.gitignore new file mode 100644 index 0000000..b8be893 --- /dev/null +++ b/c/.gitignore @@ -0,0 +1,3 @@ +.cache/ +compile_commands.json +*.o diff --git a/c/base.mk b/c/base.mk new file mode 100644 index 0000000..7aea715 --- /dev/null +++ b/c/base.mk @@ -0,0 +1,4 @@ +CC = cc +CFLAGS = \ + -Wall -Wextra -Werror -Wpedantic -pipe \ + -O3 -flto -march=native -mtune=native diff --git a/c/cat/.gitignore b/c/cat/.gitignore new file mode 100644 index 0000000..ef07ddc --- /dev/null +++ b/c/cat/.gitignore @@ -0,0 +1 @@ +cat diff --git a/c/cat/Makefile b/c/cat/Makefile new file mode 100644 index 0000000..081ffd4 --- /dev/null +++ b/c/cat/Makefile @@ -0,0 +1,8 @@ +include ../base.mk + +all: cat +cat: cat.c + $(CC) $(CFLAGS) -o $@ $< + +clean: + rm -f cat diff --git a/c/cat/cat.c b/c/cat/cat.c new file mode 100644 index 0000000..7aaaa6b --- /dev/null +++ b/c/cat/cat.c @@ -0,0 +1,102 @@ +#include <sys/sendfile.h> +#include <sys/stat.h> + +#include <err.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#define warn(...) \ + do { \ + warn(__VA_ARGS__); \ + rv = EXIT_FAILURE; \ + } while (0) + +static int rv = EXIT_SUCCESS; +static bool out_is_reg; +static char buf[BUFSIZ]; + +static void cat(const char *); +static void cat_sendfile(const char *, int, size_t); +static void cat_readwrite(const char *, int); + +int +main(int argc, char **argv) +{ + struct stat sb; + + if (fstat(STDOUT_FILENO, &sb) == -1) + warn("fstat: /dev/stdout"); + else + out_is_reg = S_ISREG(sb.st_mode); + + if (argc == 1) + cat("-"); + for (int i = 1; i < argc; i++) + cat(argv[i]); + return rv; +} + +void +cat(const char *file) +{ + int fd; + struct stat sb; + + if (strcmp(file, "-") == 0) + fd = STDIN_FILENO; + else if ((fd = open(file, O_RDONLY)) == -1) { + warn("open: %s", file); + return; + } + + if (fstat(fd, &sb) == -1) { + warn("fstat: %s", file); + goto out; + } + + if (S_ISREG(sb.st_mode) && out_is_reg) + cat_sendfile(file, fd, sb.st_size); + else + cat_readwrite(file, fd); + +out: + close(fd); +} + +void +cat_sendfile(const char *file, int fd, size_t n) +{ + off_t off = 0; + ssize_t nw; + + do { + nw = sendfile(STDOUT_FILENO, fd, &off, n); + off += nw; + } while (nw != -1 && (size_t)off < n); + + if (nw == -1) + warn("sendfile: %s", file); +} + +void +cat_readwrite(const char *file, int fd) +{ + ssize_t nr, nw; + + while ((nr = read(fd, buf, BUFSIZ)) > 0) { + for (ssize_t off = 0; nr > 0; nr -= nw, off += nw) { + if ((nw = write(STDOUT_FILENO, buf + off, nr)) == -1) { + warn("write: %s", file); + return; + } + } + } + if (nr == -1) + warn("read: %s", file); +} diff --git a/c/sigfd/.gitignore b/c/sigfd/.gitignore new file mode 100644 index 0000000..067fa65 --- /dev/null +++ b/c/sigfd/.gitignore @@ -0,0 +1 @@ +sigfd diff --git a/c/sigfd/Makefile b/c/sigfd/Makefile new file mode 100644 index 0000000..f126000 --- /dev/null +++ b/c/sigfd/Makefile @@ -0,0 +1,8 @@ +include ../base.mk + +all: sigfd +sigfd: main.c + $(CC) $(CFLAGS) -o $@ $< + +clean: + rm -f sigfd diff --git a/c/sigfd/main.c b/c/sigfd/main.c new file mode 100644 index 0000000..6721f60 --- /dev/null +++ b/c/sigfd/main.c @@ -0,0 +1,42 @@ +#include <sys/poll.h> +#include <sys/signalfd.h> + +#include <err.h> +#include <poll.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define die(...) err(EXIT_FAILURE, __VA_ARGS__) +#define lengthof(a) (sizeof(a) / sizeof(*(a))) + +static char buf[4096]; + +int +main(void) +{ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGQUIT); + sigprocmask(SIG_BLOCK, &set, NULL); + + int fd = signalfd(-1, &set, 0); + if (fd == -1) + die("signalfd"); + + struct pollfd fds[] = { + {.fd = fd, .events = POLL_IN}, + }; + for (;;) { + if (poll(fds, lengthof(fds), -1) == -1) + die("poll"); + if (fds[0].revents & POLL_IN) { + fputs("Caught signal!\n", stderr); + read(fds[0].fd, buf, sizeof(buf)); + } + } + + return EXIT_SUCCESS; +} diff --git a/c/timer/.gitignore b/c/timer/.gitignore new file mode 100644 index 0000000..fe84f2c --- /dev/null +++ b/c/timer/.gitignore @@ -0,0 +1 @@ +timer diff --git a/c/timer/Makefile b/c/timer/Makefile new file mode 100644 index 0000000..410dc79 --- /dev/null +++ b/c/timer/Makefile @@ -0,0 +1,11 @@ +include ../base.mk + +CFLAGS := $(CFLAGS) $(shell pkg-config --cflags libnotify) -D_ISOC99_SOURCE +LDLIBS = $(shell pkg-config --libs libnotify) + +all: timer +timer: main.c + $(CC) $(CFLAGS) $(LDLIBS) -o $@ $< + +clean: + rm -f timer diff --git a/c/timer/main.c b/c/timer/main.c new file mode 100644 index 0000000..751cbca --- /dev/null +++ b/c/timer/main.c @@ -0,0 +1,48 @@ +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <libnotify/notify.h> + +#define die(...) err(EXIT_FAILURE, __VA_ARGS__) +#define diex(...) errx(EXIT_FAILURE, __VA_ARGS__) + +static char buf[128]; + +int +main(int argc, char **argv) +{ + char *endptr; + long secs; + + if (argc != 3) { + fprintf(stderr, "Usage: %s secs body\n", argv[0]); + exit(EXIT_FAILURE); + } + + errno = 0; + secs = strtol(argv[1], &endptr, 10); + if (errno) + die("strtol: %s", argv[1]); + if (endptr == argv[1] || *endptr) + diex("Invalid integer: %s", argv[1]); + + snprintf(buf, sizeof(buf), "%ld Second%s Elapsed", secs, + secs == 1 ? "" : "s"); + + notify_init("TIMER"); + NotifyNotification *n = + notify_notification_new(buf, argv[2], "dialog-information"); + + notify_notification_set_timeout(n, 5000); + while ((secs = sleep(secs))) + sleep(secs); + if (!notify_notification_show(n, NULL)) + diex("Failed to send notification"); + + g_object_unref(G_OBJECT(n)); + notify_uninit(); + return EXIT_SUCCESS; +} |