Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 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 /*
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 }