Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/klibc/execvpe.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 1952 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 /*
2     * execvpe.c
3     *
4     * execvpe() function (from which we build execlp, execlpe, execvp).
5     *
6     * This version of execvpe() will *not* spawn /bin/sh if the command
7     * return ENOEXEC. That's what #! is for, folks!
8     *
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
14     * use to search.
15     */
16    
17     #include <errno.h>
18     #include <unistd.h>
19     #include <stdlib.h>
20     #include <string.h>
21     #include <limits.h>
22    
23     #define DEFAULT_PATH "/bin:/usr/bin:."
24    
25     int execvpe(const char *file, char *const *argv, char *const *envp)
26     {
27     char path[PATH_MAX];
28     const char *searchpath, *esp;
29     size_t prefixlen, filelen, totallen;
30    
31     if (strchr(file, '/')) /* Specific path */
32     return execve(file, argv, envp);
33    
34     filelen = strlen(file);
35    
36     searchpath = getenv("PATH");
37     if (!searchpath)
38     searchpath = DEFAULT_PATH;
39    
40     errno = ENOENT; /* Default errno, if execve() doesn't
41     change it */
42    
43     do {
44     esp = strchr(searchpath, ':');
45     if (esp)
46     prefixlen = esp - searchpath;
47     else
48     prefixlen = strlen(searchpath);
49    
50     if (prefixlen == 0 || searchpath[prefixlen - 1] == '/') {
51     totallen = prefixlen + filelen;
52     if (totallen >= PATH_MAX)
53     continue;
54     memcpy(path, searchpath, prefixlen);
55     memcpy(path + prefixlen, file, filelen);
56     } else {
57     totallen = prefixlen + filelen + 1;
58     if (totallen >= PATH_MAX)
59     continue;
60     memcpy(path, searchpath, prefixlen);
61     path[prefixlen] = '/';
62     memcpy(path + prefixlen + 1, file, filelen);
63     }
64     path[totallen] = '\0';
65    
66     execve(path, argv, envp);
67     if (errno == E2BIG || errno == ENOEXEC ||
68     errno == ENOMEM || errno == ETXTBSY)
69     break; /* Report this as an error, no more search */
70    
71     searchpath = esp + 1;
72     } while (esp);
73    
74     return -1;
75     }