syscalls.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
  3. * Licensed under the GPL
  4. */
  5. #include "linux/sched.h"
  6. #include "linux/shm.h"
  7. #include "asm/ipc.h"
  8. #include "asm/mman.h"
  9. #include "asm/uaccess.h"
  10. #include "asm/unistd.h"
  11. /*
  12. * Perform the select(nd, in, out, ex, tv) and mmap() system
  13. * calls. Linux/i386 didn't use to be able to handle more than
  14. * 4 system call parameters, so these system calls used a memory
  15. * block for parameter passing..
  16. */
  17. struct mmap_arg_struct {
  18. unsigned long addr;
  19. unsigned long len;
  20. unsigned long prot;
  21. unsigned long flags;
  22. unsigned long fd;
  23. unsigned long offset;
  24. };
  25. extern int old_mmap(unsigned long addr, unsigned long len,
  26. unsigned long prot, unsigned long flags,
  27. unsigned long fd, unsigned long offset);
  28. long old_mmap_i386(struct mmap_arg_struct __user *arg)
  29. {
  30. struct mmap_arg_struct a;
  31. int err = -EFAULT;
  32. if (copy_from_user(&a, arg, sizeof(a)))
  33. goto out;
  34. err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
  35. out:
  36. return err;
  37. }
  38. struct sel_arg_struct {
  39. unsigned long n;
  40. fd_set __user *inp;
  41. fd_set __user *outp;
  42. fd_set __user *exp;
  43. struct timeval __user *tvp;
  44. };
  45. long old_select(struct sel_arg_struct __user *arg)
  46. {
  47. struct sel_arg_struct a;
  48. if (copy_from_user(&a, arg, sizeof(a)))
  49. return -EFAULT;
  50. /* sys_select() does the appropriate kernel locking */
  51. return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
  52. }
  53. /* The i386 version skips reading from %esi, the fourth argument. So we must do
  54. * this, too.
  55. */
  56. long sys_clone(unsigned long clone_flags, unsigned long newsp,
  57. int __user *parent_tid, int unused, int __user *child_tid)
  58. {
  59. long ret;
  60. /* XXX: normal arch do here this pass, and also pass the regs to
  61. * do_fork, instead of NULL. Currently the arch-independent code
  62. * ignores these values, while the UML code (actually it's
  63. * copy_thread) does the right thing. But this should change,
  64. probably. */
  65. /*if (!newsp)
  66. newsp = UPT_SP(current->thread.regs);*/
  67. current->thread.forking = 1;
  68. ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
  69. current->thread.forking = 0;
  70. return(ret);
  71. }
  72. /*
  73. * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  74. *
  75. * This is really horribly ugly.
  76. */
  77. long sys_ipc (uint call, int first, int second,
  78. int third, void __user *ptr, long fifth)
  79. {
  80. int version, ret;
  81. version = call >> 16; /* hack for backward compatibility */
  82. call &= 0xffff;
  83. switch (call) {
  84. case SEMOP:
  85. return sys_semtimedop(first, (struct sembuf *) ptr, second,
  86. NULL);
  87. case SEMTIMEDOP:
  88. return sys_semtimedop(first, (struct sembuf *) ptr, second,
  89. (const struct timespec *) fifth);
  90. case SEMGET:
  91. return sys_semget (first, second, third);
  92. case SEMCTL: {
  93. union semun fourth;
  94. if (!ptr)
  95. return -EINVAL;
  96. if (get_user(fourth.__pad, (void **) ptr))
  97. return -EFAULT;
  98. return sys_semctl (first, second, third, fourth);
  99. }
  100. case MSGSND:
  101. return sys_msgsnd (first, (struct msgbuf *) ptr,
  102. second, third);
  103. case MSGRCV:
  104. switch (version) {
  105. case 0: {
  106. struct ipc_kludge tmp;
  107. if (!ptr)
  108. return -EINVAL;
  109. if (copy_from_user(&tmp,
  110. (struct ipc_kludge *) ptr,
  111. sizeof (tmp)))
  112. return -EFAULT;
  113. return sys_msgrcv (first, tmp.msgp, second,
  114. tmp.msgtyp, third);
  115. }
  116. default:
  117. panic("msgrcv with version != 0");
  118. return sys_msgrcv (first,
  119. (struct msgbuf *) ptr,
  120. second, fifth, third);
  121. }
  122. case MSGGET:
  123. return sys_msgget ((key_t) first, second);
  124. case MSGCTL:
  125. return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  126. case SHMAT:
  127. switch (version) {
  128. default: {
  129. ulong raddr;
  130. ret = do_shmat (first, (char *) ptr, second, &raddr);
  131. if (ret)
  132. return ret;
  133. return put_user (raddr, (ulong *) third);
  134. }
  135. case 1: /* iBCS2 emulator entry point */
  136. if (!segment_eq(get_fs(), get_ds()))
  137. return -EINVAL;
  138. return do_shmat (first, (char *) ptr, second, (ulong *) third);
  139. }
  140. case SHMDT:
  141. return sys_shmdt ((char *)ptr);
  142. case SHMGET:
  143. return sys_shmget (first, second, third);
  144. case SHMCTL:
  145. return sys_shmctl (first, second,
  146. (struct shmid_ds *) ptr);
  147. default:
  148. return -ENOSYS;
  149. }
  150. }
  151. long sys_sigaction(int sig, const struct old_sigaction __user *act,
  152. struct old_sigaction __user *oact)
  153. {
  154. struct k_sigaction new_ka, old_ka;
  155. int ret;
  156. if (act) {
  157. old_sigset_t mask;
  158. if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
  159. __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
  160. __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
  161. return -EFAULT;
  162. __get_user(new_ka.sa.sa_flags, &act->sa_flags);
  163. __get_user(mask, &act->sa_mask);
  164. siginitset(&new_ka.sa.sa_mask, mask);
  165. }
  166. ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  167. if (!ret && oact) {
  168. if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
  169. __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
  170. __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
  171. return -EFAULT;
  172. __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  173. __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  174. }
  175. return ret;
  176. }
  177. /*
  178. * Overrides for Emacs so that we follow Linus's tabbing style.
  179. * Emacs will notice this stuff at the end of the file and automatically
  180. * adjust the settings for this buffer only. This must remain at the end
  181. * of the file.
  182. * ---------------------------------------------------------------------------
  183. * Local variables:
  184. * c-file-style: "linux"
  185. * End:
  186. */