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 8extern char **__environ; 9 10int __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 50int execvp(const char *file, char *const argv[]) 51{ 52 return __execvpe(file, argv, __environ); 53} 54 55weak_alias(__execvpe, execvpe); 56