summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2025-08-11 21:43:11 +0200
committertv <tv@krebsco.de>2025-08-11 21:43:11 +0200
commit8f218561c608f2eaac446af3b35298ffcc3fce42 (patch)
tree781d306ce682dd8aab7c6a2420372990d293dec8
exec: initHEAD1.0master
-rw-r--r--Makefile14
-rw-r--r--exec.c105
2 files changed, 119 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..14ffa64
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+PREFIX ?= /usr/local
+BINDIR ?= $(PREFIX)/bin
+CACHEDIR ?= $(PWD)
+
+.PHONY: all
+all: $(CACHEDIR)/exec
+
+.PHONY: install
+install: $(CACHEDIR)/exec
+ mkdir -p $(BINDIR)
+ cp $(CACHEDIR)/exec $(BINDIR)/
+
+$(CACHEDIR)/%: %.c
+ gcc -Wall -Os -o $@ $<
diff --git a/exec.c b/exec.c
new file mode 100644
index 0000000..739ae74
--- /dev/null
+++ b/exec.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static void usage(const char *progname) {
+ fprintf(stderr, "Usage: %s [-n name] COMMAND [ARGS...]\n", progname);
+}
+
+int main(int argc, char *argv[]) {
+ int opt;
+ char *cmd_name = NULL;
+
+ // Parse options
+ while ((opt = getopt(argc, argv, "n:")) != -1) {
+ switch (opt) {
+ case 'n':
+ cmd_name = optarg;
+ break;
+ case '?':
+ usage(argv[0]);
+ return 1;
+ }
+ }
+
+ // Remaining args are COMMAND [ARGS...]
+ if (optind >= argc) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ char *command = argv[optind];
+ char *final_argv0 = cmd_name ? cmd_name : command;
+
+ // Prepare new argv for execvp
+ int new_argc = argc - optind;
+ char *new_argv[argc + 1];
+
+ new_argv[0] = final_argv0;
+ for (int i = 1; i < new_argc; i++) {
+ new_argv[i] = argv[optind + i];
+ }
+ new_argv[new_argc] = NULL;
+
+ execvp(command, new_argv);
+ perror("execvp");
+ return 1;
+}
+
+//#define _GNU_SOURCE
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <string.h>
+//#include <unistd.h>
+//#include <getopt.h>
+//
+//Int main(int argc, char *argv[]) {
+// char *command_name = NULL;
+//
+// // Define long options
+// static struct option long_options[] = {
+// {"name", required_argument, 0, 'n'},
+// {0, 0, 0, 0}
+// };
+//
+// // Parse options
+// int opt_index = 0;
+// int c;
+// while ((c = getopt_long(argc, argv, "n:", long_options, &opt_index)) != -1) {
+// switch (c) {
+// case 'n':
+// command_name = optarg;
+// break;
+// default:
+// fprintf(stderr, "Usage: %s --name=NEW_NAME COMMAND [ARGS...]\n", argv[0]);
+// return 1;
+// }
+// }
+//
+// if (!command_name || optind >= argc) {
+// fprintf(stderr, "Usage: %s --name=NEW_NAME COMMAND [ARGS...]\n", argv[0]);
+// return 1;
+// }
+//
+// // Construct new argv with custom argv[0]
+// int new_argc = argc - optind + 1;
+// char **new_argv = malloc(sizeof(char *) * (new_argc + 1));
+// if (!new_argv) {
+// perror("malloc failed");
+// return 1;
+// }
+//
+// new_argv[0] = command_name;
+// for (int i = 0; i < argc - optind; ++i) {
+// new_argv[i + 1] = argv[optind + i];
+// }
+// new_argv[new_argc] = NULL;
+//
+// // Exec the command
+// execvp(new_argv[0], new_argv);
+//
+// // If we’re here, exec failed
+// perror("execvp failed");
+// free(new_argv);
+// return 1;
+//}