sys_s390.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/s390/kernel/sys_s390.c
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  7.  *
  8.  *  Derived from "arch/i386/kernel/sys_i386.c"
  9.  *
  10.  *  This file contains various random system calls that
  11.  *  have a non-standard calling sequence on the Linux/s390
  12.  *  platform.
  13.  */
  14. #include <linux/errno.h>
  15. #include <linux/sched.h>
  16. #include <linux/mm.h>
  17. #include <linux/smp.h>
  18. #include <linux/smp_lock.h>
  19. #include <linux/sem.h>
  20. #include <linux/msg.h>
  21. #include <linux/shm.h>
  22. #include <linux/stat.h>
  23. #include <linux/mman.h>
  24. #include <linux/file.h>
  25. #include <linux/utsname.h>
  26. #include <asm/uaccess.h>
  27. #include <asm/ipc.h>
  28. /*
  29.  * sys_pipe() is the normal C calling standard for creating
  30.  * a pipe. It's not the way Unix traditionally does this, though.
  31.  */
  32. asmlinkage long sys_pipe(unsigned long * fildes)
  33. {
  34. int fd[2];
  35. int error;
  36. error = do_pipe(fd);
  37. if (!error) {
  38. if (copy_to_user(fildes, fd, 2*sizeof(int)))
  39. error = -EFAULT;
  40. }
  41. return error;
  42. }
  43. /* common code for old and new mmaps */
  44. static inline long do_mmap2(
  45. unsigned long addr, unsigned long len,
  46. unsigned long prot, unsigned long flags,
  47. unsigned long fd, unsigned long pgoff)
  48. {
  49. long error = -EBADF;
  50. struct file * file = NULL;
  51. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  52. if (!(flags & MAP_ANONYMOUS)) {
  53. file = fget(fd);
  54. if (!file)
  55. goto out;
  56. }
  57. down_write(&current->mm->mmap_sem);
  58. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  59. up_write(&current->mm->mmap_sem);
  60. if (file)
  61. fput(file);
  62. out:
  63. return error;
  64. }
  65. /*
  66.  * Perform the select(nd, in, out, ex, tv) and mmap() system
  67.  * calls. Linux/i386 didn't use to be able to handle more than
  68.  * 4 system call parameters, so these system calls used a memory
  69.  * block for parameter passing..
  70.  */
  71. struct mmap_arg_struct {
  72. unsigned long addr;
  73. unsigned long len;
  74. unsigned long prot;
  75. unsigned long flags;
  76. unsigned long fd;
  77. unsigned long offset;
  78. };
  79. asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
  80. {
  81. struct mmap_arg_struct a;
  82. int error = -EFAULT;
  83. if (copy_from_user(&a, arg, sizeof(a)))
  84. goto out;
  85. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
  86. out:
  87. return error;
  88. }
  89. asmlinkage long old_mmap(struct mmap_arg_struct *arg)
  90. {
  91. struct mmap_arg_struct a;
  92. long error = -EFAULT;
  93. if (copy_from_user(&a, arg, sizeof(a)))
  94. goto out;
  95. error = -EINVAL;
  96. if (a.offset & ~PAGE_MASK)
  97. goto out;
  98. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
  99. out:
  100. return error;
  101. }
  102. extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
  103. /*
  104.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  105.  *
  106.  * This is really horribly ugly.
  107.  */
  108. asmlinkage int sys_ipc (uint call, int first, long second, 
  109.                         unsigned long third, void *ptr)
  110. {
  111.         struct ipc_kludge tmp;
  112. int ret;
  113.         switch (call) {
  114.         case SEMOP:
  115.                 return sys_semop (first, (struct sembuf *)ptr, second);
  116.         case SEMGET:
  117.                 return sys_semget (first, second, third);
  118.         case SEMCTL: {
  119.                 union semun fourth;
  120.                 if (!ptr)
  121.                         return -EINVAL;
  122.                 if (get_user(fourth.__pad, (void **) ptr))
  123.                         return -EFAULT;
  124.                 return sys_semctl (first, second, third, fourth);
  125.         } 
  126.         case MSGSND:
  127. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  128.                                    second, third);
  129. break;
  130.         case MSGRCV:
  131.                 if (!ptr)
  132.                         return -EINVAL;
  133.                 if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
  134.                                     sizeof (struct ipc_kludge)))
  135.                         return -EFAULT;
  136.                 return sys_msgrcv (first, tmp.msgp,
  137.                                    second, tmp.msgtyp, third);
  138.         case MSGGET:
  139.                 return sys_msgget ((key_t) first, second);
  140.         case MSGCTL:
  141.                 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  142.                 
  143. case SHMAT: {
  144. ulong raddr;
  145. ret = sys_shmat (first, (char *) ptr, second, &raddr);
  146. if (ret)
  147. return ret;
  148. return put_user (raddr, (ulong *) third);
  149. break;
  150.         }
  151. case SHMDT: 
  152. return sys_shmdt ((char *)ptr);
  153. case SHMGET:
  154. return sys_shmget (first, second, third);
  155. case SHMCTL:
  156. return sys_shmctl (first, second,
  157.                                    (struct shmid_ds *) ptr);
  158. default:
  159. return -EINVAL;
  160. }
  161.         
  162. return -EINVAL;
  163. }
  164. /*
  165.  * Old cruft
  166.  */
  167. asmlinkage int sys_uname(struct old_utsname * name)
  168. {
  169. int err;
  170. if (!name)
  171. return -EFAULT;
  172. down_read(&uts_sem);
  173. err=copy_to_user(name, &system_utsname, sizeof (*name));
  174. up_read(&uts_sem);
  175. return err?-EFAULT:0;
  176. }
  177. asmlinkage int sys_pause(void)
  178. {
  179. set_current_state(TASK_INTERRUPTIBLE);
  180. schedule();
  181. return -ERESTARTNOHAND;
  182. }