syscalls.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * arch/v850/kernel/syscalls.c -- Various system-call definitions not
  3. * defined in machine-independent code
  4. *
  5. * Copyright (C) 2001,02 NEC Corporation
  6. * Copyright (C) 2001,02 Miles Bader <miles@gnu.org>
  7. *
  8. * This file is subject to the terms and conditions of the GNU General
  9. * Public License. See the file COPYING in the main directory of this
  10. * archive for more details.
  11. *
  12. * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
  13. * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
  14. * modified by Cort Dougan (cort@cs.nmt.edu)
  15. * and Paul Mackerras (paulus@cs.anu.edu.au).
  16. */
  17. #include <linux/config.h>
  18. #include <linux/errno.h>
  19. #include <linux/mm.h>
  20. #include <linux/smp.h>
  21. #include <linux/smp_lock.h>
  22. #include <linux/syscalls.h>
  23. #include <linux/sem.h>
  24. #include <linux/msg.h>
  25. #include <linux/shm.h>
  26. #include <linux/stat.h>
  27. #include <linux/mman.h>
  28. #include <linux/sys.h>
  29. #include <linux/ipc.h>
  30. #include <linux/utsname.h>
  31. #include <linux/file.h>
  32. #include <asm/uaccess.h>
  33. #include <asm/ipc.h>
  34. #include <asm/semaphore.h>
  35. /*
  36. * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  37. *
  38. * This is really horribly ugly.
  39. */
  40. int
  41. sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
  42. {
  43. int version, ret;
  44. version = call >> 16; /* hack for backward compatibility */
  45. call &= 0xffff;
  46. ret = -EINVAL;
  47. switch (call) {
  48. case SEMOP:
  49. ret = sys_semop (first, (struct sembuf *)ptr, second);
  50. break;
  51. case SEMGET:
  52. ret = sys_semget (first, second, third);
  53. break;
  54. case SEMCTL:
  55. {
  56. union semun fourth;
  57. if (!ptr)
  58. break;
  59. if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
  60. || (ret = get_user(fourth.__pad, (void **)ptr)))
  61. break;
  62. ret = sys_semctl (first, second, third, fourth);
  63. break;
  64. }
  65. case MSGSND:
  66. ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
  67. break;
  68. case MSGRCV:
  69. switch (version) {
  70. case 0: {
  71. struct ipc_kludge tmp;
  72. if (!ptr)
  73. break;
  74. if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
  75. || (ret = copy_from_user(&tmp,
  76. (struct ipc_kludge *) ptr,
  77. sizeof (tmp))))
  78. break;
  79. ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
  80. third);
  81. break;
  82. }
  83. default:
  84. ret = sys_msgrcv (first, (struct msgbuf *) ptr,
  85. second, fifth, third);
  86. break;
  87. }
  88. break;
  89. case MSGGET:
  90. ret = sys_msgget ((key_t) first, second);
  91. break;
  92. case MSGCTL:
  93. ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
  94. break;
  95. case SHMAT:
  96. switch (version) {
  97. default: {
  98. ulong raddr;
  99. if ((ret = access_ok(VERIFY_WRITE, (ulong*) third,
  100. sizeof(ulong)) ? 0 : -EFAULT))
  101. break;
  102. ret = do_shmat (first, (char *) ptr, second, &raddr);
  103. if (ret)
  104. break;
  105. ret = put_user (raddr, (ulong *) third);
  106. break;
  107. }
  108. case 1: /* iBCS2 emulator entry point */
  109. if (!segment_eq(get_fs(), get_ds()))
  110. break;
  111. ret = do_shmat (first, (char *) ptr, second,
  112. (ulong *) third);
  113. break;
  114. }
  115. break;
  116. case SHMDT:
  117. ret = sys_shmdt ((char *)ptr);
  118. break;
  119. case SHMGET:
  120. ret = sys_shmget (first, second, third);
  121. break;
  122. case SHMCTL:
  123. ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
  124. break;
  125. }
  126. return ret;
  127. }
  128. /*
  129. * sys_pipe() is the normal C calling standard for creating
  130. * a pipe. It's not the way unix traditionally does this, though.
  131. */
  132. int sys_pipe (int *fildes)
  133. {
  134. int fd[2];
  135. int error;
  136. error = do_pipe (fd);
  137. if (!error) {
  138. if (copy_to_user (fildes, fd, 2*sizeof (int)))
  139. error = -EFAULT;
  140. }
  141. return error;
  142. }
  143. static inline unsigned long
  144. do_mmap2 (unsigned long addr, size_t len,
  145. unsigned long prot, unsigned long flags,
  146. unsigned long fd, unsigned long pgoff)
  147. {
  148. struct file * file = NULL;
  149. int ret = -EBADF;
  150. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  151. if (! (flags & MAP_ANONYMOUS)) {
  152. if (!(file = fget (fd)))
  153. goto out;
  154. }
  155. down_write (&current->mm->mmap_sem);
  156. ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
  157. up_write (&current->mm->mmap_sem);
  158. if (file)
  159. fput (file);
  160. out:
  161. return ret;
  162. }
  163. unsigned long sys_mmap2 (unsigned long addr, size_t len,
  164. unsigned long prot, unsigned long flags,
  165. unsigned long fd, unsigned long pgoff)
  166. {
  167. return do_mmap2 (addr, len, prot, flags, fd, pgoff);
  168. }
  169. unsigned long sys_mmap (unsigned long addr, size_t len,
  170. unsigned long prot, unsigned long flags,
  171. unsigned long fd, off_t offset)
  172. {
  173. int err = -EINVAL;
  174. if (offset & ~PAGE_MASK)
  175. goto out;
  176. err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  177. out:
  178. return err;
  179. }