proc_syscalls.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <types.h>
  2. #include <kern/errno.h>
  3. #include <kern/unistd.h>
  4. #include <kern/wait.h>
  5. #include <mips/trapframe.h>
  6. #include <lib.h>
  7. #include <syscall.h>
  8. #include <current.h>
  9. #include <proc.h>
  10. #include <thread.h>
  11. #include <addrspace.h>
  12. #include <copyinout.h>
  13. #include <synch.h>
  14. /* this implementation of sys__exit does not do anything with the exit code */
  15. /* this needs to be fixed to get exit() and waitpid() working properly */
  16. void sys__exit(int exitcode)
  17. {
  18. struct addrspace * as;
  19. struct proc * p = curproc;
  20. /* for now, just include this to keep the compiler from complaining about
  21. an unused variable */
  22. (void)exitcode;
  23. DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode);
  24. KASSERT(curproc->p_addrspace != NULL);
  25. as_deactivate();
  26. /*
  27. * clear p_addrspace before calling as_destroy. Otherwise if
  28. * as_destroy sleeps (which is quite possible) when we
  29. * come back we'll be calling as_activate on a
  30. * half-destroyed address space. This tends to be
  31. * messily fatal.
  32. */
  33. as = curproc_setas(NULL);
  34. as_destroy(as);
  35. /* detach this thread from its process */
  36. /* note: curproc cannot be used after this call */
  37. proc_remthread(curthread);
  38. /* if this is the last user process in the system, proc_destroy()
  39. will wake up the kernel menu thread */
  40. proc_destroy(p);
  41. thread_exit();
  42. /* thread_exit() does not return, so we should never get here */
  43. panic("return from thread_exit in sys_exit\n");
  44. }
  45. // basically, return an error code, and put the actual result in retval
  46. int sys_getpid(pid_t * retval)
  47. {
  48. if (!(curproc)) return 1;
  49. *retval = curproc->pid;
  50. return(0);
  51. }
  52. /* stub handler for waitpid() system call */
  53. int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval)
  54. {
  55. int exitstatus;
  56. int result;
  57. /* this is just a stub implementation that always reports an
  58. exit status of 0, regardless of the actual exit status of
  59. the specified process.
  60. In fact, this will return 0 even if the specified process
  61. is still running, and even if #include <kern/wait.h>it never existed in the first place.
  62. Fix this!
  63. */
  64. if (options != 0)
  65. {
  66. return(EINVAL);
  67. }
  68. /* for now, just pretend the exitstatus is 0 */
  69. exitstatus = 0;
  70. result = copyout((void *)&exitstatus,status,sizeof(int));
  71. if (result)
  72. {
  73. return(result);
  74. }
  75. *retval = pid;
  76. return(0);
  77. }
  78. int sys_fork(struct trapframe * tf, int * retval)
  79. {
  80. // create new process' memory space
  81. struct proc * child = proc_create_runprogram("childproc");
  82. struct addrspace * new_as;
  83. struct trapframe * new_tf = kmalloc(sizeof(*tf));
  84. if ((!child)) return ENOMEM;
  85. as_copy(curproc_getas(), &new_as);
  86. if (!(new_as) || !(new_tf))
  87. {
  88. proc_destroy(child);
  89. kfree(new_as);
  90. kfree(new_tf);
  91. return ENOMEM;
  92. }
  93. // set PIDs, etc. copy data in to the new space
  94. child->p_addrspace = new_as;
  95. child->parent = curproc;
  96. add_child(curproc, child->pid);
  97. *new_tf = *tf;
  98. // start new thread
  99. thread_fork("childproc", child, enter_forked_process, new_tf, 0);
  100. // return correct values
  101. if (curproc->pid == child->pid) *retval = 0;
  102. else *retval = child->pid;
  103. return 0;
  104. }