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