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@
This commit is contained in:
parent
accf54d2fd
commit
4ad1bccf13
@ -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);
|
||||
|
@ -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 .
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user