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