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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
  7.  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8.  * Copyright (C) 2001 MIPS Technologies, Inc.
  9.  */
  10. #include <linux/errno.h>
  11. #include <linux/linkage.h>
  12. #include <linux/mm.h>
  13. #include <linux/smp.h>
  14. #include <linux/smp_lock.h>
  15. #include <linux/mman.h>
  16. #include <linux/sched.h>
  17. #include <linux/string.h>
  18. #include <linux/file.h>
  19. #include <linux/utsname.h>
  20. #include <linux/unistd.h>
  21. #include <linux/sem.h>
  22. #include <linux/msg.h>
  23. #include <linux/shm.h>
  24. #include <linux/slab.h>
  25. #include <asm/ipc.h>
  26. #include <asm/cachectl.h>
  27. #include <asm/offset.h>
  28. #include <asm/pgalloc.h>
  29. #include <asm/ptrace.h>
  30. #include <asm/signal.h>
  31. #include <asm/stackframe.h>
  32. #include <asm/sysmips.h>
  33. #include <asm/uaccess.h>
  34. extern asmlinkage void syscall_trace(void);
  35. asmlinkage int sys_pipe(abi64_no_regargs, struct pt_regs regs)
  36. {
  37. int fd[2];
  38. int error, res;
  39. error = do_pipe(fd);
  40. if (error) {
  41. res = error;
  42. goto out;
  43. }
  44. regs.regs[3] = fd[1];
  45. res = fd[0];
  46. out:
  47. return res;
  48. }
  49. asmlinkage unsigned long
  50. sys_mmap(unsigned long addr, size_t len, unsigned long prot,
  51.          unsigned long flags, unsigned long fd, off_t offset)
  52. {
  53. struct file * file = NULL;
  54. unsigned long error = -EFAULT;
  55. if (!(flags & MAP_ANONYMOUS)) {
  56. error = -EBADF;
  57. file = fget(fd);
  58. if (!file)
  59. goto out;
  60. }
  61.         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  62. down_write(&current->mm->mmap_sem);
  63.         error = do_mmap(file, addr, len, prot, flags, offset);
  64. up_write(&current->mm->mmap_sem);
  65.         if (file)
  66.                 fput(file);
  67. out:
  68. return error;
  69. }
  70. asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs)
  71. {
  72. int res;
  73. save_static(&regs);
  74. res = do_fork(SIGCHLD, regs.regs[29], &regs, 0);
  75. return res;
  76. }
  77. asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs)
  78. {
  79. unsigned long clone_flags;
  80. unsigned long newsp;
  81. int res;
  82. save_static(&regs);
  83. clone_flags = regs.regs[4];
  84. newsp = regs.regs[5];
  85. if (!newsp)
  86. newsp = regs.regs[29];
  87. res = do_fork(clone_flags, newsp, &regs, 0);
  88. return res;
  89. }
  90. /*
  91.  * sys_execve() executes a new program.
  92.  */
  93. asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs)
  94. {
  95. int error;
  96. char * filename;
  97. filename = getname((char *) (long)regs.regs[4]);
  98. error = PTR_ERR(filename);
  99. if (IS_ERR(filename))
  100. goto out;
  101. error = do_execve(filename, (char **) (long)regs.regs[5],
  102.                   (char **) (long)regs.regs[6], &regs);
  103. putname(filename);
  104. out:
  105. return error;
  106. }
  107. /*
  108.  * Do the indirect syscall syscall.
  109.  *
  110.  * XXX This is borken.
  111.  */
  112. asmlinkage int sys_syscall(abi64_no_regargs, struct pt_regs regs)
  113. {
  114. return -ENOSYS;
  115. }
  116. asmlinkage int
  117. _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
  118. {
  119. int *p;
  120. char *name;
  121. int tmp, len, errno;
  122. switch(cmd) {
  123. case SETNAME: {
  124. char nodename[__NEW_UTS_LEN + 1];
  125. if (!capable(CAP_SYS_ADMIN))
  126. return -EPERM;
  127. name = (char *) arg1;
  128. len = strncpy_from_user(nodename, name, sizeof(nodename));
  129. if (len < 0)
  130. return -EFAULT;
  131. down_write(&uts_sem);
  132. strncpy(system_utsname.nodename, name, len);
  133. up_write(&uts_sem);
  134. system_utsname.nodename[len] = '';
  135. return 0;
  136. }
  137. case MIPS_ATOMIC_SET:
  138. printk(KERN_CRIT "How did I get here?n");
  139. return -EINVAL;
  140. case MIPS_FIXADE:
  141. tmp = current->thread.mflags & ~3;
  142. current->thread.mflags = tmp | (arg1 & 3);
  143. return 0;
  144. case FLUSH_CACHE:
  145. _flush_cache_l2();
  146. return 0;
  147. case MIPS_RDNVRAM:
  148. return -EIO;
  149. }
  150. return -EINVAL;
  151. }
  152. /*
  153.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  154.  *
  155.  * This is really horribly ugly.
  156.  */
  157. asmlinkage int sys_ipc (uint call, int first, int second,
  158. unsigned long third, void *ptr, long fifth)
  159. {
  160. int version, ret;
  161. version = call >> 16; /* hack for backward compatibility */
  162. call &= 0xffff;
  163. switch (call) {
  164. case SEMOP:
  165. return sys_semop (first, (struct sembuf *)ptr, second);
  166. case SEMGET:
  167. return sys_semget (first, second, third);
  168. case SEMCTL: {
  169. union semun fourth;
  170. if (!ptr)
  171. return -EINVAL;
  172. if (get_user(fourth.__pad, (void **) ptr))
  173. return -EFAULT;
  174. return sys_semctl (first, second, third, fourth);
  175. }
  176. case MSGSND:
  177. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  178.    second, third);
  179. case MSGRCV:
  180. switch (version) {
  181. case 0: {
  182. struct ipc_kludge tmp;
  183. if (!ptr)
  184. return -EINVAL;
  185. if (copy_from_user(&tmp,
  186.    (struct ipc_kludge *) ptr, 
  187.    sizeof (tmp)))
  188. return -EFAULT;
  189. return sys_msgrcv (first, tmp.msgp, second,
  190.    tmp.msgtyp, third);
  191. }
  192. default:
  193. return sys_msgrcv (first,
  194.    (struct msgbuf *) ptr,
  195.    second, fifth, third);
  196. }
  197. case MSGGET:
  198. return sys_msgget ((key_t) first, second);
  199. case MSGCTL:
  200. return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  201. case SHMAT:
  202. switch (version) {
  203. default: {
  204. ulong raddr;
  205. ret = sys_shmat (first, (char *) ptr, second, &raddr);
  206. if (ret)
  207. return ret;
  208. return put_user (raddr, (ulong *) third);
  209. }
  210. case 1: /* iBCS2 emulator entry point */
  211. if (!segment_eq(get_fs(), get_ds()))
  212. return -EINVAL;
  213. return sys_shmat (first, (char *) ptr, second, (ulong *) third);
  214. }
  215. case SHMDT: 
  216. return sys_shmdt ((char *)ptr);
  217. case SHMGET:
  218. return sys_shmget (first, second, third);
  219. case SHMCTL:
  220. return sys_shmctl (first, second,
  221.    (struct shmid_ds *) ptr);
  222. default:
  223. return -EINVAL;
  224. }
  225. }
  226. /*
  227.  * No implemented yet ...
  228.  */
  229. asmlinkage int
  230. sys_cachectl(char *addr, int nbytes, int op)
  231. {
  232. return -ENOSYS;
  233. }
  234. /*
  235.  * If we ever come here the user sp is bad.  Zap the process right away.
  236.  * Due to the bad stack signaling wouldn't work.
  237.  */
  238. asmlinkage void bad_stack(void)
  239. {
  240. do_exit(SIGSEGV);
  241. }
  242. asmlinkage int sys_pause(void)
  243. {
  244. current->state = TASK_INTERRUPTIBLE;
  245. schedule();
  246. return -ERESTARTNOHAND;
  247. }