From 3d18255f314091023f47d377de93c6715908d1c7 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Sat, 22 Jul 2023 23:03:29 +0200 Subject: Add initial version --- .gitignore | 1 + Makefile | 21 ++++++++++++++++ wd.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 wd.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20b605e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +wd diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..73edfbc --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +PREFIX ?= /usr/local +BINDIR ?= /bin + +CFLAGS = -Wunused-variable -Wunused-function -Wconversion + +all: wd + +clean: + rm -f wd + +wd: wd.c + $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) + +install: + install -d "$(DESTDIR)$(PREFIX)$(BINDIR)" + install -m755 wd -t "$(DESTDIR)$(PREFIX)$(BINDIR)" + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)$(BINDIR)/wd" + +.PHONY: all install uninstall diff --git a/wd.c b/wd.c new file mode 100644 index 0000000..3fb2b46 --- /dev/null +++ b/wd.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "wd: "); + vfprintf(stderr, fmt, ap); + if (*fmt && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + va_end(ap); + + exit(1); +} + +static void +findbin(char *dst, const char *name) +{ + char *env, *tok; + struct dirent *ent; + int len; + DIR *d; + + env = getenv("PATH"); + if (!env) die("PATH not set"); + + env = strdup(env); + if (!env) die("strdup:"); + + for (tok = strtok(env, ":"); tok; tok = strtok(NULL, ":")) { + if (!*tok) continue; + d = opendir(tok); + if (!d) continue; + while ((ent = readdir(d))) { + if (!strcmp(ent->d_name, name)) { + closedir(d); + free(env); + len = snprintf(dst, PATH_MAX, + "%s/%s", tok, ent->d_name); + if (len > PATH_MAX) abort(); + return; + } + } + closedir(d); + } + + free(env); + + die("'%s' not found", name); +} + +int +main(int argc, char **argv) +{ + char binpath[PATH_MAX]; + + if (argc < 3) { + fprintf(stderr, "Usage: wd DIR CMD..\n"); + return 1; + } + + if (chdir(argv[1])) die("chdir:"); + + findbin(binpath, argv[2]); + + execv(binpath, argv + 2); + + die("execv:"); +} -- cgit v1.2.3-71-gd317