diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/proc.c | 3 | ||||
| -rw-r--r-- | common/tcb.c | 6 | ||||
| -rw-r--r-- | common/uapi/proc.c | 39 |
3 files changed, 41 insertions, 7 deletions
diff --git a/common/proc.c b/common/proc.c index 270ec0c..137a2fe 100644 --- a/common/proc.c +++ b/common/proc.c @@ -39,6 +39,9 @@ stat_t init_proc(void *fdt) /* set current tcb */ use_tcb(t); + /* init process has all capabilities */ + set_caps(t->caps, 0, CAP_CAPS | CAP_PROC | CAP_CALL); + /* allocate stacks after ELF file to make sure nothing of importance * clashes */ return prepare_proc(t, get_init_base(fdt), 0); diff --git a/common/tcb.c b/common/tcb.c index 675aa1f..1c1a623 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -300,6 +300,12 @@ __weak struct tcb *cur_tcb() struct tcb *cur_proc() { struct tcb *t = cur_tcb(); + return get_tcb(t->pid); +} + +struct tcb *eff_proc() +{ + struct tcb *t = cur_tcb(); return get_tcb(t->eid); } diff --git a/common/uapi/proc.c b/common/uapi/proc.c index ea42a3a..0039195 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -17,16 +17,25 @@ /** * Create syscall handler. * - * \todo Implement. - * * @param func Function to jump to at thread creation. - * @param arg Argument to pass to the function. + * @param d0 Argument 0. + * @param d1 Argument 1. + * @param d2 Argument 2. + * @param d3 Argument 3. * - * @return \ref OK and 0. + * @return ERR_OOMEM if thread creation was unsuccessful, otherwise OK and the + * thread id. */ SYSCALL_DEFINE5(create)(sys_arg_t func, - sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, sys_arg_t d3){ - return SYS_RET1(OK); + sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, sys_arg_t d3){ + struct tcb *t = create_thread(cur_tcb()); + if (!t) + return SYS_RET1(ERR_OOMEM); + + set_args(t, SYS_RET5(t->tid, d0, d1, d2, d3)); + set_return(t, func); + + return SYS_RET2(OK, t->tid); } /** @@ -45,7 +54,11 @@ SYSCALL_DEFINE5(create)(sys_arg_t func, * @return \ref OK and 0. */ SYSCALL_DEFINE0(fork)(){ - struct tcb *t = create_proc(cur_proc()); + struct tcb *c = cur_proc(); + if (!(get_caps(c->caps, 0) & CAP_PROC)) + return SYS_RET1(ERR_PERM); + + struct tcb *t = create_proc(eff_proc()); if (!t) return SYS_RET1(ERR_OOMEM); @@ -103,6 +116,10 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ */ SYSCALL_DEFINE2(spawn)(sys_arg_t bin, sys_arg_t interp) { + struct tcb *c = cur_proc(); + if (!(get_caps(c->caps, 0) & CAP_PROC)) + return SYS_RET1(ERR_PERM); + struct tcb *t = create_proc(NULL); if (!t) return SYS_RET1(ERR_OOMEM); @@ -120,6 +137,10 @@ SYSCALL_DEFINE2(spawn)(sys_arg_t bin, sys_arg_t interp) */ SYSCALL_DEFINE1(kill)(sys_arg_t tid) { + struct tcb *c = cur_proc(); + if (!(get_caps(c->caps, 0) & CAP_PROC)) + return SYS_RET1(ERR_PERM); + return SYS_RET1(OK); } @@ -134,6 +155,10 @@ SYSCALL_DEFINE1(kill)(sys_arg_t tid) * @return \ref OK. */ SYSCALL_DEFINE1(swap)(sys_arg_t tid){ + struct tcb *c = cur_proc(); + if (!(get_caps(c->caps, 0) & CAP_PROC)) + return SYS_RET1(ERR_PERM); + struct tcb *t = get_tcb(tid); if (!t) return SYS_RET1(ERR_INVAL); |
