4 * execvpe() function (from which we build execlp, execlpe, execvp).
6 * This version of execvpe() will *not* spawn /bin/sh if the command
7 * return ENOEXEC. That's what #! is for, folks!
9 * Since execlpe() and execvpe() aren't in POSIX, nor in glibc,
10 * I have followed QNX precedent in the implementation of the PATH:
11 * the PATH that is used is the one in the current environment, not
12 * in the new environment. Otherwise it would be impossible to pass
13 * a different PATH to the new process than the one one would want to
23 #define DEFAULT_PATH "/bin:/usr/bin:."
25 int execvpe(const char *file, char * const *argv, char * const *envp)
28 const char *searchpath, *esp;
29 size_t prefixlen, filelen, totallen;
31 if ( strchr(file, '/') ) /* Specific path */
32 return execve(file, argv, envp);
34 filelen = strlen(file);
36 searchpath = getenv("PATH");
38 searchpath = DEFAULT_PATH;
40 errno = ENOENT; /* Default errno, if execve() doesn't change it */
43 esp = strchr(searchpath, ':');
45 prefixlen = esp-searchpath;
47 prefixlen = strlen(searchpath);
49 if ( prefixlen == 0 || searchpath[prefixlen-1] == '/' ) {
50 totallen = prefixlen+filelen;
51 if ( totallen >= PATH_MAX )
53 memcpy(path, searchpath, prefixlen);
54 memcpy(path+prefixlen, file, filelen);
56 totallen = prefixlen+filelen+1;
57 if ( totallen >= PATH_MAX )
59 memcpy(path, searchpath, prefixlen);
60 path[prefixlen] = '/';
61 memcpy(path+prefixlen+1, file, filelen);
63 path[totallen] = '\0';
65 execve(path, argv, envp);
66 if ( errno == E2BIG || errno == ENOEXEC ||
67 errno == ENOMEM || errno == ETXTBSY )
68 break; /* Report this as an error, no more search */