Correct BSD License clause numbering from 1-2-4 to 1-2-3.
[dragonfly.git] / lib / libc / gen / exec.c
1 /*-
2  * Copyright (c) 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)exec.c   8.1 (Berkeley) 6/4/93
30  * $FreeBSD: src/lib/libc/gen/exec.c,v 1.25 2008/06/23 05:22:06 ed Exp $
31  */
32
33 #include "namespace.h"
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <paths.h>
43
44 #include <stdarg.h>
45 #include "un-namespace.h"
46 #include "libc_private.h"
47
48 extern char **environ;
49
50 int
51 execl(const char *name, const char *arg, ...)
52 {
53         va_list ap;
54         const char **argv;
55         int n;
56
57         va_start(ap, arg);
58         n = 1;
59         while (va_arg(ap, char *) != NULL)
60                 n++;
61         va_end(ap);
62         argv = alloca((n + 1) * sizeof(*argv));
63         if (argv == NULL) {
64                 errno = ENOMEM;
65                 return (-1);
66         }
67         va_start(ap, arg);
68         n = 1;
69         argv[0] = arg;
70         while ((argv[n] = va_arg(ap, const char *)) != NULL)
71                 n++;
72         va_end(ap);
73         return (_execve(name, __DECONST(char **, argv),
74                         __DECONST(char **, environ)));
75 }
76
77 int
78 execle(const char *name, const char *arg, ...)
79 {
80         va_list ap;
81         const char **argv, **envp;
82         int n;
83
84         va_start(ap, arg);
85         n = 1;
86         while (va_arg(ap, char *) != NULL)
87                 n++;
88         va_end(ap);
89         argv = alloca((n + 1) * sizeof(*argv));
90         if (argv == NULL) {
91                 errno = ENOMEM;
92                 return (-1);
93         }
94         va_start(ap, arg);
95         n = 1;
96         argv[0] = arg;
97         while ((argv[n] = va_arg(ap, const char *)) != NULL)
98                 n++;
99         envp = va_arg(ap, const char **);
100         va_end(ap);
101         return (_execve(name, __DECONST(char **, argv),
102                         __DECONST(char **, envp)));
103 }
104
105 int
106 execlp(const char *name, const char *arg, ...)
107 {
108         va_list ap;
109         const char **argv;
110         int n;
111
112         va_start(ap, arg);
113         n = 1;
114         while (va_arg(ap, char *) != NULL)
115                 n++;
116         va_end(ap);
117         argv = alloca((n + 1) * sizeof(*argv));
118         if (argv == NULL) {
119                 errno = ENOMEM;
120                 return (-1);
121         }
122         va_start(ap, arg);
123         n = 1;
124         argv[0] = arg;
125         while ((argv[n] = va_arg(ap, const char *)) != NULL)
126                 n++;
127         va_end(ap);
128         return (execvp(name, __DECONST(char **, argv)));
129 }
130
131 int
132 execv(const char *name, char * const *argv)
133 {
134         _execve(name, argv, environ);
135         return (-1);
136 }
137
138 int
139 execvp(const char *name, char * const *argv)
140 {
141         return (_execvpe(name, argv, environ));
142 }
143
144 static int
145 execvPe(const char *name, const char *path, char * const *argv,
146         char * const *envp __unused)
147 {
148         const char **memp;
149         int cnt;
150         size_t lp, ln;
151         int eacces, save_errno;
152         const char *bp, *p;
153         char *cur, buf[MAXPATHLEN];
154         struct stat sb;
155
156         eacces = 0;
157
158         /* If it's an absolute or relative path name, it's easy. */
159         if (index(name, '/')) {
160                 bp = name;
161                 cur = NULL;
162                 goto retry;
163         }
164         bp = buf;
165
166         /* If it's an empty path name, fail in the usual POSIX way. */
167         if (*name == '\0') {
168                 errno = ENOENT;
169                 return (-1);
170         }
171
172         cur = alloca(strlen(path) + 1);
173         if (cur == NULL) {
174                 errno = ENOMEM;
175                 return (-1);
176         }
177         strcpy(cur, path);
178         while ((p = strsep(&cur, ":")) != NULL) {
179                 /*
180                  * It's a SHELL path -- double, leading and trailing colons
181                  * mean the current directory.
182                  */
183                 if (*p == '\0') {
184                         p = ".";
185                         lp = 1;
186                 } else
187                         lp = strlen(p);
188                 ln = strlen(name);
189
190                 /*
191                  * If the path is too long complain.  This is a possible
192                  * security issue; given a way to make the path too long
193                  * the user may execute the wrong program.
194                  */
195                 if (lp + ln + 2 > sizeof(buf)) {
196                         _write(STDERR_FILENO, "execvP: ", 8);
197                         _write(STDERR_FILENO, p, lp);
198                         _write(STDERR_FILENO, ": path too long\n", 16);
199                         continue;
200                 }
201                 bcopy(p, buf, lp);
202                 buf[lp] = '/';
203                 bcopy(name, buf + lp + 1, ln);
204                 buf[lp + ln + 1] = '\0';
205 retry:
206                 _execve(bp, argv, environ);
207                 switch (errno) {
208                 case E2BIG:
209                         goto done;
210                 case ELOOP:
211                 case ENAMETOOLONG:
212                 case ENOENT:
213                         break;
214                 case ENOEXEC:
215                         for (cnt = 0; argv[cnt]; ++cnt)
216                                 ;
217                         memp = alloca((cnt + 2) * sizeof(char *));
218                         if (memp == NULL) {
219                                 /* errno = ENOMEM; XXX override ENOEXEC? */
220                                 goto done;
221                         }
222                         memp[0] = "sh";
223                         memp[1] = bp;
224                         bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
225                         _execve(_PATH_BSHELL, __DECONST(char **, memp), environ);
226                         goto done;
227                 case ENOMEM:
228                         goto done;
229                 case ENOTDIR:
230                         break;
231                 case ETXTBSY:
232                         /*
233                          * We used to retry here, but sh(1) doesn't.
234                          */
235                         goto done;
236                 default:
237                         /*
238                          * EACCES may be for an inaccessible directory or
239                          * a non-executable file.  Call stat() to decide
240                          * which.  This also handles ambiguities for EFAULT
241                          * and EIO, and undocumented errors like ESTALE.
242                          * We hope that the race for a stat() is unimportant.
243                          */
244                         save_errno = errno;
245                         if (stat(bp, &sb) != 0)
246                                 break;
247                         if (save_errno == EACCES) {
248                                 eacces = 1;
249                                 continue;
250                         }
251                         errno = save_errno;
252                         goto done;
253                 }
254         }
255         if (eacces)
256                 errno = EACCES;
257         else
258                 errno = ENOENT;
259 done:
260         return (-1);
261 }
262
263 int
264 execvP(const char *name, const char *path, char * const argv[])
265 {
266         return execvPe(name, path, argv, environ);
267 }
268
269 int
270 _execvpe(const char *name, char * const argv[], char * const envp[])
271 {
272         const char *path;
273
274         /* Get the path we're searching. */
275         if ((path = getenv("PATH")) == NULL)
276                 path = _PATH_DEFPATH;
277
278         return (execvPe(name, path, argv, envp));
279 }