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