From 2f8da5a5eb726f3c05b8fca19e82928d8acb147d Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 10 Oct 2025 18:49:43 -0400 Subject: kern: proc: Add initial penv block support This commit introduces the initial support for the process environment block and implements argv and argc. Signed-off-by: Ian Moffett --- src/cmd/init/init.c | 2 +- src/lib/libc/src/l5/spawn.c | 15 +++++- src/sys/arch/amd64/os/os_proc.c | 8 ++++ src/sys/include/sys/limits.h | 2 + src/sys/include/sys/proc.h | 16 +++++-- src/sys/os/os_proc.c | 103 ++++++++++++++++++++++++++++++++++++++-- 6 files changed, 133 insertions(+), 13 deletions(-) diff --git a/src/cmd/init/init.c b/src/cmd/init/init.c index befaa18..6b05bfa 100644 --- a/src/cmd/init/init.c +++ b/src/cmd/init/init.c @@ -34,7 +34,7 @@ void main(void) { char shell_path[] = "/usr/bin/hush"; - char *argv_dmmy[] = {NULL}; + char *argv_dmmy[] = { "/usr/bin/hush", NULL }; spawn(shell_path, argv_dmmy); for (;;); diff --git a/src/lib/libc/src/l5/spawn.c b/src/lib/libc/src/l5/spawn.c index 9f0c80b..50ade53 100644 --- a/src/lib/libc/src/l5/spawn.c +++ b/src/lib/libc/src/l5/spawn.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -35,14 +36,24 @@ int spawn(const char *path, char **argv) { + struct penv_blk blk; + size_t argc = 0; + if (path == NULL || argv == NULL) { return -EINVAL; } - /* TODO: We must handle the penv_blk */ + /* Get the argument count */ + while (argv[argc++] != NULL); + --argc; + + /* Setup the penv block */ + blk.argv = argv; + blk.argc = argc; + return syscall( SYS_spawn, (uintptr_t)path, - 0 + (uintptr_t)&blk ); } diff --git a/src/sys/arch/amd64/os/os_proc.c b/src/sys/arch/amd64/os/os_proc.c index b8e7c99..f2eb2b3 100644 --- a/src/sys/arch/amd64/os/os_proc.c +++ b/src/sys/arch/amd64/os/os_proc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include extern struct proc g_rootproc; @@ -237,6 +238,7 @@ md_proc_kill(struct proc *procp, int flags) { const size_t PSIZE = DEFAULT_PAGESIZE; struct proc *self; + struct penv_blk *envblk; struct pcore *core = this_core(); struct md_pcb *pcbp; struct vm_range *range; @@ -259,6 +261,12 @@ md_proc_kill(struct proc *procp, int flags) vm_free_frame(range->pa_base, range->len / PSIZE); } + if ((envblk = procp->envblk) != NULL) { + ptrbox_terminate(procp->envblk_box); + kfree(envblk->argv); + procp->envblk = NULL; + } + /* Release the VAS */ pcbp = &procp->pcb; mmu_free_vas(&pcbp->vas); diff --git a/src/sys/include/sys/limits.h b/src/sys/include/sys/limits.h index 5e32233..180d3fc 100644 --- a/src/sys/include/sys/limits.h +++ b/src/sys/include/sys/limits.h @@ -37,5 +37,7 @@ #define SC_MAX 64 /* Max syscalls */ #define SCWIN_MAX 2 /* Max syscall windows */ #define FD_MAX 256 /* Max file descriptors */ +#define NARG_MAX 16 /* Max arguments */ +#define ARG_LEN 64 /* Max length per argument */ #endif /* !_SYS_LIMITS_H_ */ diff --git a/src/sys/include/sys/proc.h b/src/sys/include/sys/proc.h index ea89d4c..5bffc3e 100644 --- a/src/sys/include/sys/proc.h +++ b/src/sys/include/sys/proc.h @@ -35,12 +35,15 @@ #include #include #include +#if defined(_KERNEL) +#include #include #include #include #include #include #include /* standard */ +#endif /* _KERNEL */ /* * The stack starts here and grows down @@ -48,18 +51,20 @@ #define STACK_TOP 0xBFFFFFFF #define STACK_LEN 4096 -#if defined(_KERNEL) - /* * Process environment block, used to store arguments * and other information. * - * @pid: PID of the process that owns this block + * @argv: Argument vector + * @argc: Argument count */ struct penv_blk { - pid_t pid; + char **argv; + uint16_t argc; }; +#if defined(_KERNEL) + /* * A process describes a running program image * on the system. @@ -81,7 +86,8 @@ struct proc { struct md_pcb pcb; struct syscall_domain scdom; struct filedesc *fdtab[FD_MAX]; - struct penv_blk envblk; + struct penv_blk *envblk; + struct ptrbox *envblk_box; mac_level_t level; struct spinlock maplist_lock; sigtab_t sigtab; diff --git a/src/sys/os/os_proc.c b/src/sys/os/os_proc.c index 14f8ceb..27ffac8 100644 --- a/src/sys/os/os_proc.c +++ b/src/sys/os/os_proc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,94 @@ static pid_t next_pid = 0; +/* + * Copy a process environment block from userland + */ +static struct penv_blk * +penv_blk_cpy(struct proc *procp, struct penv_blk *u_blk) +{ + struct penv_blk *blk; + int error; + char argbuf[ARG_LEN]; + char **u_argv; + char *arg; + uint16_t i; + + if (u_blk == NULL) { + return NULL; + } + + /* Allocate a kernel copy */ + blk = kalloc(sizeof(*blk)); + if (blk == NULL) { + return NULL; + } + + /* Copy in the user side */ + memset(blk, 0, sizeof(*blk)); + error = copyin(u_blk, blk, sizeof(*blk)); + if (error < 0) { + printf("penv_blk_cpy: bad u_blk\n"); + kfree(blk); + return NULL; + } + + /* Too many args? */ + if (blk->argc > NARG_MAX) { + printf("penv_blk_cpy: argc > ARG_MAX!!\n"); + kfree(blk); + return NULL; + } + + /* Allocate a pointer box for args */ + if (ptrbox_init(&procp->envblk_box) < 0) { + return NULL; + } + + /* Allocate a new string store */ + u_argv = blk->argv; + blk->argv = ptrbox_alloc( + sizeof(char *) * blk->argc, + procp->envblk_box + ); + if (blk->argv == NULL) { + kfree(blk); + return NULL; + } + + /* Dup each arg */ + for (i = 0; i < blk->argc; ++i) { + error = proc_check_addr( + procp, + (uintptr_t)&u_argv[i], + sizeof(char *) + ); + + /* Is the address valid? */ + if (error != 0) { + printf("penv_blk_cpy: bad arg pointer (%d)\n", i); + break; + } + + error = copyinstr(u_argv[i], argbuf, ARG_LEN); + if (error < 0) { + printf("penv_blk_cpy: bad arg pointer (%d)\n", i); + break; + } + + blk->argv[i] = ptrbox_strdup(argbuf, procp->envblk_box); + } + + /* Cleanup on error */ + if (error != 0) { + ptrbox_terminate(procp->envblk_box); + kfree(blk); + blk = NULL; + } + + return blk; +} + /* * Deallocate saved memory ranges * @@ -204,19 +293,22 @@ proc_spawn(const char *path, struct penv_blk *envbp) panic("spawn: failed to arbitrate core\n"); } - if (envbp != NULL) { - memcpy(&proc->envblk, envbp, sizeof(proc->envblk)); - } - + proc->envblk = envbp; md_set_ip(proc, elf.entrypoint); sched_enq(&core->scq, proc); return proc->pid; } +/* + * ARG0: Pathname to spawn + * ARG1: Process environment block + */ scret_t sys_spawn(struct syscall_args *scargs) { const char *u_path = SCARG(scargs, const char *, 0); + struct penv_blk *u_blk = SCARG(scargs, struct penv_blk *, 1); + struct penv_blk *envblk; char buf[PATH_MAX]; int error; @@ -225,5 +317,6 @@ sys_spawn(struct syscall_args *scargs) return error; } - return proc_spawn(buf, NULL); + envblk = penv_blk_cpy(proc_self(), u_blk); + return proc_spawn(buf, envblk); } -- cgit v1.2.3