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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/x86_64/kernel/sys_x86_64.c
  3.  */
  4. #include <linux/errno.h>
  5. #include <linux/sched.h>
  6. #include <linux/mm.h>
  7. #include <linux/smp.h>
  8. #include <linux/smp_lock.h>
  9. #include <linux/sem.h>
  10. #include <linux/msg.h>
  11. #include <linux/shm.h>
  12. #include <linux/stat.h>
  13. #include <linux/mman.h>
  14. #include <linux/file.h>
  15. #include <linux/utsname.h>
  16. #include <linux/personality.h>
  17. #include <asm/uaccess.h>
  18. #include <asm/ipc.h>
  19. /*
  20.  * sys_pipe() is the normal C calling standard for creating
  21.  * a pipe. It's not the way Unix traditionally does this, though.
  22.  */
  23. asmlinkage long sys_pipe(unsigned long * fildes)
  24. {
  25. int fd[2];
  26. int error;
  27. error = do_pipe(fd);
  28. if (!error) {
  29. if (copy_to_user(fildes, fd, 2*sizeof(int)))
  30. error = -EFAULT;
  31. }
  32. return error;
  33. }
  34. long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
  35. unsigned long fd, unsigned long off)
  36. {
  37. long error;
  38. struct file * file;
  39. error = -EINVAL;
  40. if (off & ~PAGE_MASK)
  41. goto out;
  42. error = -EBADF;
  43. file = NULL;
  44. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  45. if (!(flags & MAP_ANONYMOUS)) {
  46. file = fget(fd);
  47. if (!file)
  48. goto out;
  49. }
  50. down_write(&current->mm->mmap_sem);
  51. error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
  52. up_write(&current->mm->mmap_sem);
  53. if (file)
  54. fput(file);
  55. out:
  56. return error;
  57. }
  58. unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
  59. {
  60. struct vm_area_struct *vma;
  61. unsigned long end = TASK_SIZE;
  62. if (current->thread.flags & THREAD_IA32)
  63. flags |= MAP_32BIT; 
  64. if (flags & MAP_32BIT)
  65. end = 0xffffffff-1;
  66. if (len > end)
  67. return -ENOMEM;
  68. if (!addr) { 
  69. addr = TASK_UNMAPPED_64;
  70. if (flags & MAP_32BIT) {
  71. addr = TASK_UNMAPPED_32;
  72. }
  73. addr = PAGE_ALIGN(addr);
  74. for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
  75. /* At this point:  (!vma || addr < vma->vm_end). */
  76. if (end - len < addr)
  77. return -ENOMEM;
  78. if (!vma || addr + len <= vma->vm_start)
  79. return addr;
  80. addr = vma->vm_end;
  81. }
  82. }
  83. asmlinkage long sys_uname(struct new_utsname * name)
  84. {
  85. int err;
  86. down_read(&uts_sem);
  87. err=copy_to_user(name, &system_utsname, sizeof (*name));
  88. up_read(&uts_sem);
  89. if (personality(current->personality) == PER_LINUX32)
  90. err = copy_to_user(name->machine, "i686", 5);
  91. return err?-EFAULT:0;
  92. }
  93. asmlinkage long sys_pause(void)
  94. {
  95. current->state = TASK_INTERRUPTIBLE;
  96. schedule();
  97. return -ERESTARTNOHAND;
  98. }
  99. asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
  100. {
  101. unsigned long raddr;
  102. return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr;