#include #include "syscall.h" #include "proc/proc.h" #include "spinlock/spinlock.h" #include "errors.h" #include "util/util.h" #include "sysdefs/processctl.h" #include "vfs/vfs.h" #include "path/path.h" #include "kprintf.h" #include "dlmalloc/malloc.h" #define PCTL_MP_MAX 0xff #define PCTL_PATH_MAX VFS_PATH_MAX int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) { uint64_t pid = pid1; uint64_t cmd = cmd1; int32_t ret = E_OK; if (pid == (uint64_t)-1) { pid = PROCS.current->pid; } spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); if (proc == NULL) { if (cmd == PCTL_POLLSTATE) { ret = PROC_DIED; goto done; } ret = E_INVALIDARGUMENT; goto done; } switch (cmd) { case PCTL_KILL: { proc_kill(proc); ret = E_DOSCHEDULING; } break; case PCTL_SPAWN: { const char *opath = (const char *)arg1; if (opath == NULL) { ret = E_INVALIDARGUMENT; goto done; } char mp[PCTL_MP_MAX]; char path[PCTL_PATH_MAX]; path_parse(opath, mp, path); Proc *newproc = proc_spawnuser(mp, path); if (newproc == NULL) { ret = E_SPAWNERROR; goto done; } size_t argslen = arg3; char *(*args)[] = (char *(*)[])arg2; for (size_t i = 0; i < argslen; i++) { PROC_ARG(newproc, (*args)[i]); } proc_register(newproc); ret = newproc->pid; } break; case PCTL_POLLSTATE: { ret = proc->state; } break; case PCTL_RUN: { proc->state = PROC_READY; } break; case PCTL_GETPID: { ret = proc->pid; } break; case PCTL_ARGLEN: { ret = proc->procargs.len; } break; case PCTL_ARGV: { char **argbuf = (char **)arg1; if (argbuf == NULL) { ret = E_INVALIDARGUMENT; goto done; } size_t len = arg2; ProcArg *arg = proc->procargs.list; size_t i = 0; while (arg) { if (i == len) { break; } if (argbuf[i] == NULL) { ret = E_INVALIDARGUMENT; goto done; } hal_strcpy(argbuf[i], arg->string); arg = arg->next; i++; } ret = E_OK; } break; case PCTL_PLS_SZ: { size_t i = 0; spinlock_acquire(&PROCS.spinlock); Proc *p = PROCS.procs; while (p) { i++; p = p->next; } spinlock_release(&PROCS.spinlock); ret = i; } break; case PCTL_PLS_STAT: { uint64_t pidx = arg1; ProcStat *stat = (ProcStat *)arg2; if (stat == NULL) { ret = E_INVALIDARGUMENT; goto done; } size_t i = 0; spinlock_acquire(&PROCS.spinlock); Proc *p = PROCS.procs; while (p) { if (i == pidx) { stat->pid = p->pid; hal_strcpy(stat->name, p->name); stat->state = p->state; stat->kern = p->kern; break; } i++; p = p->next; } spinlock_release(&PROCS.spinlock); ret = E_OK; } break; default: { ret = E_INVALIDARGUMENT; } break; } done: return ret; }