#include #include #include "syscall.h" #include "proc/proc.h" #include "spinlock/spinlock.h" #include "errors.h" #include "util/util.h" #include "sysdefs/proc.h" #include "vfs/vfs.h" #include "path/path.h" #include "kprintf.h" #include "dlmalloc/malloc.h" #include "ipc/pipe/pipe.h" #define _MP_MAX 0xff #define _PATH_MAX VFS_PATH_MAX int32_t SYSCALL1(sys_proc_kill, pid1) { uint64_t pid = pid1; int32_t ret = E_OK; if (pid == (uint64_t)-1) { pid = _caller_pid; } spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); proc_kill(proc); ret = E_DOSCHEDULING; return ret; } int32_t SYSCALL3(sys_proc_spawn, opath1, args1, argslen1) { int32_t ret = E_OK; spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, _caller_pid); spinlock_release(&PROCS.spinlock); const char *opath = (const char *)opath1; if (opath == NULL) { ret = E_INVALIDARGUMENT; goto done; } char mp[_MP_MAX]; char path[_PATH_MAX]; path_parse(opath, mp, path); Proc *newproc = proc_spawnuser(mp, path); if (newproc == NULL) { ret = E_SPAWNERROR; goto done; } size_t argslen = argslen1; char **args = (char **)args1; if (args != NULL && argslen > 0) { for (size_t i = 0; i < argslen; i++) { PROC_ARG(newproc, args[i]); } } for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) { if (newproc->pipes[i] != NULL) { ipc_pipefree(newproc->pipes[i]); dlfree(newproc->pipes[i]); } newproc->pipes[i] = proc->pipes[i]; } proc_register(newproc); ret = newproc->pid; done: return ret; } int32_t SYSCALL1(sys_proc_pollstate, pid1) { uint64_t pid = pid1; int32_t ret = E_OK; if (pid == (uint64_t)-1) { pid = _caller_pid; } spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); if (proc == NULL) { ret = PROC_DIED; goto done; } ret = proc->state; done: return ret; } int32_t SYSCALL0(sys_proc_getpid) { return _caller_pid; } int32_t SYSCALL1(sys_proc_run, pid1) { uint64_t pid = pid1; int32_t ret = E_OK; spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); if (proc == NULL) { ret = E_INVALIDARGUMENT; goto done; } proc->state = PROC_READY; done: return ret; } int32_t SYSCALL1(sys_proc_arglen, pid1) { uint64_t pid = pid1; int32_t ret = E_OK; if (pid == (uint64_t)-1) { pid = _caller_pid; } spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); ret = proc->procargs.len; return ret; } int32_t SYSCALL4(sys_proc_argv, pid1, argslen1, argbuf1, maxargs1) { uint64_t pid = pid1; int32_t ret = E_OK; if (pid == (uint64_t)-1) { pid = _caller_pid; } spinlock_acquire(&PROCS.spinlock); Proc *proc = NULL; LL_FINDPROP(PROCS.procs, proc, pid, pid); spinlock_release(&PROCS.spinlock); size_t *argslen = (size_t *)argslen1; char **argbuf = (char **)argbuf1; if (argbuf == NULL) { ret = E_INVALIDARGUMENT; goto done; } size_t maxargs = (size_t)maxargs1; ProcArg *arg, *argtmp; size_t i; LL_FOREACH_SAFE_IDX_LIMIT(proc->procargs.list, arg, argtmp, i, maxargs) { if (argbuf[i] == NULL) { ret = E_INVALIDARGUMENT; goto done; } hal_strcpy(argbuf[i], arg->string); } *argslen = i; ret = E_OK; done: return ret; } int32_t SYSCALL0(sys_proc_listsize) { int32_t ret; Proc *p, *ptmp; size_t i; spinlock_acquire(&PROCS.spinlock); LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i); spinlock_release(&PROCS.spinlock); ret = i; return ret; } int32_t SYSCALL2(sys_proc_stat, pidx, pstat1) { int32_t ret; ProcStat *stat = (ProcStat *)pstat1; if (stat == NULL) { ret = E_INVALIDARGUMENT; goto done; } Proc *p, *ptmp; size_t i; spinlock_acquire(&PROCS.spinlock); LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i) { if (i == pidx) { stat->pid = p->pid; hal_strcpy(stat->name, p->name); stat->state = p->state; VasRange *vas, *vastmp; LL_FOREACH_SAFE(p->vas, vas, vastmp) { stat->usemem += vas->size; } hal_memcpy(&stat->time, &p->time, sizeof(p->time)); break; } } spinlock_release(&PROCS.spinlock); ret = E_OK; done: return ret; }