From b3d0cdd4b20855c62a759b66da94907f6bf81cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 11 Apr 2022 14:02:18 +0200 Subject: [PATCH] =?UTF-8?q?slave:=20roll=20our=20own=20=E2=80=98execvpe()?= =?UTF-8?q?=E2=80=99=20on=20FreeBSD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slave.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/slave.c b/slave.c index dc4a8bc6..db60d7b5 100644 --- a/slave.c +++ b/slave.c @@ -25,6 +25,63 @@ extern char **environ; +#if defined(__FreeBSD__) +static char * +find_file_in_path(const char *file) +{ + if (strchr(file, '/') != NULL) + return xstrdup(file); + + const char *env_path = getenv("PATH"); + char *path_list = NULL; + + if (env_path != NULL && env_path[0] != '\0') + path_list = xstrdup(env_path); + else { + size_t sc_path_len = confstr(_CS_PATH, NULL, 0); + if (sc_path_len > 0) { + path_list = xmalloc(sc_path_len); + confstr(_CS_PATH, path_list, sc_path_len); + } else + return xstrdup(file); + } + + for (const char *path = strtok(path_list, ":"); + path != NULL; + path = strtok(NULL, ":")) + { + char *full = xasprintf("%s/%s", path, file); + if (access(full, F_OK) == 0) { + free(path_list); + return full; + } + + free(full); + } + + free(path_list); + return xstrdup(file); +} + +static int +foot_execvpe(const char *file, char *const argv[], char *const envp[]) +{ + char *path = find_file_in_path(file); + int ret = execve(path, argv, envp); + + /* + * Getting here is an error + */ + free(path); + return ret; +} + +#else /* !__FreeBSD__ */ + +#define foot_execvpe(file, argv, envp) execvpe(file, argv, envp) + +#endif /* !__FreeBSD__ */ + static bool is_valid_shell(const char *shell) { @@ -234,7 +291,7 @@ slave_exec(int ptmx, char *argv[], char *const envp[], int err_fd, } else file = argv[0]; - execvpe(file, argv, envp); + foot_execvpe(file, argv, envp); err: (void)!write(err_fd, &errno, sizeof(errno));