diff options
author | tv <tv@krebsco.de> | 2025-08-11 21:43:11 +0200 |
---|---|---|
committer | tv <tv@krebsco.de> | 2025-08-11 21:43:11 +0200 |
commit | 8f218561c608f2eaac446af3b35298ffcc3fce42 (patch) | |
tree | 781d306ce682dd8aab7c6a2420372990d293dec8 |
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | exec.c | 105 |
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 $@ $< @@ -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; +//} |