github.com/afumu/libc@v0.0.6/musl/src/process/execvp.c (about)

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