Partial exec, environment variables

This commit is contained in:
2026-03-17 19:14:29 +01:00
parent b1648a146a
commit c69ee1b745
9 changed files with 199 additions and 26 deletions

View File

@@ -340,7 +340,7 @@ static void help (struct context* context) {
} }
static void cmd_cancel_proc (void* arg) { static void cmd_cancel_proc (void* arg) {
int pid = (int)arg; int pid = (int)(uintptr_t)arg;
char ch = 0; char ch = 0;
do { do {
@@ -350,6 +350,18 @@ static void cmd_cancel_proc (void* arg) {
kill (pid); kill (pid);
} }
static void cmd_collect_proc (void* arg) {
#define RECV_MAX (1024 * 16)
for (;;) {
char recv[RECV_MAX];
memset (recv, 0, sizeof (recv));
mail_receive (&recv, sizeof (recv) - 1);
mail_send (e_pgid, recv, strlen (recv));
}
}
static void execute_cmd (struct ast_cmd* cmd, struct context* context) { static void execute_cmd (struct ast_cmd* cmd, struct context* context) {
if (strcmp (cmd->name, "echo") == 0) { if (strcmp (cmd->name, "echo") == 0) {
echo (context, cmd->args, cmd->arg_count); echo (context, cmd->args, cmd->arg_count);
@@ -398,19 +410,40 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) {
return; return;
} }
int pid = exec (volume, path); int pid = exec_partial (volume, path);
if (pid < 0) { if (pid < 0) {
cprintf (context, "ERROR could not run '%s': %s\n", cmd->name, str_status[-pid]); cprintf (context, "ERROR could not run '%s': %s\n", cmd->name, str_status[-pid]);
return; return;
} }
for (int i = 0; i < cmd->arg_count; i++) {
char* arg = cmd->args[i];
char *key, *value;
char* sep = strchr (arg, '=');
if (sep != NULL) {
*sep = '\0';
key = arg;
value = sep + 1;
env_set (pid, key, value, strlen (value) + 1);
}
}
exec_partial_fini (pid);
struct process_data* cancel_pdata = process_spawn (&cmd_cancel_proc, (void*)pid); struct process_data* cancel_pdata = process_spawn (&cmd_cancel_proc, (void*)pid);
struct process_data* collect_pdata = process_spawn (&cmd_collect_proc, NULL);
wait_for_pid (pid); wait_for_pid (pid);
kill (cancel_pdata->pid); kill (cancel_pdata->pid);
process_data_free (cancel_pdata); process_data_free (cancel_pdata);
kill (collect_pdata->pid);
process_data_free (collect_pdata);
} }
} }

View File

@@ -25,5 +25,6 @@
#define ST_REMOVE_ERROR 21 #define ST_REMOVE_ERROR 21
#define ST_XDRV_READ_ERROR 22 #define ST_XDRV_READ_ERROR 22
#define ST_XDRV_WRITE_ERROR 23 #define ST_XDRV_WRITE_ERROR 23
#define ST_NOT_PARTIAL 24
#endif // _M_STATUS_H #endif // _M_STATUS_H

View File

@@ -32,5 +32,7 @@
#define SYS_CREATE_VOLUME 29 #define SYS_CREATE_VOLUME 29
#define SYS_ENV_SET 30 #define SYS_ENV_SET 30
#define SYS_ENV_GET 31 #define SYS_ENV_GET 31
#define SYS_EXEC_PARTIAL 32
#define SYS_EXEC_PARTIAL_FINI 33
#endif // _M_SYSCALL_DEFS_H #endif // _M_SYSCALL_DEFS_H

View File

@@ -212,6 +212,18 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu
rctx_insert_cpu (rctx, cpu); rctx_insert_cpu (rctx, cpu);
} }
void proc_register_partial (struct proc* proc) {
uint64_t fpt, fp;
spin_lock (&proc_tree_lock, &fpt);
spin_lock (&proc->lock, &fp);
rbtree_insert (struct proc, &proc_tree, &proc->proc_tree_link, proc_tree_link, pid);
spin_unlock (&proc->lock, fp);
spin_unlock (&proc_tree_lock, fpt);
}
/* caller holds cpu->lock */ /* caller holds cpu->lock */
static struct proc* proc_find_sched (struct cpu* cpu) { static struct proc* proc_find_sched (struct cpu* cpu) {
uint64_t fp; uint64_t fp;

View File

@@ -22,6 +22,7 @@
/* process states */ /* process states */
#define PROC_READY 0 #define PROC_READY 0
#define PROC_SUSPENDED 1 #define PROC_SUSPENDED 1
#define PROC_PARTIAL 2
/* process flags */ /* process flags */
#define PROC_USTK_PREALLOC (1 << 0) #define PROC_USTK_PREALLOC (1 << 0)
@@ -61,6 +62,8 @@ struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx); void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx);
void proc_register_partial (struct proc* proc);
struct proc* proc_find_pid (int pid); struct proc* proc_find_pid (int pid);
struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* path, struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* path,

View File

