From c856ca9339e7154699a8ac81ec943d45d8c5ffe8 Mon Sep 17 00:00:00 2001 From: Victor Mignot Date: Wed, 18 Feb 2026 08:16:09 +0100 Subject: Implement `true` and `false` --- .gitignore | 2 ++ LICENSE | 14 ++++++++++++++ Makefile | 28 ++++++++++++++++++++++++++++ README.md | 3 +++ src/false.c | 3 +++ src/main.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/true.c | 3 +++ 7 files changed, 97 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 src/false.c create mode 100644 src/main.c create mode 100644 src/true.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1da65b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +futiles +*.o diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d2bb57b --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Copyright (c) 2026 Victor Mignot + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c8010d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +CC := gcc +CFLAGS := +CFLAGS_EXTRA := -std=c23 -Wpedantic -Wall -Wextra +LDFLAGS := +PREFIX := +UTILS := true false + +BIN := futiles +OBJS := $(patsubst %.c, %.o, $(wildcard src/*.c)) + +all: $(BIN) + +$(BIN): $(OBJS) + $(CC) -o $@ $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) $^ + +src/%.o: src/%.c + $(CC) -c -o $@ $(CFLAGS) $(CFLAGS_EXTRA) $< + +clean: + rm -f $(BIN) $(OBJS) + +install: $(BIN) + install -m 755 $(BIN) $(PREFIX)/bin/ + for util in $(UTILS) ; do \ + ln -sf futiles /usr/bin/$$util; \ + done + +.PHONY: clean install diff --git a/README.md b/README.md new file mode 100644 index 0000000..7934cd0 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# futiles + +An implementation of POSIX utilities. diff --git a/src/false.c b/src/false.c new file mode 100644 index 0000000..f30e835 --- /dev/null +++ b/src/false.c @@ -0,0 +1,3 @@ +int false_main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) { + return 1; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..64da70f --- /dev/null +++ b/src/main.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +typedef int util_main(int, char **); + +extern util_main true_main; +extern util_main false_main; + +typedef struct futiles_util futiles_util_t; +struct futiles_util { + const char *name; + util_main *main; +}; + +int display_utils(int, char **); +const futiles_util_t utils[] = { + { .name = "futiles", .main = display_utils }, + { .name = "true", .main = true_main }, + { .name = "false", .main = false_main } +}; +#define UTILS_NB (sizeof(utils) / sizeof(futiles_util_t)) + +int display_utils([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) { + fputs("Available utils: ", stdout); + for (size_t i = 1; i < UTILS_NB; i++) { + printf("%s ", utils[i].name); + } + putc('\n', stdout); + + return EXIT_SUCCESS; +} + +int main(int argc, char *argv[]) { + char *called_basename = basename(argv[0]); + + for (size_t i = 0; i < UTILS_NB; i++) { + if (strcmp(called_basename, utils[i].name) == 0) { + return utils[i].main(argc, argv); + } + } + return EXIT_FAILURE; +} diff --git a/src/true.c b/src/true.c new file mode 100644 index 0000000..aed6117 --- /dev/null +++ b/src/true.c @@ -0,0 +1,3 @@ +int true_main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) { + return 0; +} -- cgit v1.2.3