From 19482e5ef5b6710b4b9a52edcb1bb39692336d7a Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Sun, 15 Dec 2024 01:30:24 +0100 Subject: libc: Add setenv/getenv --- userland/libc/unistd/execvp.c | 46 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'userland/libc/unistd/execvp.c') diff --git a/userland/libc/unistd/execvp.c b/userland/libc/unistd/execvp.c index e38b4b7..af3ed29 100644 --- a/userland/libc/unistd/execvp.c +++ b/userland/libc/unistd/execvp.c @@ -1,8 +1,48 @@ +#include +#include +#include +#include #include +#include +#include #include -// FIXME: Path resolution +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[]) { - struct SYS_EXEC_PARAMS args = {.path = file, .argv = (char **)argv}; - return syscall(SYS_EXEC, &args, 0, 0, 0, 0); + 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; } -- cgit v1.2.3