summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-07-22 23:03:29 +0200
committerLouis Burda <quent.burda@gmail.com>2023-07-22 23:03:29 +0200
commit3d18255f314091023f47d377de93c6715908d1c7 (patch)
tree16a6312ad58e850a89a644b810a233d81c022312
downloadwd-3d18255f314091023f47d377de93c6715908d1c7.tar.gz
wd-3d18255f314091023f47d377de93c6715908d1c7.zip
Add initial version
-rw-r--r--.gitignore1
-rw-r--r--Makefile21
-rw-r--r--wd.c82
3 files changed, 104 insertions, 0 deletions
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 <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:");
+}