sys_s390.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

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 int 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. int 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 for S/390 isn't able to handle more than 5
  68.  * 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 int old_mmap(struct mmap_arg_struct *arg)
  90. {
  91. struct mmap_arg_struct a;
  92. int 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. struct sel_arg_struct {
  104. unsigned long n;
  105. fd_set *inp, *outp, *exp;
  106. struct timeval *tvp;
  107. };
  108. asmlinkage int old_select(struct sel_arg_struct *arg)
  109. {
  110. struct sel_arg_struct a;
  111. if (copy_from_user(&a, arg, sizeof(a)))
  112. return -EFAULT;
  113. /* sys_select() does the appropriate kernel locking */
  114. return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
  115. }
  116. /*
  117.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  118.  *
  119.  * This is really horribly ugly.
  120.  */
  121. asmlinkage int sys_ipc (uint call, int first, int second, 
  122.                         int third, void *ptr)
  123. {
  124.         struct ipc_kludge tmp;
  125. int ret;
  126.         switch (call) {
  127.         case SEMOP:
  128.                 return sys_semop (first, (struct sembuf *)ptr, second);
  129.         case SEMGET:
  130.                 return sys_semget (first, second, third);
  131.         case SEMCTL: {
  132.                 union semun fourth;
  133.                 if (!ptr)
  134.                         return -EINVAL;
  135.                 if (get_user(fourth.__pad, (void **) ptr))
  136.                         return -EFAULT;
  137.                 return sys_semctl (first, second, third, fourth);
  138.         } 
  139.         case MSGSND:
  140. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  141.                                    second, third);
  142. break;
  143.         case MSGRCV:
  144.                 if (!ptr)
  145.                         return -EINVAL;
  146.                 if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
  147.                                     sizeof (struct ipc_kludge)))
  148.                         return -EFAULT;
  149.                 return sys_msgrcv (first, tmp.msgp,
  150.                                    second, tmp.msgtyp, third);
  151.         case MSGGET:
  152.                 return sys_msgget ((key_t) first, second);
  153.         case MSGCTL:
  154.                 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  155.                 
  156. case SHMAT: {
  157. ulong raddr;
  158. ret = sys_shmat (first, (char *) ptr, second, &raddr);
  159. if (ret)
  160. return ret;
  161. return put_user (raddr, (ulong *) third);
  162. break;
  163.         }
  164. case SHMDT: 
  165. return sys_shmdt ((char *)ptr);
  166. case SHMGET:
  167. return sys_shmget (first, second, third);
  168. case SHMCTL:
  169. return sys_shmctl (first, second,
  170.                                    (struct shmid_ds *) ptr);
  171. default:
  172. return -EINVAL;
  173. }
  174.         
  175. return -EINVAL;
  176. }
  177. /*
  178.  * Old cruft
  179.  */
  180. asmlinkage int sys_uname(struct old_utsname * name)
  181. {
  182. int err;
  183. if (!name)
  184. return -EFAULT;
  185. down_read(&uts_sem);
  186. err=copy_to_user(name, &system_utsname, sizeof (*name));
  187. up_read(&uts_sem);
  188. return err?-EFAULT:0;
  189. }
  190. asmlinkage int sys_olduname(struct oldold_utsname * name)
  191. {
  192. int error;
  193. if (!name)
  194. return -EFAULT;
  195. if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
  196. return -EFAULT;
  197.   
  198.    down_read(&uts_sem);
  199. error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
  200. error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
  201. error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
  202. error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
  203. error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
  204. error |= __put_user(0,name->release+__OLD_UTS_LEN);
  205. error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
  206. error |= __put_user(0,name->version+__OLD_UTS_LEN);
  207. error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
  208. error |= __put_user(0,name->machine+__OLD_UTS_LEN);
  209. up_read(&uts_sem);
  210. error = error ? -EFAULT : 0;
  211. return error;
  212. }
  213. asmlinkage int sys_pause(void)
  214. {
  215. set_current_state(TASK_INTERRUPTIBLE);
  216. schedule();
  217. return -ERESTARTNOHAND;
  218. }
  219. asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
  220. {
  221.   return -ENOSYS;
  222. }