~xnox/ubuntu/trusty/gcc-arm-linux-androideabi/dima

« back to all changes in this revision

Viewing changes to android/bionic/libc/unistd/exec.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-07-05 10:12:24 UTC
  • Revision ID: package-import@ubuntu.com-20130705101224-6qo3e8jbz8p31aa1
Tags: upstream-0.20130705.1
ImportĀ upstreamĀ versionĀ 0.20130705.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $OpenBSD: exec.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */
 
2
/*-
 
3
 * Copyright (c) 1991, 1993
 
4
 *      The Regents of the University of California.  All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
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.
 
17
 *
 
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
 
28
 * SUCH DAMAGE.
 
29
 */
 
30
 
 
31
#include <sys/param.h>
 
32
#include <sys/types.h>
 
33
#include <sys/uio.h>
 
34
#include <errno.h>
 
35
#include <unistd.h>
 
36
#include <limits.h>
 
37
#include <stdlib.h>
 
38
#include <string.h>
 
39
#include <strings.h>
 
40
#include <stdio.h>
 
41
#include <paths.h>
 
42
#include <stdarg.h>
 
43
#include <alloca.h>
 
44
 
 
45
extern char **environ;
 
46
 
 
47
int
 
48
execl(const char *name, const char *arg, ...)
 
49
{
 
50
        va_list ap;
 
51
        char **argv;
 
52
        int n;
 
53
 
 
54
        va_start(ap, arg);
 
55
        n = 1;
 
56
        while (va_arg(ap, char *) != NULL)
 
57
                n++;
 
58
        va_end(ap);
 
59
        argv = alloca((n + 1) * sizeof(*argv));
 
60
        if (argv == NULL) {
 
61
                errno = ENOMEM;
 
62
                return (-1);
 
63
        }
 
64
        va_start(ap, arg);
 
65
        n = 1;
 
66
        argv[0] = (char *)arg;
 
67
        while ((argv[n] = va_arg(ap, char *)) != NULL)
 
68
                n++;
 
69
        va_end(ap);
 
70
        return (execve(name, argv, environ));
 
71
}
 
72
 
 
73
int
 
74
execle(const char *name, const char *arg, ...)
 
75
{
 
76
        va_list ap;
 
77
        char **argv, **envp;
 
78
        int n;
 
79
 
 
80
        va_start(ap, arg);
 
81
        n = 1;
 
82
        while (va_arg(ap, char *) != NULL)
 
83
                n++;
 
84
        va_end(ap);
 
85
        argv = alloca((n + 1) * sizeof(*argv));
 
86
        if (argv == NULL) {
 
87
                errno = ENOMEM;
 
88
                return (-1);
 
89
        }
 
90
        va_start(ap, arg);
 
91
        n = 1;
 
92
        argv[0] = (char *)arg;
 
93
        while ((argv[n] = va_arg(ap, char *)) != NULL)
 
94
                n++;
 
95
        envp = va_arg(ap, char **);
 
96
        va_end(ap);
 
97
        return (execve(name, argv, envp));
 
98
}
 
99
 
 
100
int
 
101
execlp(const char *name, const char *arg, ...)
 
102
{
 
103
        va_list ap;
 
104
        char **argv;
 
105
        int n;
 
106
 
 
107
        va_start(ap, arg);
 
108
        n = 1;
 
109
        while (va_arg(ap, char *) != NULL)
 
110
                n++;
 
111
        va_end(ap);
 
112
        argv = alloca((n + 1) * sizeof(*argv));
 
113
        if (argv == NULL) {
 
114
                errno = ENOMEM;
 
115
                return (-1);
 
116
        }
 
117
        va_start(ap, arg);
 
118
        n = 1;
 
119
        argv[0] = (char *)arg;
 
120
        while ((argv[n] = va_arg(ap, char *)) != NULL)
 
121
                n++;
 
122
        va_end(ap);
 
123
        return (execvp(name, argv));
 
124
}
 
125
 
 
126
int
 
127
execv(const char *name, char * const *argv)
 
128
{
 
129
        (void)execve(name, argv, environ);
 
130
        return (-1);
 
131
}
 
