| 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); | 
|  |