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

Linux/Unix编程

开发平台:

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 by Ralf Baechle
  7.  * Copyright (C) 2000 Silicon Graphics, Inc.
  8.  *
  9.  * TODO:  Implement the compatibility syscalls.
  10.  *        Don't waste that much memory for empty entries in the syscall
  11.  *        table.
  12.  */
  13. #undef CONF_PRINT_SYSCALLS
  14. #undef CONF_DEBUG_IRIX
  15. #include <linux/config.h>
  16. #include <linux/compiler.h>
  17. #include <linux/linkage.h>
  18. #include <linux/mm.h>
  19. #include <linux/smp.h>
  20. #include <linux/smp_lock.h>
  21. #include <linux/mman.h>
  22. #include <linux/sched.h>
  23. #include <linux/file.h>
  24. #include <linux/slab.h>
  25. #include <linux/utsname.h>
  26. #include <linux/unistd.h>
  27. #include <asm/branch.h>
  28. #include <asm/offset.h>
  29. #include <asm/ptrace.h>
  30. #include <asm/signal.h>
  31. #include <asm/shmparam.h>
  32. #include <asm/uaccess.h>
  33. extern asmlinkage void syscall_trace(void);
  34. typedef asmlinkage int (*syscall_t)(void *a0,...);
  35. extern asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun,
  36.      int narg);
  37. extern syscall_t sys_call_table[];
  38. extern unsigned char sys_narg_table[];
  39. asmlinkage int sys_pipe(struct pt_regs regs)
  40. {
  41. int fd[2];
  42. int error, res;
  43. error = do_pipe(fd);
  44. if (error) {
  45. res = error;
  46. goto out;
  47. }
  48. regs.regs[3] = fd[1];
  49. res = fd[0];
  50. out:
  51. return res;
  52. }
  53. #define COLOUR_ALIGN(addr,pgoff)
  54. ((((addr)+SHMLBA-1)&~(SHMLBA-1)) +
  55.  (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
  56. unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
  57. unsigned long len, unsigned long pgoff, unsigned long flags)
  58. {
  59. struct vm_area_struct * vmm;
  60. int do_color_align;
  61. if (flags & MAP_FIXED) {
  62. /*
  63.  * We do not accept a shared mapping if it would violate
  64.  * cache aliasing constraints.
  65.  */
  66. if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
  67. return -EINVAL;
  68. return addr;
  69. }
  70. if (len > TASK_SIZE)
  71. return -ENOMEM;
  72. do_color_align = 0;
  73. if (filp || (flags & MAP_SHARED))
  74. do_color_align = 1;
  75. if (addr) {
  76. if (do_color_align)
  77. addr = COLOUR_ALIGN(addr, pgoff);
  78. else
  79. addr = PAGE_ALIGN(addr);
  80. vmm = find_vma(current->mm, addr);
  81. if (TASK_SIZE - len >= addr &&
  82.     (!vmm || addr + len <= vmm->vm_start))
  83. return addr;
  84. }
  85. addr = TASK_UNMAPPED_BASE;
  86. if (do_color_align)
  87. addr = COLOUR_ALIGN(addr, pgoff);
  88. else
  89. addr = PAGE_ALIGN(addr);
  90. for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
  91. /* At this point:  (!vmm || addr < vmm->vm_end). */
  92. if (TASK_SIZE - len < addr)
  93. return -ENOMEM;
  94. if (!vmm || addr + len <= vmm->vm_start)
  95. return addr;
  96. addr = vmm->vm_end;
  97. if (do_color_align)
  98. addr = COLOUR_ALIGN(addr, pgoff);
  99. }
  100. }
  101. /* common code for old and new mmaps */
  102. static inline long
  103. do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
  104.         unsigned long flags, unsigned long fd, unsigned long pgoff)
  105. {
  106. int error = -EBADF;
  107. struct file * file = NULL;
  108. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  109. if (!(flags & MAP_ANONYMOUS)) {
  110. file = fget(fd);
  111. if (!file)
  112. goto out;
  113. }
  114. down_write(&current->mm->mmap_sem);
  115. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  116. up_write(&current->mm->mmap_sem);
  117. if (file)
  118. fput(file);
  119. out:
  120. return error;
  121. }
  122. asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
  123.                                   int flags, int fd, off_t offset)
  124. {
  125. int result;
  126. result = -EINVAL;
  127. if (offset & ~PAGE_MASK)
  128. goto out;
  129. result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  130. out:
  131. return result;
  132. }
  133. asmlinkage long
  134. sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
  135.           unsigned long flags, unsigned long fd, unsigned long pgoff)
  136. {
  137. return do_mmap2(addr, len, prot, flags, fd, pgoff);
  138. }
  139. save_static_function(sys_fork);
  140. static_unused int _sys_fork(struct pt_regs regs)
  141. {
  142. int res;
  143. res = do_fork(SIGCHLD, regs.regs[29], &regs, 0);
  144. return res;
  145. }
  146. save_static_function(sys_clone);
  147. static_unused int _sys_clone(struct pt_regs regs)
  148. {
  149. unsigned long clone_flags;
  150. unsigned long newsp;
  151. int res;
  152. clone_flags = regs.regs[4];
  153. newsp = regs.regs[5];
  154. if (!newsp)
  155. newsp = regs.regs[29];
  156. res = do_fork(clone_flags, newsp, &regs, 0);
  157. return res;
  158. }
  159. /*
  160.  * sys_execve() executes a new program.
  161.  */
  162. asmlinkage int sys_execve(struct pt_regs regs)
  163. {
  164. int error;
  165. char * filename;
  166. filename = getname((char *) (long)regs.regs[4]);
  167. error = PTR_ERR(filename);
  168. if (IS_ERR(filename))
  169. goto out;
  170. error = do_execve(filename, (char **) (long)regs.regs[5],
  171.                   (char **) (long)regs.regs[6], &regs);
  172. putname(filename);
  173. out:
  174. return error;
  175. }
  176. /*
  177.  * Compacrapability ...
  178.  */
  179. asmlinkage int sys_uname(struct old_utsname * name)
  180. {
  181. if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
  182. return 0;
  183. return -EFAULT;
  184. }
  185. /*
  186.  * Compacrapability ...
  187.  */
  188. asmlinkage int sys_olduname(struct oldold_utsname * name)
  189. {
  190. int error;
  191. if (!name)
  192. return -EFAULT;
  193. if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
  194. return -EFAULT;
  195. error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
  196. error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
  197. error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
  198. error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
  199. error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
  200. error -= __put_user(0,name->release+__OLD_UTS_LEN);
  201. error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
  202. error -= __put_user(0,name->version+__OLD_UTS_LEN);
  203. error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
  204. error = __put_user(0,name->machine+__OLD_UTS_LEN);
  205. error = error ? -EFAULT : 0;
  206. return error;
  207. }
  208. /*
  209.  * If we ever come here the user sp is bad.  Zap the process right away.
  210.  * Due to the bad stack signaling wouldn't work.
  211.  * XXX kernel locking???
  212.  */
  213. asmlinkage void bad_stack(void)
  214. {
  215. do_exit(SIGSEGV);
  216. }
  217. /*
  218.  * Build the string table for the builtin "poor man's strace".
  219.  */
  220. #ifdef CONF_PRINT_SYSCALLS
  221. #define SYS(fun, narg) #fun,
  222. static char *sfnames[] = {
  223. #include "syscalls.h"
  224. };
  225. #endif
  226. #if defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX)
  227. #define SYS(fun, narg) #fun,
  228. static char *irix_sys_names[] = {
  229. #include "irix5sys.h"
  230. };
  231. #endif