From: Ben Pfaff Date: Fri, 20 Mar 2009 20:47:35 +0000 (-0700) Subject: process: New function process_search_path(). X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d469eebea6ad6371cf84335a5f50f28edee202e9;p=openvswitch 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. --- 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 */