toaruos/libc/unistd/execvp.c

70 lines
1.6 KiB
C
Raw Normal View History

2018-10-12 09:40:45 +03:00
#include <stdio.h>
2018-02-25 08:13:54 +03:00
#include <syscall.h>
#include <syscall_nums.h>
#include <stdlib.h>
2018-02-25 08:13:54 +03:00
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
DEFN_SYSCALL3(execve, SYS_EXECVE, char *, char **, char **);
2018-02-25 08:13:54 +03:00
extern char ** environ;
2018-10-12 09:40:45 +03:00
extern char * _argv_0;
extern int __libc_debug;
2018-02-25 08:13:54 +03:00
2018-08-14 08:04:53 +03:00
#define DEFAULT_PATH "/bin:/usr/bin"
2018-02-25 08:13:54 +03:00
int execve(const char *name, char * const argv[], char * const envp[]) {
2018-10-12 09:40:45 +03:00
if (__libc_debug) {
fprintf(stderr, "%s: execve(\"%s\"", _argv_0, name);
char * const* arg = argv;
while (*arg) {
fprintf(stderr,", \"%s\"", *arg);
arg++;
}
fprintf(stderr, ")\n");
}
2018-09-28 07:10:32 +03:00
__sets_errno(syscall_execve((char*)name,(char**)argv,(char**)envp));
2018-02-25 08:13:54 +03:00
}
int execvp(const char *file, char *const argv[]) {
if (file && (!strstr(file, "/"))) {
/* We don't quite understand "$PATH", so... */
char * path = getenv("PATH");
if (!path) {
path = DEFAULT_PATH;
}
char * xpath = strdup(path);
2018-04-25 15:39:55 +03:00
char * p, * last;
2018-02-25 08:13:54 +03:00
for ((p = strtok_r(xpath, ":", &last)); p; p = strtok_r(NULL, ":", &last)) {
int r;
struct stat stat_buf;
char * exe = malloc(strlen(p) + strlen(file) + 2);
strcpy(exe, p);
strcat(exe, "/");
strcat(exe, file);
r = stat(exe, &stat_buf);
if (r != 0) {
continue;
}
if (!(stat_buf.st_mode & 0111)) {
continue; /* XXX not technically correct; need to test perms */
}
2018-10-12 09:40:45 +03:00
2018-02-25 08:13:54 +03:00
return execve(exe, argv, environ);
}
free(xpath);
errno = ENOENT;
return -1;
} else if (file) {
return execve(file, argv, environ);
}
errno = ENOENT;
return -1;
}
2018-06-25 10:28:13 +03:00
int execv(const char * file, char * const argv[]) {
return execve(file, argv, environ);
}