* Copyright (c) 1991 The Regents of the University of California.
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)exec.c 5.9 (Berkeley) %G%";
#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
);