diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2003-08-18 17:55:58 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2003-08-18 17:55:58 +0000 |
commit | 67aefb38bb64562b01aa14a644c3911373a26570 (patch) | |
tree | ad689c659289892efddb18f8b6de3028a1694dfd | |
parent | beff3e6377d5d75d9a8cf18bae505187a6863a5d (diff) |
when given only an executable name without a valid path, resolve the
actual executable path from the PATH environment, so the calls to access()
and stat() work correctly when loading the process
ok art@
-rw-r--r-- | usr.bin/pmdb/pmdb.c | 69 | ||||
-rw-r--r-- | usr.bin/pmdb/pmdb.h | 4 | ||||
-rw-r--r-- | usr.bin/pmdb/process.c | 33 |
3 files changed, 100 insertions, 6 deletions
diff --git a/usr.bin/pmdb/pmdb.c b/usr.bin/pmdb/pmdb.c index 972c4028496..3520272ba8d 100644 --- a/usr.bin/pmdb/pmdb.c +++ b/usr.bin/pmdb/pmdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmdb.c,v 1.18 2003/08/02 20:38:38 mickey Exp $ */ +/* $OpenBSD: pmdb.c,v 1.19 2003/08/18 17:55:57 jfb Exp $ */ /* * Copyright (c) 2002 Artur Grabowski <art@openbsd.org> * All rights reserved. @@ -36,6 +36,7 @@ #include <err.h> #include <errno.h> #include <string.h> +#include <paths.h> #include "pmdb.h" #include "symbol.h" @@ -96,7 +97,7 @@ main(int argc, char **argv) int i, c; int status; void *cm; - char *pmenv, *core, *perr; + char *pmenv, *core, *perr, execpath[MAXPATHLEN]; int level; pid_t pid; @@ -138,10 +139,16 @@ main(int argc, char **argv) if (pmenv) free(pmenv); + if (getexecpath(argv[0], execpath, sizeof(execpath)) == -1) { + err(1, "cannot find `%s'", argv[0]); + } + argv[0] = execpath; + + memset(&ps, 0, sizeof(ps)); + process_setargv(&ps, argc, argv); + ps.ps_pid = pid; ps.ps_state = NONE; - ps.ps_argc = argc; - ps.ps_argv = argv; ps.ps_flags = 0; ps.ps_signum = 0; ps.ps_npc = 1; @@ -408,3 +415,57 @@ emalloc(size_t sz) err(1, "malloc"); return (ret); } + + +/* + * Find the first valid path to the executable whose name is <ename>. + * The resulting path is stored in <dst>, up to <dlen> - 1 bytes, and is + * NUL-terminated. If <dst> is too small, the result will be truncated to + * fit, but getexecpath() will return -1. + * Returns 0 on success, -1 on failure. + */ + +int +getexecpath(const char *ename, char *dst, size_t dlen) +{ + char *envp, *pathenv, *pp, *pfp; + struct stat pstat; + + if (stat(ename, &pstat) == 0) { + if (strlcpy(dst, ename, dlen) >= dlen) + return (-1); + return (0); + } + + if (strchr(ename, '/') != NULL) { + /* don't bother looking in PATH */ + return (-1); + } + + envp = getenv("PATH"); + if (envp == NULL) + envp = _PATH_DEFPATH; + + pathenv = strdup(envp); + if (pathenv == NULL) { + warn("failed to allocate PATH buffer"); + return (-1); + } + + for (pp = pathenv; (pfp = strsep(&pp, ":")) != NULL; ) { + /* skip cwd, was already tested */ + if (*pfp == '\0') + continue; + + if (snprintf(dst, dlen, "%s/%s", pfp, ename) >= (int)dlen) + continue; + + if (stat(dst, &pstat) != -1) { + free(pathenv); + return (0); + } + } + + free(pathenv); + return (-1); +} diff --git a/usr.bin/pmdb/pmdb.h b/usr.bin/pmdb/pmdb.h index 5cb63a20cf2..98276c8700f 100644 --- a/usr.bin/pmdb/pmdb.h +++ b/usr.bin/pmdb/pmdb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmdb.h,v 1.6 2003/05/15 00:11:03 jfb Exp $ */ +/* $OpenBSD: pmdb.h,v 1.7 2003/08/18 17:55:57 jfb Exp $ */ /* * Copyright (c) 2002 Artur Grabowski <art@openbsd.org> * All rights reserved. @@ -81,10 +81,12 @@ struct pstate { #define SS_IGNORE 0x01 /* misc helper functions */ +int getexecpath(const char *, char *, size_t); int process_kill(struct pstate *); /* process.c */ int process_load(struct pstate *); +int process_setargv(struct pstate *, int, char **); int process_run(struct pstate *); int process_read(struct pstate *, off_t, void *, size_t); int process_write(struct pstate *, off_t, void *, size_t); diff --git a/usr.bin/pmdb/process.c b/usr.bin/pmdb/process.c index a1b40f6ef22..e6d28eb44dc 100644 --- a/usr.bin/pmdb/process.c +++ b/usr.bin/pmdb/process.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process.c,v 1.12 2003/08/02 20:38:38 mickey Exp $ */ +/* $OpenBSD: process.c,v 1.13 2003/08/18 17:55:57 jfb Exp $ */ /* * Copyright (c) 2002 Artur Grabowski <art@openbsd.org> * All rights reserved. @@ -79,6 +79,37 @@ process_load(struct pstate *ps) int +process_setargv(struct pstate *ps, int argc, char **argv) +{ + int i; + + if (ps->ps_argv != NULL) { + for (i = 0; i < ps->ps_argc; i++) + free(ps->ps_argv[i]); + free(ps->ps_argv); + } + + ps->ps_argv = (char **)calloc((argc + 1), sizeof(char *)); + if (ps->ps_argv == NULL) { + warn("failed to allocate argument vector"); + return (-1); + } + + ps->ps_argc = argc; + for (i = 0; i < argc; i++) { + ps->ps_argv[i] = strdup(argv[i]); + if (ps->ps_argv[i] == NULL) { + warn("failed to copy argument"); + return (-1); + } + } + + ps->ps_argv[i] = NULL; + return (0); +} + + +int process_run(struct pstate *ps) { int status; |