summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgordon <gordon@FreeBSD.org>2003-06-29 17:33:34 +0000
committergordon <gordon@FreeBSD.org>2003-06-29 17:33:34 +0000
commit4ad1bccf132b3c564df8fe00da9bd5e9124ef9a5 (patch)
tree8f553a0aed9c7e26590831e651a76750dd5efb9d
parentaccf54d2fd6d971fc3cf6cc35ff5866b1275597e (diff)
downloadFreeBSD-src-4ad1bccf132b3c564df8fe00da9bd5e9124ef9a5.zip
FreeBSD-src-4ad1bccf132b3c564df8fe00da9bd5e9124ef9a5.tar.gz
Add a libc function execvP that takes the search path as an arguement.
Change execvp to be a wrapper around execvP. This is necessary for some of the /rescue pieces. It may also be more generally applicable as well. Submitted by: Tim Kientzle <kientzle@acm.org> Approved by: Silence on arch@
-rw-r--r--include/unistd.h1
-rw-r--r--lib/libc/gen/exec.331
-rw-r--r--lib/libc/gen/exec.c24
3 files changed, 41 insertions, 15 deletions
diff --git a/include/unistd.h b/include/unistd.h
index 4c4b04c..3753cd8 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -335,6 +335,7 @@ int execlp(const char *, const char *, ...);
int execv(const char *, char * const *);
int execve(const char *, char * const *, char * const *);
int execvp(const char *, char * const *);
+int execvP(const char *, const char *, char * const *);
pid_t fork(void);
long fpathconf(int, int);
char *getcwd(char *, size_t);
diff --git a/lib/libc/gen/exec.3 b/lib/libc/gen/exec.3
index 9387267..ea0f5b4 100644
--- a/lib/libc/gen/exec.3
+++ b/lib/libc/gen/exec.3
@@ -41,7 +41,8 @@
.Nm execle ,
.Nm exect ,
.Nm execv ,
-.Nm execvp
+.Nm execvp ,
+.Nm execvP
.Nd execute a file
.Sh LIBRARY
.Lb libc
@@ -60,6 +61,8 @@
.Fn execv "const char *path" "char *const argv[]"
.Ft int
.Fn execvp "const char *file" "char *const argv[]"
+.Ft int
+.Fn execvP "const char *file" "const char *search_path" "char *const argv[]"
.Sh DESCRIPTION
The
.Nm exec
@@ -99,8 +102,9 @@ pointer.
The
.Fn exect ,
.Fn execv ,
+.Fn execvp ,
and
-.Fn execvp
+.Fn execvP
functions provide an array of pointers to null-terminated strings that
represent the argument list available to the new program.
The first argument, by convention, should point to the file name associated
@@ -134,14 +138,19 @@ in the current process.
Some of these functions have special semantics.
.Pp
The functions
-.Fn execlp
+.Fn execlp ,
+.Fn execvp ,
and
-.Fn execvp
+.Fn execvP
will duplicate the actions of the shell in searching for an executable file
if the specified file name does not contain a slash
.Dq Li /
character.
-The search path is the path specified in the environment by
+For
+.Fn execlp
+and
+.Fn execvp ,
+search path is the path specified in the environment by
.Dq Ev PATH
variable.
If this variable isn't specified,
@@ -151,6 +160,9 @@ definition in
.Aq paths.h ,
which is set to
.Dq Ev /usr/bin:/bin .
+For
+.Fn execvP ,
+the search path is specified as an argument to the function.
In addition, certain errors are treated specially.
.Pp
If an error is ambiguous (for simplicity, we shall consider all
@@ -206,9 +218,10 @@ The shell.
The
.Fn execl ,
.Fn execle ,
-.Fn execlp
-and
+.Fn execlp ,
.Fn execvp
+and
+.Fn execvP
functions
may fail and set
.Va errno
@@ -300,3 +313,7 @@ and
functions
conform to
.St -p1003.1-88 .
+The
+.Fn execvP
+function first appeared in
+.Fx 5.2 .
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c
index 7f13e0a..3f81a3a 100644
--- a/lib/libc/gen/exec.c
+++ b/lib/libc/gen/exec.c
@@ -142,15 +142,27 @@ execv(name, argv)
}
int
-execvp(name, argv)
+execvp(const char *name, char *const *argv)
+{
+ const char *path;
+
+ /* Get the path we're searching. */
+ if (!(path = getenv("PATH")))
+ path = _PATH_DEFPATH;
+ return(execvP(name,path,argv));
+}
+
+int
+execvP(name, path, argv)
const char *name;
+ const char *path;
char * const *argv;
{
char **memp;
int cnt, lp, ln;
char *p;
int eacces, save_errno;
- char *bp, *cur, *path, buf[MAXPATHLEN];
+ char *bp, *cur, buf[MAXPATHLEN];
struct stat sb;
eacces = 0;
@@ -158,7 +170,7 @@ execvp(name, argv)
/* If it's an absolute or relative path name, it's easy. */
if (index(name, '/')) {
bp = (char *)name;
- cur = path = NULL;
+ cur = NULL;
goto retry;
}
bp = buf;
@@ -169,16 +181,12 @@ execvp(name, argv)
return (-1);
}
- /* Get the path we're searching. */
- if (!(path = getenv("PATH")))
- path = _PATH_DEFPATH;
cur = alloca(strlen(path) + 1);
if (cur == NULL) {
errno = ENOMEM;
return (-1);
}
strcpy(cur, path);
- path = cur;
while ( (p = strsep(&cur, ":")) ) {
/*
* It's a SHELL path -- double, leading and trailing colons
@@ -197,7 +205,7 @@ execvp(name, argv)
* the user may execute the wrong program.
*/
if (lp + ln + 2 > sizeof(buf)) {
- (void)_write(STDERR_FILENO, "execvp: ", 8);
+ (void)_write(STDERR_FILENO, "execvP: ", 8);
(void)_write(STDERR_FILENO, p, lp);
(void)_write(STDERR_FILENO, ": path too long\n",
16);
OpenPOWER on IntegriCloud