diff options
author | Ian Moffett <ian@osmora.org> | 2025-06-13 19:16:27 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-06-13 19:16:27 -0400 |
commit | 68fbe4a2292dc5b4025dd4201fd4b892605079b7 (patch) | |
tree | b2683975dc48116a57a7c7911712b63749a176b1 | |
parent | 9f534c75cd0e29b5b829c412ced28fa846c7d911 (diff) |
kernel: spawn: Add argv + stub envp arguments
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | lib/libc/src/hyra/spawn.c | 7 | ||||
-rw-r--r-- | sys/include/sys/limits.h | 1 | ||||
-rw-r--r-- | sys/include/sys/spawn.h | 2 | ||||
-rw-r--r-- | sys/kern/kern_spawn.c | 52 | ||||
-rw-r--r-- | usr.bin/osh/osh.c | 3 | ||||
-rw-r--r-- | usr.sbin/install/install.c | 4 |
6 files changed, 56 insertions, 13 deletions
diff --git a/lib/libc/src/hyra/spawn.c b/lib/libc/src/hyra/spawn.c index 227d8f7..b4c92ef 100644 --- a/lib/libc/src/hyra/spawn.c +++ b/lib/libc/src/hyra/spawn.c @@ -35,10 +35,13 @@ * Spawn a process * * @pathname: Path to executable. + * @argv: Argument vector + * @envp: Environment vector * @flags: Spawn flags. */ pid_t -spawn(const char *pathname, int flags) +spawn(const char *pathname, char **argv, char **envp, int flags) { - return syscall(SYS_spawn, (uintptr_t)pathname, flags); + return syscall(SYS_spawn, (uintptr_t)pathname, (uintptr_t)argv, + (uintptr_t)envp, flags); } diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h index 198c963..f56958e 100644 --- a/sys/include/sys/limits.h +++ b/sys/include/sys/limits.h @@ -32,6 +32,7 @@ #define PATH_MAX 1024 #define SSIZE_MAX 32767 +#define ARG_MAX 4096 #define CHAR_BIT 8 #if defined(_KERNEL) #define CPU_MAX 256 diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h index 9d823db..0c54e4c 100644 --- a/sys/include/sys/spawn.h +++ b/sys/include/sys/spawn.h @@ -36,6 +36,6 @@ #define SPAWN_WAIT BIT(0) #if !defined(_KERNEL) -pid_t spawn(const char *pathname, int flags); +pid_t spawn(const char *pathname, char **argv, char **envp, int flags); #endif /* _KERNEL */ #endif /* !_SYS_SPAWN_H_ */ diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c index 6addf8f..a953a6e 100644 --- a/sys/kern/kern_spawn.c +++ b/sys/kern/kern_spawn.c @@ -45,10 +45,17 @@ #define pr_trace(fmt, ...) kprintf("spawn: " fmt, ##__VA_ARGS__) #define pr_error(...) pr_trace(__VA_ARGS__) +#define ARGVP_MAX (ARG_MAX / sizeof(void *)) + static volatile size_t nthreads = 0; +/* + * TODO: envp + */ struct spawn_args { char path[PATH_MAX]; + char argv_blk[ARG_MAX]; + char *argv[ARGVP_MAX]; }; static inline void @@ -67,7 +74,6 @@ spawn_thunk(void) struct proc *cur; struct execve_args execve_args; struct spawn_args *args; - char *argv[] = { NULL, NULL }; char *envp[] = { NULL }; cur = this_td(); @@ -76,11 +82,9 @@ spawn_thunk(void) memset(pathbuf, 0, sizeof(pathbuf)); memcpy(pathbuf, path, strlen(path)); - argv[0] = (char *)pathbuf; - execve_args.pathname = argv[0]; - execve_args.argv = argv; + execve_args.pathname = pathbuf; + execve_args.argv = (char **)&args->argv[0]; execve_args.envp = envp; - path = NULL; if (execve(cur, &execve_args) != 0) { @@ -210,19 +214,26 @@ get_child(struct proc *cur, pid_t pid) /* * arg0: The file /path/to/executable - * arg1: Optional flags (`flags') + * arg1: Argv + * arg2: Envp (TODO) + * arg3: Optional flags (`flags') */ scret_t sys_spawn(struct syscall_args *scargs) { struct spawn_args *args; - const char *u_path; + char *path; + const char *u_path, **u_argv; + const char *u_p = NULL; struct proc *td; int flags, error; + size_t len, bytes_copied = 0; + size_t argv_i = 0; td = this_td(); - flags = scargs->arg1; u_path = (const char *)scargs->arg0; + u_argv = (const char **)scargs->arg1; + flags = scargs->arg3; args = dynalloc(sizeof(*args)); if (args == NULL) { @@ -235,5 +246,30 @@ sys_spawn(struct syscall_args *scargs) return error; } + memset(args->argv, 0, ARG_MAX); + for (size_t i = 0; i < ARG_MAX - 1; ++i) { + error = copyin(&u_argv[argv_i], &u_p, sizeof(u_p)); + if (error < 0) { + dynfree(args); + return error; + } + if (u_p == NULL) { + args->argv[argv_i++] = NULL; + break; + } + + path = &args->argv_blk[i]; + error = copyinstr(u_p, path, ARG_MAX - bytes_copied); + if (error < 0) { + dynfree(args); + return error; + } + + args->argv[argv_i++] = &args->argv_blk[i]; + len = strlen(path); + bytes_copied += (len + 1); + i += len; + } + return spawn(td, spawn_thunk, args, flags, NULL); } diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c index 93ac876..aaa4502 100644 --- a/usr.bin/osh/osh.c +++ b/usr.bin/osh/osh.c @@ -219,6 +219,7 @@ static int cmd_run(const char *input, int argc, char *argv[]) { char bin_path[256]; + char *envp[1] = { NULL }; int error; snprintf(bin_path, sizeof(bin_path), "/usr/bin/%s", input); @@ -228,7 +229,7 @@ cmd_run(const char *input, int argc, char *argv[]) return -1; } - if ((error = spawn(bin_path, SPAWN_WAIT)) < 0) { + if ((error = spawn(bin_path, argv, envp, SPAWN_WAIT)) < 0) { return error; } diff --git a/usr.sbin/install/install.c b/usr.sbin/install/install.c index 5cedc06..91f75df 100644 --- a/usr.sbin/install/install.c +++ b/usr.sbin/install/install.c @@ -82,6 +82,8 @@ installer_clearscr(uint32_t color, bool setattr) static void pre_installer(void) { + char *argv[] = { "/usr/bin/osh", NULL }; + char *envp[] = { NULL }; char c; puts("[S]hell/[I]nstall"); @@ -90,7 +92,7 @@ pre_installer(void) if (c == 's') { puts("\033[0m"); installer_clearscr(0x000000, false); - spawn("/usr/bin/osh", SPAWN_WAIT); + spawn(argv[0], argv, envp, SPAWN_WAIT); installer_clearscr(INSTALLER_BG, true); break; } else if (c == 'i') { |