feat: implement per-process environment variables (AI)

- Created env.c/h: key=value store with ENV_MAX_VARS=32 entries per
  process. Supports get, set, unset, and copy operations.
- Added env_block_t and cwd[128] fields to process_t struct.
- process_create() initializes CWD=/ by default.
- Fork inherits environment via memcpy of the entire process_t.
- Added SYS_GETENV (8) and SYS_SETENV (9) system calls.
- Created env-test user app that verifies: CWD default, set/get,
  and inheritance across fork.
- Updated kernel.c to launch 'sh' as init process (for next task).
- Updated README.md to check off environment variables task.

Tested: env-test reads CWD=/, sets TEST=hello, reads it back,
forks child which inherits TEST=hello. All verified via QEMU.
This commit is contained in:
AI
2026-02-23 12:46:12 +00:00
parent 6910deae7c
commit 9cef025687
9 changed files with 359 additions and 8 deletions

View File

@@ -9,6 +9,7 @@
#include "syscall.h"
#include "process.h"
#include "env.h"
#include "port_io.h"
#include "vga.h"
#include <stddef.h>
@@ -139,6 +140,37 @@ static int32_t sys_exec(registers_t *regs) {
return -1; /* Not implemented yet */
}
/**
* Handle SYS_GETENV: get an environment variable.
* EBX = key pointer, ECX = value buffer pointer, EDX = buffer size.
* Returns length of value, or -1 if not found.
*/
static int32_t sys_getenv(registers_t *regs) {
const char *key = (const char *)regs->ebx;
char *buf = (char *)regs->ecx;
uint32_t bufsize = regs->edx;
process_t *cur = process_current();
if (!cur) return -1;
return env_get(&cur->env, key, buf, bufsize);
}
/**
* Handle SYS_SETENV: set an environment variable.
* EBX = key pointer, ECX = value pointer (NULL to unset).
* Returns 0 on success, -1 on error.
*/
static int32_t sys_setenv(registers_t *regs) {
const char *key = (const char *)regs->ebx;
const char *value = (const char *)regs->ecx;
process_t *cur = process_current();
if (!cur) return -1;
return env_set(&cur->env, key, value);
}
/** System call dispatch table. */
typedef int32_t (*syscall_fn)(registers_t *);
static syscall_fn syscall_table[NUM_SYSCALLS] = {
@@ -150,6 +182,8 @@ static syscall_fn syscall_table[NUM_SYSCALLS] = {
[SYS_YIELD] = sys_yield,
[SYS_WAITPID] = sys_waitpid,
[SYS_EXEC] = sys_exec,
[SYS_GETENV] = sys_getenv,
[SYS_SETENV] = sys_setenv,
};
void syscall_handler(registers_t *regs) {