1
/* $OpenBSD: exec.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */
3
* Copyright (c) 1991, 1993
4
* The Regents of the University of California. All rights reserved.
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* 3. Neither the name of the University nor the names of its contributors
15
* may be used to endorse or promote products derived from this software
16
* without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
#include <sys/param.h>
32
#include <sys/types.h>
45
extern char **environ;
48
execl(const char *name, const char *arg, ...)
56
while (va_arg(ap, char *) != NULL)
59
argv = alloca((n + 1) * sizeof(*argv));
66
argv[0] = (char *)arg;
67
while ((argv[n] = va_arg(ap, char *)) != NULL)
70
return (execve(name, argv, environ));
74
execle(const char *name, const char *arg, ...)
82
while (va_arg(ap, char *) != NULL)
85
argv = alloca((n + 1) * sizeof(*argv));
92
argv[0] = (char *)arg;
93
while ((argv[n] = va_arg(ap, char *)) != NULL)
95
envp = va_arg(ap, char **);
97
return (execve(name, argv, envp));
101
execlp(const char *name, const char *arg, ...)
109
while (va_arg(ap, char *) != NULL)
112
argv = alloca((n + 1) * sizeof(*argv));
119
argv[0] = (char *)arg;
120
while ((argv[n] = va_arg(ap, char *)) != NULL)
123
return (execvp(name, argv));
127
execv(const char *name, char * const *argv)
129
(void)execve(name, argv, environ);
134
execvp(const char *name, char * const *argv)
137
int cnt, lp, ln, len;
140
char *bp, *cur, *path, buf[MAXPATHLEN];
143
* Do not allow null name
145
if (name == NULL || *name == '\0') {
150
/* If it's an absolute or relative path name, it's easy. */
151
if (strchr(name, '/')) {
158
/* Get the path we're searching. */
159
if (!(path = getenv("PATH")))
160
path = _PATH_DEFPATH;
161
len = strlen(path) + 1;
167
strlcpy(cur, path, len);
169
while ((p = strsep(&cur, ":"))) {
171
* It's a SHELL path -- double, leading and trailing colons
172
* mean the current directory.
182
* If the path is too long complain. This is a possible
183
* security issue; given a way to make the path too long
184
* the user may execute the wrong program.
186
if (lp + ln + 2 > (int)sizeof(buf)) {
189
iov[0].iov_base = "execvp: ";
193
iov[2].iov_base = ": path too long\n";
195
(void)writev(STDERR_FILENO, iov, 3);
200
memcpy(buf + lp + 1, name, ln);
201
buf[lp + ln + 1] = '\0';
203
retry: (void)execve(bp, argv, environ);
213
for (cnt = 0; argv[cnt]; ++cnt)
215
memp = alloca((cnt + 2) * sizeof(char *));
220
memcpy(memp + 2, argv + 1, cnt * sizeof(char *));
221
(void)execve(_PATH_BSHELL, memp, environ);
229
* We used to retry here, but sh(1) doesn't.