xref: /aosp_15_r20/external/musl/src/process/execvp.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <stdlib.h>
2*c9945492SAndroid Build Coastguard Worker #include <string.h>
3*c9945492SAndroid Build Coastguard Worker #include <unistd.h>
4*c9945492SAndroid Build Coastguard Worker #include <errno.h>
5*c9945492SAndroid Build Coastguard Worker #include <limits.h>
6*c9945492SAndroid Build Coastguard Worker 
7*c9945492SAndroid Build Coastguard Worker extern char **__environ;
8*c9945492SAndroid Build Coastguard Worker 
__execvpe(const char * file,char * const argv[],char * const envp[])9*c9945492SAndroid Build Coastguard Worker int __execvpe(const char *file, char *const argv[], char *const envp[])
10*c9945492SAndroid Build Coastguard Worker {
11*c9945492SAndroid Build Coastguard Worker 	const char *p, *z, *path = getenv("PATH");
12*c9945492SAndroid Build Coastguard Worker 	size_t l, k;
13*c9945492SAndroid Build Coastguard Worker 	int seen_eacces = 0;
14*c9945492SAndroid Build Coastguard Worker 
15*c9945492SAndroid Build Coastguard Worker 	errno = ENOENT;
16*c9945492SAndroid Build Coastguard Worker 	if (!*file) return -1;
17*c9945492SAndroid Build Coastguard Worker 
18*c9945492SAndroid Build Coastguard Worker 	if (strchr(file, '/'))
19*c9945492SAndroid Build Coastguard Worker 		return execve(file, argv, envp);
20*c9945492SAndroid Build Coastguard Worker 
21*c9945492SAndroid Build Coastguard Worker 	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
22*c9945492SAndroid Build Coastguard Worker 	k = strnlen(file, NAME_MAX+1);
23*c9945492SAndroid Build Coastguard Worker 	if (k > NAME_MAX) {
24*c9945492SAndroid Build Coastguard Worker 		errno = ENAMETOOLONG;
25*c9945492SAndroid Build Coastguard Worker 		return -1;
26*c9945492SAndroid Build Coastguard Worker 	}
27*c9945492SAndroid Build Coastguard Worker 	l = strnlen(path, PATH_MAX-1)+1;
28*c9945492SAndroid Build Coastguard Worker 
29*c9945492SAndroid Build Coastguard Worker 	for(p=path; ; p=z) {
30*c9945492SAndroid Build Coastguard Worker 		char b[l+k+1];
31*c9945492SAndroid Build Coastguard Worker 		z = __strchrnul(p, ':');
32*c9945492SAndroid Build Coastguard Worker 		if (z-p >= l) {
33*c9945492SAndroid Build Coastguard Worker 			if (!*z++) break;
34*c9945492SAndroid Build Coastguard Worker 			continue;
35*c9945492SAndroid Build Coastguard Worker 		}
36*c9945492SAndroid Build Coastguard Worker 		memcpy(b, p, z-p);
37*c9945492SAndroid Build Coastguard Worker 		b[z-p] = '/';
38*c9945492SAndroid Build Coastguard Worker 		memcpy(b+(z-p)+(z>p), file, k+1);
39*c9945492SAndroid Build Coastguard Worker 		execve(b, argv, envp);
40*c9945492SAndroid Build Coastguard Worker 		switch (errno) {
41*c9945492SAndroid Build Coastguard Worker 		case EACCES:
42*c9945492SAndroid Build Coastguard Worker 			seen_eacces = 1;
43*c9945492SAndroid Build Coastguard Worker 		case ENOENT:
44*c9945492SAndroid Build Coastguard Worker 		case ENOTDIR:
45*c9945492SAndroid Build Coastguard Worker 			break;
46*c9945492SAndroid Build Coastguard Worker 		default:
47*c9945492SAndroid Build Coastguard Worker 			return -1;
48*c9945492SAndroid Build Coastguard Worker 		}
49*c9945492SAndroid Build Coastguard Worker 		if (!*z++) break;
50*c9945492SAndroid Build Coastguard Worker 	}
51*c9945492SAndroid Build Coastguard Worker 	if (seen_eacces) errno = EACCES;
52*c9945492SAndroid Build Coastguard Worker 	return -1;
53*c9945492SAndroid Build Coastguard Worker }
54*c9945492SAndroid Build Coastguard Worker 
execvp(const char * file,char * const argv[])55*c9945492SAndroid Build Coastguard Worker int execvp(const char *file, char *const argv[])
56*c9945492SAndroid Build Coastguard Worker {
57*c9945492SAndroid Build Coastguard Worker 	return __execvpe(file, argv, __environ);
58*c9945492SAndroid Build Coastguard Worker }
59*c9945492SAndroid Build Coastguard Worker 
60*c9945492SAndroid Build Coastguard Worker weak_alias(__execvpe, execvpe);
61