From f3984a9b4fb17c12956138694936c62959ebec2d Mon Sep 17 00:00:00 2001 From: Tobias Wiese Date: Sat, 21 Mar 2020 02:47:36 +0100 Subject: Initial Commit The application exchanges 2 files, given as arguments. Signed-off-by: Tobias Wiese --- .gitignore | 3 ++ Makefile | 9 +++++ README | 4 +++ src/Makefile | 19 +++++++++++ src/exchange.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README create mode 100644 src/Makefile create mode 100644 src/exchange.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6783a1d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.[oa] +*~ +/src/exchange diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ec85e7e --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +SHELL = /bin/sh + +.PHONY: all clean + +all: + @$(MAKE) -C src/ + +clean: + @$(MAKE) -C src/ $@ diff --git a/README b/README new file mode 100644 index 0000000..32b9783 --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +# exchange + +A small tool that allows 2 files to be exchanged. +This is done through the renameat2(2) syscall. diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..972f55e --- /dev/null +++ b/src/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -Wall +LDFLAGS := + +CFLAGS += -DVERSIN="\"$(shell git describe --dirty --always)\"" + +TARGETS := exchange +MAINS := $(addsuffix .o, $(TARGETS)) +OBJ := $(MAINS) + +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + rm -rf $(OBJ) $(TARGETS) + +$(TARGETS): % : %.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ diff --git a/src/exchange.c b/src/exchange.c new file mode 100644 index 0000000..e525e8f --- /dev/null +++ b/src/exchange.c @@ -0,0 +1,103 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +#ifndef SMALL +#include +#include +#endif + +#ifndef DEFAULT_PROGRAM_NAME +# define DEFAULT_PROGRAM_NAME "exchange" +#endif + +#ifndef VERSION +# define VERSION "" +#endif + +#ifndef SMALL +static char *program_name = DEFAULT_PROGRAM_NAME; +static struct option const long_options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 }, +}; + +void usage(FILE *fd) { + fprintf(fd, "\ +Usage: %s [OPTION]... \n\ +Exchange PATH 1 and PATH 2.\n", + program_name); + fputs("\n", fd); + fputs("\ +Available Options:\n\ + -h, --help display this help and exit\n\ + -v, --version output version information and exit\n", fd); +} + +void version() { + printf("%s %s\n", program_name, VERSION); + printf("Build on %s %s.\n", __DATE__, __TIME__); +} +#endif // !SMALL + +int main(int argc, char *argv[]) { + char *path1, *path2; +#ifndef SMALL + if (argc > 0) + program_name = argv[0]; + + int c; + while ((c = getopt_long(argc, argv, "hvt", long_options, NULL)) + != -1) + { + switch (c) { + case 't': + break; + case 'h': // help + usage(stdout); + return EXIT_SUCCESS; + case 'v': // version + version(); + return EXIT_SUCCESS; + default: + usage(stderr); + return EXIT_FAILURE; + } + } + + if (argc - optind != 2) { + fprintf(stderr, "%s: invalid number of arguments. Expected 2.\n", program_name); + usage(stderr); + return EXIT_FAILURE; + } + +#else + // We currently don't accept any options + // when compiling with SMALL + // Define optind manually, because we don't use optparse. + const int optind = 1; +#endif // !SMALL + + if (argc - optind != 2) { +#ifndef SMALL + fprintf(stderr, "%s: invalid number of arguments. Expected 2.\n", program_name); + usage(stderr); +#endif + return EXIT_FAILURE; + } + path1 = argv[optind]; + path2 = argv[optind + 1]; + + // Do the magic + if (renameat2(AT_FDCWD, path1, AT_FDCWD, path2, RENAME_EXCHANGE) != 0) { + int errsv = errno; +#ifndef SMALL + perror(program_name); +#endif + return -errsv; + } + return EXIT_SUCCESS; +} -- cgit v1.2.3