#include #include #include #include #include #include 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); }