132
 
 
133
int
 
134
execvp(const char *name, char * const *argv)
 
135
{
 
136
        char **memp;
 
137
        int cnt, lp, ln, len;
 
138
        char *p;
 
139
        int eacces = 0;
 
140
        char *bp, *cur, *path, buf[MAXPATHLEN];
 
141
 
 
142
        /*
 
143
         * Do not allow null name
 
144
         */
 
145
        if (name == NULL || *name == '\0') {
 
146
                errno = ENOENT;
 
147
                return (-1);
 
148
        }
 
149
 
 
150
        /* If it's an absolute or relative path name, it's easy. */
 
151
        if (strchr(name, '/')) {
 
152
                bp = (char *)name;
 
153
                cur = path = NULL;
 
154
                goto retry;
 
155
        }
 
156
        bp = buf;
 
157
 
 
158
        /* Get the path we're searching. */
 
159
        if (!(path = getenv("PATH")))
 
160
                path = _PATH_DEFPATH;
 
161
        len = strlen(path) + 1;
 
162
        cur = alloca(len);
 
163
        if (cur == NULL) {
 
164
                errno = ENOMEM;
 
165
                return (-1);
 
166
        }
 
167
        strlcpy(cur, path, len);
 
168
        path = cur;
 
169
        while ((p = strsep(&cur, ":"))) {
 
170
                /*
 
171
                 * It's a SHELL path -- double, leading and trailing colons
 
172
                 * mean the current directory.
 
173
                 */
 
174
                if (!*p) {
 
175
                        p = ".";
 
176
                        lp = 1;
 
177
                } else
 
178
                        lp = strlen(p);
 
179
                ln = strlen(name);
 
180
 
 
181
                /*
 
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.
 
185
                 */
 
186
                if (lp + ln + 2 > (int)sizeof(buf)) {
 
187
                        struct iovec iov[3];
 
188
 
 
189
                        iov[0].iov_base = "execvp: ";
 
190
                        iov[0].iov_len = 8;
 
191
                        iov[1].iov_base = p;
 
192
                        iov[1].iov_len = lp;
 
193
                        iov[2].iov_base = ": path too long\n";
 
194
                        iov[2].iov_len = 16;
 
195
                        (void)writev(STDERR_FILENO, iov, 3);
 
196
                        continue;
 
197
                }
 
198
                memcpy(buf, p, lp);
 
199
                buf[lp] = '/';
 
200
                memcpy(buf + lp + 1, name, ln);
 
201
                buf[lp + ln + 1] = '\0';
 
202
 
 
203
retry:          (void)execve(bp, argv, environ);
 
204
                switch(errno) {
 
205
                case E2BIG:
 
206
                        goto done;
 
207
                case EISDIR:
 
208
                case ELOOP:
 
209
                case ENAMETOOLONG:
 
210
                case ENOENT:
 
211
                        break;
 
212
                case ENOEXEC:
 
213
                        for (cnt = 0; argv[cnt]; ++cnt)
 
214
                                ;
 
215
                        memp = alloca((cnt + 2) * sizeof(char *));
 
216
                        if (memp == NULL)
 
217
                                goto done;
 
218
                        memp[0] = "sh";
 
219
                        memp[1] = bp;
 
220
                        memcpy(memp + 2, argv + 1, cnt * sizeof(char *));
 
221
                        (void)execve(_PATH_BSHELL, memp, environ);
 
222
                        goto done;
 
223
                case ENOMEM:
 
224
                        goto done;
 
225
                case ENOTDIR:
 
226
                        break;
 
227
                case ETXTBSY:
 
228
                        /*
 
229
                         * We used to retry here, but sh(1) doesn't.
 
230
                         */
 
231
                        goto done;
 
232
                case EACCES:
 
233
                        eacces = 1;
 
234
                        break;
 
235
                default:
 
236
                        goto done;
 
237
                }
 
238
        }
 
239
        if (eacces)
 
240
                errno = EACCES;
 
241
        else if (!errno)
 
242
                errno = ENOENT;
 
243
done:
 
244
        return (-1);
 
245
}