1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <tb/sb.h>
#include <tb/sv.h>
#include <unistd.h>
int execv(const char *pathname, char *const argv[]) {
struct SYS_EXEC_PARAMS args = {.path = pathname, .argv = (char **)argv};
RC_ERRNO(syscall(SYS_EXEC, &args, 0, 0, 0, 0));
}
int execvp(const char *file, char *const argv[]) {
if ('/' == *file) {
return execv(file, argv);
}
char *p = getenv("PATH");
if (!p) {
errno = ENOENT;
return -1;
}
struct sv paths = C_TO_SV(p);
struct sb builder;
sb_init(&builder);
for (;;) {
struct sv path = sv_split_delim(paths, &paths, ':');
if (0 == sv_length(path)) {
break;
}
sb_reset(&builder);
sb_append_sv(&builder, path);
sb_append(&builder, "/");
sb_append(&builder, file);
sb_append_buffer(&builder, "\0", 1);
if (-1 == execv(builder.string, argv)) {
continue;
}
}
sb_free(&builder);
errno = ENOENT;
return -1;
}
|