diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | cat.c | 41 | ||||
-rw-r--r-- | fallocate.c | 59 | ||||
-rw-r--r-- | panic.c | 14 | ||||
-rw-r--r-- | panic.h | 6 |
6 files changed, 133 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b0dc11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +cat +fallocate diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2027646 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CFLAGS+=-std=c11 -Wall -Wextra -Wpedantic -D_POSIX_C_SOURCE=200809L + +all: cat fallocate + +cat: cat.o panic.o + +clean: + rm -f *.o cat fallocate + +.PHONY: all clean @@ -0,0 +1,41 @@ +#include <errno.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +#include "panic.h" + + +void cat(int fd, char * name) +{ + char buffer[4096]; + size_t length; + while (0 < (length=read(fd, buffer, sizeof(buffer)))) + if (length != write(1, buffer, length)) + panic("write: %s: %s", name, strerror(errno)); + if (0 > length) + panic("read: %s: %s", name, strerror(errno)); +} + + +int main(int argc, char * argv[]) +{ + int i; + int fd; + if (1 == argc) + cat(0, "<stdin>"); + else for (i = 1; i < argc; ++i) + { + fd = open(argv[i], O_RDONLY); + if (0 > fd) + panic("open: %s: %s", argv[i], strerror(errno)); + else + { + cat(fd, argv[i]); + close(fd); + } + } +} diff --git a/fallocate.c b/fallocate.c new file mode 100644 index 0000000..910d191 --- /dev/null +++ b/fallocate.c @@ -0,0 +1,59 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +#define EXIT_BAD_OPTION 2 + + +void usage(int fd, char * progname) +{ + dprintf(fd, "Usage: %s [-o offset] -l length name\n", progname); +} + + +int try_fallocate(char * filename, int offset, int length) +{ + int fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0644); + if (-1 == fd) return -1; + int res = posix_fallocate(fd, offset, length); + if (-1 == res) return -1; + res = close(fd); + if (-1 == res) return -1; + return 0; +} + + +int main(int argc, char * argv[]) +{ + int opt; + int offset = 0; + int length = 0; + char * filename; + while (-1 != (opt = getopt(argc, argv, "o:l:"))) { + switch (opt) { + case 'o': + offset = atoi(optarg); + break; + case 'l': + length = atoi(optarg); + break; + default: + usage(2, argv[0]); + exit(EXIT_BAD_OPTION); + } + } + if (0 >= length || argc <= optind) { + usage(2, argv[0]); + exit(EXIT_BAD_OPTION); + } + filename = argv[optind]; + int res = try_fallocate(filename, offset, length); + if (-1 == res) { + dprintf(2, "%s: %s: %s\n", argv[0], filename, strerror(errno)); + exit(EXIT_FAILURE); + } +} @@ -0,0 +1,14 @@ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdnoreturn.h> + + +noreturn void panic(char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + vdprintf(2, fmt, args); + va_end(args); + exit(1); +} @@ -0,0 +1,6 @@ +#pragma once + +#include <stdnoreturn.h> + + +noreturn void panic(char * fmt, ...); |