From d469eebea6ad6371cf84335a5f50f28edee202e9 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 20 Mar 2009 13:47:35 -0700 Subject: [PATCH] process: New function process_search_path(). The process code already had the logic to search PATH for a file, but it didn't export it, and it didn't return the executable that was found. This exports it and returns the name, for the benefit of an upcoming commit that wants to search the PATH for an executable only once per program run. --- lib/process.c | 57 ++++++++++++++++++++++++++------------------------- lib/process.h | 2 ++ 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/lib/process.c b/lib/process.c index a06f5dc1..e27f6547 100644 --- a/lib/process.c +++ b/lib/process.c @@ -71,7 +71,6 @@ static void block_sigchld(sigset_t *); static void unblock_sigchld(const sigset_t *); static void sigchld_handler(int signr UNUSED); static bool is_member(int x, const int *array, size_t); -static bool find_in_path(const char *name); /* Initializes the process subsystem (if it is not already initialized). Calls * exit() if initialization fails. @@ -152,6 +151,7 @@ process_start(char **argv, struct process **pp) { sigset_t oldsigs; + char *binary; pid_t pid; *pp = NULL; @@ -165,10 +165,12 @@ process_start(char **argv, /* execvp() will search PATH too, but the error in that case is more * obscure, since it is only reported post-fork. */ - if (!find_in_path(argv[0])) { + binary = process_search_path(argv[0]); + if (!binary) { VLOG_ERR("%s not found in PATH", argv[0]); return ENOENT; } + free(binary); block_sigchld(&oldsigs); pid = fork(); @@ -344,6 +346,31 @@ process_wait(struct process *p) poll_fd_wait(fds[0], POLLIN); } } + +char * +process_search_path(const char *name) +{ + char *save_ptr = NULL; + char *path, *dir; + struct stat s; + + if (strchr(name, '/') || !getenv("PATH")) { + return stat(name, &s) == 0 ? xstrdup(name) : NULL; + } + + path = xstrdup(getenv("PATH")); + for (dir = strtok_r(path, ":", &save_ptr); dir; + dir = strtok_r(NULL, ":", &save_ptr)) { + char *file = xasprintf("%s/%s", dir, name); + if (stat(file, &s) == 0) { + free(path); + return file; + } + free(file); + } + free(path); + return NULL; +} static void sigchld_handler(int signr UNUSED) @@ -401,29 +428,3 @@ unblock_sigchld(const sigset_t *oldsigs) ofp_fatal(errno, "sigprocmask"); } } - -static bool -find_in_path(const char *name) -{ - char *save_ptr = NULL; - char *path, *dir; - struct stat s; - - if (strchr(name, '/') || !getenv("PATH")) { - return stat(name, &s) == 0; - } - - path = xstrdup(getenv("PATH")); - for (dir = strtok_r(path, ":", &save_ptr); dir; - dir = strtok_r(NULL, ":", &save_ptr)) { - char *file = xasprintf("%s/%s", dir, name); - if (stat(file, &s) == 0) { - free(file); - free(path); - return true; - } - free(file); - } - free(path); - return false; -} diff --git a/lib/process.h b/lib/process.h index ee7876e1..c47628cd 100644 --- a/lib/process.h +++ b/lib/process.h @@ -60,4 +60,6 @@ char *process_status_msg(int); void process_wait(struct process *); +char *process_search_path(const char *); + #endif /* process.h */ -- 2.30.2