syscall.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  3. * Licensed under the GPL
  4. */
  5. #include "linux/file.h"
  6. #include "linux/fs.h"
  7. #include "linux/mm.h"
  8. #include "linux/sched.h"
  9. #include "linux/utsname.h"
  10. #include "asm/current.h"
  11. #include "asm/mman.h"
  12. #include "asm/uaccess.h"
  13. #include "asm/unistd.h"
  14. #include "internal.h"
  15. long sys_fork(void)
  16. {
  17. long ret;
  18. current->thread.forking = 1;
  19. ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
  20. &current->thread.regs, 0, NULL, NULL);
  21. current->thread.forking = 0;
  22. return ret;
  23. }
  24. long sys_vfork(void)
  25. {
  26. long ret;
  27. current->thread.forking = 1;
  28. ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
  29. UPT_SP(&current->thread.regs.regs),
  30. &current->thread.regs, 0, NULL, NULL);
  31. current->thread.forking = 0;
  32. return ret;
  33. }
  34. /* common code for old and new mmaps */
  35. long sys_mmap2(unsigned long addr, unsigned long len,
  36. unsigned long prot, unsigned long flags,
  37. unsigned long fd, unsigned long pgoff)
  38. {
  39. long error = -EBADF;
  40. struct file * file = NULL;
  41. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  42. if (!(flags & MAP_ANONYMOUS)) {
  43. file = fget(fd);
  44. if (!file)
  45. goto out;
  46. }
  47. down_write(&current->mm->mmap_sem);
  48. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  49. up_write(&current->mm->mmap_sem);
  50. if (file)
  51. fput(file);
  52. out:
  53. return error;
  54. }
  55. long old_mmap(unsigned long addr, unsigned long len,
  56. unsigned long prot, unsigned long flags,
  57. unsigned long fd, unsigned long offset)
  58. {
  59. long err = -EINVAL;
  60. if (offset & ~PAGE_MASK)
  61. goto out;
  62. err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  63. out:
  64. return err;
  65. }
  66. long sys_uname(struct old_utsname __user * name)
  67. {
  68. long err;
  69. if (!name)
  70. return -EFAULT;
  71. down_read(&uts_sem);
  72. err = copy_to_user(name, utsname(), sizeof (*name));
  73. up_read(&uts_sem);
  74. return err?-EFAULT:0;
  75. }
  76. long sys_olduname(struct oldold_utsname __user * name)
  77. {
  78. long error;
  79. if (!name)
  80. return -EFAULT;
  81. if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
  82. return -EFAULT;
  83. down_read(&uts_sem);
  84. error = __copy_to_user(&name->sysname, &utsname()->sysname,
  85. __OLD_UTS_LEN);
  86. error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
  87. error |= __copy_to_user(&name->nodename, &utsname()->nodename,
  88. __OLD_UTS_LEN);
  89. error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
  90. error |= __copy_to_user(&name->release, &utsname()->release,
  91. __OLD_UTS_LEN);
  92. error |= __put_user(0, name->release + __OLD_UTS_LEN);
  93. error |= __copy_to_user(&name->version, &utsname()->version,
  94. __OLD_UTS_LEN);
  95. error |= __put_user(0, name->version + __OLD_UTS_LEN);
  96. error |= __copy_to_user(&name->machine, &utsname()->machine,
  97. __OLD_UTS_LEN);
  98. error |= __put_user(0, name->machine + __OLD_UTS_LEN);
  99. up_read(&uts_sem);
  100. error = error ? -EFAULT : 0;
  101. return error;
  102. }
  103. int kernel_execve(const char *filename, char *const argv[], char *const envp[])
  104. {
  105. mm_segment_t fs;
  106. int ret;
  107. fs = get_fs();
  108. set_fs(KERNEL_DS);
  109. ret = um_execve((char *)filename, (char __user *__user *)argv,
  110. (char __user *__user *) envp);
  111. set_fs(fs);
  112. return ret;
  113. }