Index: fusl/src/process/execvp.c |
diff --git a/fusl/src/process/execvp.c b/fusl/src/process/execvp.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3a8bbe83295ab3e76abcec90c30c3dee0378f75a |
--- /dev/null |
+++ b/fusl/src/process/execvp.c |
@@ -0,0 +1,55 @@ |
+#include <stdlib.h> |
+#include <string.h> |
+#include <unistd.h> |
+#include <errno.h> |
+#include <limits.h> |
+#include "libc.h" |
+ |
+extern char **__environ; |
+ |
+int __execvpe(const char *file, char *const argv[], char *const envp[]) |
+{ |
+ const char *p, *z, *path = getenv("PATH"); |
+ size_t l, k; |
+ int seen_eacces = 0; |
+ |
+ errno = ENOENT; |
+ if (!*file) return -1; |
+ |
+ if (strchr(file, '/')) |
+ return execve(file, argv, envp); |
+ |
+ if (!path) path = "/usr/local/bin:/bin:/usr/bin"; |
+ k = strnlen(file, NAME_MAX+1); |
+ if (k > NAME_MAX) { |
+ errno = ENAMETOOLONG; |
+ return -1; |
+ } |
+ l = strnlen(path, PATH_MAX-1)+1; |
+ |
+ for(p=path; ; p=z) { |
+ char b[l+k+1]; |
+ z = strchr(p, ':'); |
+ if (!z) z = p+strlen(p); |
+ if (z-p >= l) { |
+ if (!*z++) break; |
+ continue; |
+ } |
+ memcpy(b, p, z-p); |
+ b[z-p] = '/'; |
+ memcpy(b+(z-p)+(z>p), file, k+1); |
+ execve(b, argv, envp); |
+ if (errno == EACCES) seen_eacces = 1; |
+ else if (errno != ENOENT) return -1; |
+ if (!*z++) break; |
+ } |
+ if (seen_eacces) errno = EACCES; |
+ return -1; |
+} |
+ |
+int execvp(const char *file, char *const argv[]) |
+{ |
+ return __execvpe(file, argv, __environ); |
+} |
+ |
+weak_alias(__execvpe, execvpe); |