syscalls_32.c 1.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/* 
 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include "linux/sched.h"
#include "linux/shm.h"
A
Adrian Bunk 已提交
8
#include "linux/ipc.h"
A
Al Viro 已提交
9
#include "linux/syscalls.h"
L
Linus Torvalds 已提交
10 11 12 13
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"

14 15 16 17 18 19 20
/*
 * The prototype on i386 is:
 *
 *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
 *
 * and the "newtls" arg. on i386 is read by copy_thread directly from the
 * register saved on the stack.
L
Linus Torvalds 已提交
21 22
 */
long sys_clone(unsigned long clone_flags, unsigned long newsp,
23
	       int __user *parent_tid, void *newtls, int __user *child_tid)
L
Linus Torvalds 已提交
24 25 26
{
	long ret;

J
Jeff Dike 已提交
27 28
	if (!newsp)
		newsp = UPT_SP(&current->thread.regs.regs);
29

L
Linus Torvalds 已提交
30
	current->thread.forking = 1;
J
Jeff Dike 已提交
31 32
	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
		      child_tid);
L
Linus Torvalds 已提交
33
	current->thread.forking = 0;
34
	return ret;
L
Linus Torvalds 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
}

long sys_sigaction(int sig, const struct old_sigaction __user *act,
			 struct old_sigaction __user *oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;

	if (act) {
		old_sigset_t mask;
		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
			return -EFAULT;
		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
		__get_user(mask, &act->sa_mask);
		siginitset(&new_ka.sa.sa_mask, mask);
	}

	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

	if (!ret && oact) {
		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
			return -EFAULT;
		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
	}

	return ret;
}