1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
From d20556adadea03bff0bba051172caf0314a35471 Mon Sep 17 00:00:00 2001
From: Henning Heinold <heinold@inf.fu-berlin.de>
Date: Sat, 4 Jun 2011 21:23:15 +0200
Subject: [PATCH 2/2] libc: add non standard execvpe function
Signed-off-by: Henning Heinold <heinold@inf.fu-berlin.de>
---
include/unistd.h | 6 ++++++
libc/unistd/exec.c | 38 +++++++++++++++++++++++++++++++++-----
libc/unistd/execvpe.c | 7 +++++++
3 files changed, 46 insertions(+), 5 deletions(-)
create mode 100644 libc/unistd/execvpe.c
diff --git a/include/unistd.h b/include/unistd.h
index 9568790..070e4f2 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -557,6 +557,12 @@ extern int execvp (__const char *__file, char *__const __argv[])
__THROW __nonnull ((1));
libc_hidden_proto(execvp)
+/* Execute FILE, searching in the `PATH' environment variable if it contains
+ no slashes, with arguments ARGV and environment from a pointer */
+extern int execvpe (__const char *__file, char *__const __argv[], char *__const __envp[])
+ __THROW __nonnull ((1));
+libc_hidden_proto(execvpe)
+
/* Execute FILE, searching in the `PATH' environment variable if
it contains no slashes, with all arguments after FILE until a
NULL pointer and environment from `environ'. */
diff --git a/libc/unistd/exec.c b/libc/unistd/exec.c
index 7d24072..802a174 100644
--- a/libc/unistd/exec.c
+++ b/libc/unistd/exec.c
@@ -32,6 +32,8 @@
/**********************************************************************/
#define EXEC_FUNC_COMMON 0
#define EXEC_FUNC_EXECVP 1
+#define EXEC_FUNC_EXECVPE 2
+
#if defined(__ARCH_USE_MMU__)
/* We have an MMU, so use alloca() to grab space for buffers and arg lists. */
@@ -58,6 +60,7 @@
* execle(a) -> execve(-)
* execv(-) -> execve(-)
* execvp(a) -> execve(-)
+ * execvpe(a) -> execve(-)
*/
# define EXEC_ALLOC_SIZE(VAR) /* nothing to do */
@@ -219,15 +222,18 @@ libc_hidden_def(execlp)
#endif
/**********************************************************************/
-#ifdef L_execvp
+#if defined (L_execvp) || defined(L_execvpe)
/* Use a default path that matches glibc behavior, since SUSv3 says
* this is implementation-defined. The default is current working dir,
* /bin, and then /usr/bin. */
static const char default_path[] = ":/bin:/usr/bin";
-
+#if defined (L_execvp)
int execvp(const char *path, char *const argv[])
+#elif defined (L_execvpe)
+int execvpe(const char *path, char *const argv[], char *const envp[])
+#endif
{
char *buf = NULL;
char *p;
@@ -245,7 +251,11 @@ int execvp(const char *path, char *const argv[])
}
if (strchr(path, '/')) {
+#if defined (L_execvp)
execve(path, argv, __environ);
+#elif defined (L_execvpe)
+ execve(path, argv, envp);
+#endif
if (errno == ENOEXEC) {
char **nargv;
EXEC_ALLOC_SIZE(size2) /* Do NOT add a semicolon! */
@@ -254,11 +264,19 @@ int execvp(const char *path, char *const argv[])
/* Need the dimension - 1. We omit counting the trailing
* NULL but we actually omit the first entry. */
for (n=0 ; argv[n] ; n++) {}
+#if defined (L_execvp)
nargv = (char **) EXEC_ALLOC((n+2) * sizeof(char *), size2, EXEC_FUNC_EXECVP);
+#elif defined (L_execvpe)
+ nargv = (char **) EXEC_ALLOC((n+2) * sizeof(char *), size2, EXEC_FUNC_EXECVPE);
+#endif
nargv[0] = argv[0];
nargv[1] = (char *)path;
memcpy(nargv+2, argv+1, n*sizeof(char *));
+#if defined (L_execvp)
execve("/bin/sh", nargv, __environ);
+#elif defined (L_execvpe)
+ execve("/bin/sh", nargv, envp);
+#endif
EXEC_FREE(nargv, size2);
}
} else {
@@ -277,8 +295,11 @@ int execvp(const char *path, char *const argv[])
return -1;
}
len = (FILENAME_MAX - 1) - plen;
-
+#if defined (L_execvp)
buf = EXEC_ALLOC(FILENAME_MAX, size, EXEC_FUNC_EXECVP);
+#elif defined (L_execvpe)
+ buf = EXEC_ALLOC(FILENAME_MAX, size, EXEC_FUNC_EXECVPE);
+#endif
{
int seen_small = 0;
s0 = buf + len;
@@ -300,8 +321,11 @@ int execvp(const char *path, char *const argv[])
s[plen-1] = '/';
}
+#if defined (L_execvp)
execve(s, argv, __environ);
-
+#elif defined (L_execvpe)
+ execve(s, argv, envp);
+#endif
seen_small = 1;
if (errno == ENOEXEC) {
@@ -325,7 +349,11 @@ int execvp(const char *path, char *const argv[])
return -1;
}
+#if defined (L_execvp)
libc_hidden_def(execvp)
-
+#elif defined (L_execvpe)
+libc_hidden_def(execvpe)
#endif
+
+#endif /* #if defined (L_execvp) || defined(L_execvpe) */
/**********************************************************************/
diff --git a/libc/unistd/execvpe.c b/libc/unistd/execvpe.c
new file mode 100644
index 0000000..5c1ce06
--- /dev/null
+++ b/libc/unistd/execvpe.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2011 Hennning Heinold <heinold@inf.fu-berlin.de>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_execvpe
+#include "exec.c"
--
1.7.5.3
|