wd

Workdir changer
git clone https://git.sinitax.com/sinitax/wd
Log | Files | Refs | LICENSE | sfeed.txt

commit 3d18255f314091023f47d377de93c6715908d1c7
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 22 Jul 2023 23:03:29 +0200

Add initial version

Diffstat:
A.gitignore | 1+
AMakefile | 21+++++++++++++++++++++
Awd.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +wd diff --git a/Makefile 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 @@ -0,0 +1,82 @@ +#include <linux/limits.h> +#include <unistd.h> +#include <dirent.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> + +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:"); +}