1 #include "libc.h"
2 #include <errno.h>
3 #include <limits.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7
__execvpe(const char * file,char * const argv[],char * const envp[])8 int __execvpe(const char* file, char* const argv[], char* const envp[]) {
9 const char *p, *z, *path = getenv("PATH");
10 size_t l, k;
11 int seen_eacces = 0;
12
13 errno = ENOENT;
14 if (!*file)
15 return -1;
16
17 if (strchr(file, '/'))
18 return execve(file, argv, envp);
19
20 if (!path)
21 path = "/usr/local/bin:/bin:/usr/bin";
22 k = strnlen(file, NAME_MAX + 1);
23 if (k > NAME_MAX) {
24 errno = ENAMETOOLONG;
25 return -1;
26 }
27 l = strnlen(path, PATH_MAX - 1) + 1;
28
29 for (p = path;; p = z) {
30 char b[l + k + 1];
31 z = strchr(p, ':');
32 if (!z)
33 z = p + strlen(p);
34 if (z - p >= l) {
35 if (!*z++)
36 break;
37 continue;
38 }
39 memcpy(b, p, z - p);
40 b[z - p] = '/';
41 memcpy(b + (z - p) + (z > p), file, k + 1);
42 execve(b, argv, envp);
43 if (errno == EACCES)
44 seen_eacces = 1;
45 else if (errno != ENOENT)
46 return -1;
47 if (!*z++)
48 break;
49 }
50 if (seen_eacces)
51 errno = EACCES;
52 return -1;
53 }
54
execvp(const char * file,char * const argv[])55 int execvp(const char* file, char* const argv[]) {
56 return __execvpe(file, argv, __environ);
57 }
58
59 weak_alias(__execvpe, execvpe);
60