#include #include #include #include #include #include #include #include #include #include #include /* this implementation of sys__exit does not do anything with the exit code */ /* this needs to be fixed to get exit() and waitpid() working properly */ void sys__exit(int exitcode) { struct addrspace * as; struct proc * p = curproc; /* for now, just include this to keep the compiler from complaining about an unused variable */ (void)exitcode; DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode); KASSERT(curproc->p_addrspace != NULL); as_deactivate(); /* * clear p_addrspace before calling as_destroy. Otherwise if * as_destroy sleeps (which is quite possible) when we * come back we'll be calling as_activate on a * half-destroyed address space. This tends to be * messily fatal. */ as = curproc_setas(NULL); as_destroy(as); /* detach this thread from its process */ /* note: curproc cannot be used after this call */ proc_remthread(curthread); /* if this is the last user process in the system, proc_destroy() will wake up the kernel menu thread */ proc_destroy(p); thread_exit(); /* thread_exit() does not return, so we should never get here */ panic("return from thread_exit in sys_exit\n"); } // basically, return an error code, and put the actual result in retval int sys_getpid(pid_t * retval) { if (!(curproc)) return 1; *retval = curproc->pid; return(0); } /* stub handler for waitpid() system call */ int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval) { int exitstatus; int result; /* this is just a stub implementation that always reports an exit status of 0, regardless of the actual exit status of the specified process. In fact, this will return 0 even if the specified process is still running, and even if it never existed in the first place. Fix this! */ if (options != 0) { return(EINVAL); } /* for now, just pretend the exitstatus is 0 */ exitstatus = 0; result = copyout((void *)&exitstatus,status,sizeof(int)); if (result) { return(result); } *retval = pid; return(0); } int sys_fork(struct trapframe * tf, int * retval) { // create new process' memory space struct proc * child = proc_create_runprogram("childproc"); struct addrspace * new_as; struct trapframe * new_tf = kmalloc(sizeof(*tf)); if ((!child) return ENOMEM; as_copy(curproc_getas(), &childAddrspace); if (!(new_as) || !(new_tf)) { proc_destroy(child); kfree(new_as); kfree(new_tf); return ENOMEM; } // might want to handle inserting PID into overall struct here. perhaps a setpid function or something in proc_create_runprogram... // set PIDs, etc. copy data in to the new space child->p_addrspace = new_as; child->parent = curproc; *new_tf = *tf; // start new thread thread_fork("childproc", child, enter_forked_process, new_tf, 0); // return correct values if (curproc->pid == child->pid) *retval = 0; else *retval = child->pid; return 0; }