@@ -396,6 +396,101 @@ DEFINE_SYSCALL (sys_exec) {
return SYSRESULT (pid); return SYSRESULT (pid);
} }
/* int exec_partial (char* volume, char* path) */
DEFINE_SYSCALL (sys_exec_partial) {
uint64_t fpg, fp;
uintptr_t uvaddr_volume = a1;
uintptr_t uvaddr_path = a2;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t out_paddr;
spin_lock (&proc->lock, &fp);
struct procgroup* procgroup = proc->procgroup;
int pid1 = proc->pid;
spin_unlock (&proc->lock, fp);
spin_lock (&procgroup->lock, &fpg);
out_paddr = mm_v2p (&procgroup->pd, uvaddr_path);
spin_unlock (&procgroup->lock, fpg);
if (out_paddr == 0)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr);
spin_lock (&procgroup->lock, &fpg);
out_paddr = mm_v2p (&procgroup->pd, uvaddr_volume);
if (out_paddr == 0) {
spin_unlock (&procgroup->lock, fpg);
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
}
const char* volume = (const char*)((uintptr_t)hhdm->offset + out_paddr);
struct proc* new = proc_from_file (proc, volume, path, rctx);
if (new == NULL) {
spin_unlock (&procgroup->lock, fpg);
return SYSRESULT (-ST_EXEC_ERROR);
}
spin_unlock (&procgroup->lock, fpg);
int pid = new->pid;
new->exec_pid = pid1;
new->state = PROC_PARTIAL;
proc_register_partial (new);
return SYSRESULT (pid);
}
/* int exec_partial_fini (int pid) */
DEFINE_SYSCALL (sys_exec_partial_fini) {
uint64_t fp, fc;
int pid = (int)a1;
struct proc* target_proc = proc_find_pid (pid);
if (target_proc == NULL)
return SYSRESULT (-ST_NOT_FOUND);
spin_lock (&target_proc->lock, &fp);
if (target_proc->state != PROC_PARTIAL) {
spin_unlock (&target_proc->lock, fp);
return SYSRESULT (-ST_NOT_PARTIAL);
}
spin_unlock (&target_proc->lock, fp);
struct cpu* cpu = cpu_find_lightest ();
spin_lock (&cpu->lock, &fc);
spin_lock (&target_proc->lock, &fp);
target_proc->cpu = cpu;
target_proc->state = PROC_READY;
cpu->proc_run_q_count++;
list_append (cpu->proc_run_q, &target_proc->cpu_run_q_link);
if (cpu->proc_current == NULL)
cpu->proc_current = target_proc;
spin_unlock (&target_proc->lock, fp);
spin_unlock (&cpu->lock, fc);
rctx_insert_cpu (rctx, cpu);
return SYSRESULT (ST_OK);
}
/* int volume_open (char* volume) */ /* int volume_open (char* volume) */
DEFINE_SYSCALL (sys_volume_open) { DEFINE_SYSCALL (sys_volume_open) {
uint64_t fpg, fp; uint64_t fpg, fp;
@@ -688,8 +783,6 @@ DEFINE_SYSCALL (sys_wait_for_pid) {
/* int kill (int pid) */ /* int kill (int pid) */
DEFINE_SYSCALL (sys_kill) { DEFINE_SYSCALL (sys_kill) {
uint64_t fp;
int pid = (int)a1; int pid = (int)a1;
struct proc* target_proc = proc_find_pid (pid); struct proc* target_proc = proc_find_pid (pid);
@@ -810,21 +903,28 @@ DEFINE_SYSCALL (sys_create_volume) {
return SYSRESULT (vfs_create_volume (proc, rctx, key, type, device, false)); return SYSRESULT (vfs_create_volume (proc, rctx, key, type, device, false));
} }
/* int env_set (char* key, void* buffer, size_t size) */ /* int env_set (int pid, char* key, void* buffer, size_t size) */
DEFINE_SYSCALL (sys_env_set) { DEFINE_SYSCALL (sys_env_set) {
uint64_t fp, fpg; uint64_t fp, fpg;
uintptr_t uvaddr_key = a1; int pid = (int)a1;
uintptr_t uvaddr_buffer = a2; uintptr_t uvaddr_key = a2;
size_t size = (size_t)a3; uintptr_t uvaddr_buffer = a3;
size_t size = (size_t)a4;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response; struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
struct proc* target_proc = proc_find_pid (pid);
if (target_proc == NULL) {
return SYSRESULT (-ST_NOT_FOUND);
}
uintptr_t out_paddr; uintptr_t out_paddr;
spin_lock (&proc->lock, &fp); spin_lock (&target_proc->lock, &fp);
struct procgroup* procgroup = proc->procgroup; struct procgroup* procgroup = target_proc->procgroup;
spin_unlock (&proc->lock, fp); spin_unlock (&target_proc->lock, fp);
spin_lock (&procgroup->lock, &fpg); spin_lock (&procgroup->lock, &fpg);
@@ -844,24 +944,31 @@ DEFINE_SYSCALL (sys_env_set) {
if (buffer == NULL) if (buffer == NULL)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE); return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
return SYSRESULT (proc_env_set (proc, key, buffer, size)); return SYSRESULT (proc_env_set (target_proc, key, buffer, size));
} }
/* int env_get (char* key, void* buffer, size_t size) */ /* int env_get (int pid, char* key, void* buffer, size_t size) */
DEFINE_SYSCALL (sys_env_get) { DEFINE_SYSCALL (sys_env_get) {
uint64_t fp, fpg; uint64_t fp, fpg;
uintptr_t uvaddr_key = a1; int pid = (int)a1;
uintptr_t uvaddr_buffer = a2; uintptr_t uvaddr_key = a2;
size_t size = (size_t)a3; uintptr_t uvaddr_buffer = a3;
size_t size = (size_t)a4;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response; struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
struct proc* target_proc = proc_find_pid (pid);
if (target_proc == NULL) {
return SYSRESULT (-ST_NOT_FOUND);
}
uintptr_t out_paddr; uintptr_t out_paddr;
spin_lock (&proc->lock, &fp); spin_lock (&target_proc->lock, &fp);
struct procgroup* procgroup = proc->procgroup; struct procgroup* procgroup = target_proc->procgroup;
spin_unlock (&proc->lock, fp); spin_unlock (&target_proc->lock, fp);
spin_lock (&procgroup->lock, &fpg); spin_lock (&procgroup->lock, &fpg);
@@ -881,7 +988,7 @@ DEFINE_SYSCALL (sys_env_get) {
if (buffer == NULL) if (buffer == NULL)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE); return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
return SYSRESULT (proc_env_set (proc, key, buffer, size)); return SYSRESULT (proc_env_set (target_proc, key, buffer, size));
} }
static syscall_handler_func_t handler_table[] = { static syscall_handler_func_t handler_table[] = {
@@ -916,6 +1023,8 @@ static syscall_handler_func_t handler_table[] = {
[SYS_CREATE_VOLUME] = &sys_create_volume, [SYS_CREATE_VOLUME] = &sys_create_volume,
[SYS_ENV_SET] = &sys_env_set, [SYS_ENV_SET] = &sys_env_set,
[SYS_ENV_GET] = &sys_env_get, [SYS_ENV_GET] = &sys_env_get,
[SYS_EXEC_PARTIAL] = &sys_exec_partial,
[SYS_EXEC_PARTIAL_FINI] = &sys_exec_partial_fini,
}; };
syscall_handler_func_t syscall_find_handler (int syscall_num) { syscall_handler_func_t syscall_find_handler (int syscall_num) {

View File

@@ -28,6 +28,7 @@ static const char* str_status[] = {
[ST_REMOVE_ERROR] = "remove error", [ST_REMOVE_ERROR] = "remove error",
[ST_XDRV_READ_ERROR] = "drive read error", [ST_XDRV_READ_ERROR] = "drive read error",
[ST_XDRV_WRITE_ERROR] = "drive write error", [ST_XDRV_WRITE_ERROR] = "drive write error",
[ST_NOT_PARTIAL] = "not a partially created process",
}; };
#endif // _LIBSYSTEM_STR_STATUS_H #endif // _LIBSYSTEM_STR_STATUS_H

View File

@@ -87,10 +87,16 @@ int create_volume (const char* key, int fs_type, const char* device_key) {
return (int)do_syscall (SYS_CREATE_VOLUME, key, fs_type, device_key); return (int)do_syscall (SYS_CREATE_VOLUME, key, fs_type, device_key);
} }
int env_set (const char* key, void* buffer, size_t len) { int env_set (int pid, const char* key, void* buffer, size_t len) {
return (int)do_syscall (SYS_ENV_SET, key, buffer, len); return (int)do_syscall (SYS_ENV_SET, pid, key, buffer, len);
} }
int env_get (const char* key, void* buffer, size_t len) { int env_get (int pid, const char* key, void* buffer, size_t len) {
return (int)do_syscall (SYS_ENV_GET, key, buffer, len); return (int)do_syscall (SYS_ENV_GET, pid, key, buffer, len);
} }
int exec_partial (const char* volume, const char* path) {
return (int)do_syscall (SYS_EXEC_PARTIAL, volume, path);
}
int exec_partial_fini (int pid) { return (int)do_syscall (SYS_EXEC_PARTIAL_FINI, pid); }

View File

@@ -94,9 +94,15 @@ int remove (const char* path);
int create_volume (const char* key, int fs_type, const char* device_key); int create_volume (const char* key, int fs_type, const char* device_key);
/* Set environment variable */ /* Set environment variable */
int env_set (const char* key, void* buffer, size_t len); int env_set (int pid, const char* key, void* buffer, size_t len);
/* Get environment variable */ /* Get environment variable */
int env_get (const char* key, void* buffer, size_t len); int env_get (int pid, const char* key, void* buffer, size_t len);
/* Prepare process for execution */
int exec_partial (const char* volume, const char* path);
/* Finish process for execution - run it! */
int exec_partial_fini (int pid);
#endif // _LIBMSL_M_SYSTEM_H #endif // _LIBMSL_M_SYSTEM_H