kern
diff src/proc.c @ 72:3941e82b07f2
- implemented syscalls: exit, waitpid, getppid
- moved sys_whatever functions out of syscall.c into more reasonable files
- putting all the definitions that must be synced with userland to include/kdef.h
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 15 Oct 2011 07:45:56 +0300 |
parents | b45e2d5f0ae1 |
children | 8b21fe04ba2c |
line diff
1.1 --- a/src/proc.c Thu Oct 13 05:22:35 2011 +0300 1.2 +++ b/src/proc.c Sat Oct 15 07:45:56 2011 +0300 1.3 @@ -12,6 +12,7 @@ 1.4 #include "syscall.h" 1.5 #include "sched.h" 1.6 #include "tss.h" 1.7 +#include "kdef.h" 1.8 1.9 #define FLAGS_INTR_BIT (1 << 9) 1.10 1.11 @@ -138,7 +139,7 @@ 1.12 intr_ret(ifrm); 1.13 } 1.14 1.15 -int fork(void) 1.16 +int sys_fork(void) 1.17 { 1.18 int i, pid; 1.19 struct process *p, *parent; 1.20 @@ -189,8 +190,13 @@ 1.21 /* initialize the rest of the process structure */ 1.22 p->id = pid; 1.23 p->parent = parent->id; 1.24 + p->child_list = 0; 1.25 p->next = p->prev = 0; 1.26 1.27 + /* add to the child list */ 1.28 + p->sib_next = parent->child_list; 1.29 + parent->child_list = p; 1.30 + 1.31 /* will be copied on write */ 1.32 p->user_stack_pg = parent->user_stack_pg; 1.33 1.34 @@ -203,6 +209,105 @@ 1.35 return pid; 1.36 } 1.37 1.38 +int sys_exit(int status) 1.39 +{ 1.40 + struct process *p, *child; 1.41 + 1.42 + p = get_current_proc(); 1.43 + 1.44 + /* TODO deliver SIGCHLD to the parent */ 1.45 + 1.46 + /* find any child processes and make init adopt them */ 1.47 + child = p->child_list; 1.48 + while(child) { 1.49 + child->parent = 1; 1.50 + child = child->sib_next; 1.51 + } 1.52 + 1.53 + cleanup_vm(p); 1.54 + 1.55 + /* remove it from the runqueue */ 1.56 + remove_proc(p->id); 1.57 + 1.58 + /* make it a zombie until its parent reaps it */ 1.59 + p->state = STATE_ZOMBIE; 1.60 + p->exit_status = (status & _WSTATUS_MASK) | (_WREASON_EXITED << _WREASON_SHIFT); 1.61 + 1.62 + /* wakeup any processes waiting for it 1.63 + * we're waking up the parent's address, because waitpid waits 1.64 + * on it's own process struct, not knowing which child will die 1.65 + * first. 1.66 + */ 1.67 + wakeup(get_process(p->parent)); 1.68 + return 0; 1.69 +} 1.70 + 1.71 +int sys_waitpid(int pid, int *status, int opt) 1.72 +{ 1.73 + struct process *p, *child; 1.74 + 1.75 + p = get_current_proc(); 1.76 + 1.77 +restart: 1.78 + if(pid <= 0) { 1.79 + /* search for zombie children */ 1.80 + child = p->child_list; 1.81 + while(child) { 1.82 + if(child->state == STATE_ZOMBIE) { 1.83 + break; 1.84 + } 1.85 + child = child->sib_next; 1.86 + } 1.87 + } else { 1.88 + if(!(child = get_process(pid)) || child->parent != p->id) { 1.89 + return -ECHILD; 1.90 + } 1.91 + if(child->state != STATE_ZOMBIE) { 1.92 + child = 0; 1.93 + } 1.94 + } 1.95 + 1.96 + /* found ? */ 1.97 + if(child) { 1.98 + int res; 1.99 + struct process *prev, dummy; 1.100 + 1.101 + if(status) { 1.102 + *status = child->exit_status; 1.103 + } 1.104 + res = child->id; 1.105 + 1.106 + /* remove it from our children list */ 1.107 + dummy.sib_next = p->child_list; 1.108 + prev = &dummy; 1.109 + while(prev->next) { 1.110 + if(prev->next == child) { 1.111 + prev->next = child->next; 1.112 + break; 1.113 + } 1.114 + } 1.115 + p->child_list = dummy.next; 1.116 + 1.117 + /* invalidate the id */ 1.118 + child->id = 0; 1.119 + return res; 1.120 + } 1.121 + 1.122 + /* not found, wait or sod off */ 1.123 + if(!(opt & WNOHANG)) { 1.124 + /* wait on our own process struct because 1.125 + * we have no way of knowing which child will 1.126 + * die first. 1.127 + * exit will wakeup the parent structure... 1.128 + */ 1.129 + wait(p); 1.130 + /* done waiting, restart waitpid */ 1.131 + goto restart; 1.132 + } 1.133 + 1.134 + return 0; /* he's not dead jim */ 1.135 +} 1.136 + 1.137 void context_switch(int pid) 1.138 { 1.139 static struct process *prev, *new; 1.140 @@ -262,5 +367,25 @@ 1.141 1.142 struct process *get_process(int pid) 1.143 { 1.144 - return &proc[pid]; 1.145 + struct process *p = proc + pid; 1.146 + if(p->id != pid) { 1.147 + printf("get_process called with invalid pid: %d\n", pid); 1.148 + return 0; 1.149 + } 1.150 + return p; 1.151 } 1.152 + 1.153 +int sys_getpid(void) 1.154 +{ 1.155 + return cur_pid; 1.156 +} 1.157 + 1.158 +int sys_getppid(void) 1.159 +{ 1.160 + struct process *p = get_current_proc(); 1.161 + 1.162 + if(!p) { 1.163 + return 0; 1.164 + } 1.165 + return p->parent; 1.166 +}