Beispiellösung
Content |
Zur Frage
Die Funktionen strtok und strtok_r verändern das erste Argument, indem sie Nullbytes einsetzen. Daher dürfen diese nicht auf eine Zeichenkette angewandt werden, auf die getenv zurückliefert. Stattdessen wird diese mit strdup dupliziert. Dann kann diese problem verändert werden. Später sollte das mit free wieder freigegeben werden.
Programmtext
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <afblib/strlist.h> int execvpe(const char* file, char* const argv[], char* const envp[]) { const char* path = getenv("PATH"); if (strchr(argv[0], '/') || !path) { return execve(file, argv, envp); } else { char* mypath = strdup(path); if (!mypath) { return -1; } char* lasts; char* dir = strtok_r(mypath, ":", &lasts); int fd = -1; while (fd < 0 && dir) { int dirfd = open(dir, O_DIRECTORY|O_SEARCH); if (dirfd < 0) continue; fd = openat(dirfd, file, O_EXEC); dir = strtok_r(0, ":", &lasts); } free(mypath); if (fd < 0) { return -1; } return fexecve(fd, argv, envp); } } int main(int argc, char** argv) { strlist env = {0}; const char* cmdname = *argv++; --argc; while (argc > 0 && strchr(*argv, '=')) { if (!strlist_push(&env, *argv)) { perror(""); exit(1); } --argc; ++argv; } if (argc == 0) { fprintf(stderr, "Usage: %s param=value ... command\n", cmdname); exit(1); } if (!strlist_push0(&env)) { perror(""); exit(1); } execvpe(argv[0], argv, env.list); perror(argv[0]); exit(1); }
Übersetzung und Ausführung
theon$ gcc -Wall -o environ2 environ2.c -lafb environ2.c:6:10: fatal error: afblib/strlist.h: No such file or directory 6 | #include <afblib/strlist.h> | ^~~~~~~~~~~~~~~~~~ compilation terminated. theon$ ./environ2 date Tue Nov 15 23:15:31 CET 2022 theon$ ./environ2 LANG=de TZ=EST date Dienstag, 15. November 2022 um 17:15:31 Uhr EST theon$