| 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 |