* Copyright (c) 1991 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)exec.c 5.9 (Berkeley) 6/17/91";
#endif /* LIBC_SCCS and not lint */
buildargv(ap
, arg
, envpp
)
register size_t max
, off
;
register char **argv
= NULL
;
for (off
= max
= 0;; ++off
) {
max
+= 50; /* Starts out at 0. */
max
*= 2; /* Ramp up fast. */
if (!(argv
= realloc(argv
, max
* sizeof(char *))))
if (!(argv
[off
] = va_arg(ap
, char *)))
/* Get environment pointer if user supposed to provide one. */
*envpp
= va_arg(ap
, char **);
execl(const char *name
, const char *arg
, ...)
execl(name
, arg
, va_alist
)
if (argv
= buildargv(ap
, arg
, (char ***)NULL
))
(void)execve(name
, argv
, environ
);
execle(const char *name
, const char *arg
, ...)
execle(name
, arg
, va_alist
)
if (argv
= buildargv(ap
, arg
, &envp
))
(void)execve(name
, argv
, envp
);
execlp(const char *name
, const char *arg
, ...)
execlp(name
, arg
, va_alist
)
if (argv
= buildargv(ap
, arg
, (char ***)NULL
))
(void)execvp(name
, argv
);
(void)execve(name
, argv
, environ
);
char *bp
, *cur
, *path
, buf
[MAXPATHLEN
];
/* If it's an absolute or relative path name, it's easy. */
/* Get the path we're searching. */
if (!(path
= getenv("PATH")))
cur
= path
= strdup(path
);
while (p
= strsep(&cur
, ":")) {
* It's a SHELL path -- double, leading and trailing colons
* mean the current directory.
* If the path is too long complain. This is a possible
* security issue; given a way to make the path too long
* the user may execute the wrong program.
if (lp
+ ln
+ 2 > sizeof(buf
)) {
(void)write(STDERR_FILENO
, "execvp: ", 8);
(void)write(STDERR_FILENO
, p
, lp
);
(void)write(STDERR_FILENO
, ": path too long\n", 16);
bcopy(name
, buf
+ lp
+ 1, ln
);
retry
: (void)execve(bp
, argv
, environ
);
for (cnt
= 0, ap
= (char **)argv
; *ap
; ++ap
, ++cnt
);
if (ap
= malloc((cnt
+ 2) * sizeof(char *))) {
bcopy(argv
+ 1, ap
+ 2, cnt
* sizeof(char *));
(void)execve(_PATH_BSHELL
, ap
, environ
);