79 строки
2.0 KiB
C
79 строки
2.0 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
* Copyright (C) 1994 - 2000, 2006 Ralf Baechle
|
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
|
* Copyright (C) 2016, Imagination Technologies Ltd.
|
|
*/
|
|
#include <linux/compat.h>
|
|
#include <linux/compiler.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/syscalls.h>
|
|
|
|
#include <asm/compat-signal.h>
|
|
#include <linux/uaccess.h>
|
|
#include <asm/unistd.h>
|
|
|
|
#include "signal-common.h"
|
|
|
|
/* 32-bit compatibility types */
|
|
|
|
typedef unsigned int __sighandler32_t;
|
|
typedef void (*vfptr_t)(void);
|
|
|
|
/*
|
|
* Atomically swap in the new signal mask, and wait for a signal.
|
|
*/
|
|
|
|
asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
|
|
{
|
|
return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
|
|
}
|
|
|
|
SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
|
|
struct compat_sigaction __user *, oact)
|
|
{
|
|
struct k_sigaction new_ka, old_ka;
|
|
int ret;
|
|
int err = 0;
|
|
|
|
if (act) {
|
|
old_sigset_t mask;
|
|
s32 handler;
|
|
|
|
if (!access_ok(act, sizeof(*act)))
|
|
return -EFAULT;
|
|
err |= __get_user(handler, &act->sa_handler);
|
|
new_ka.sa.sa_handler = (void __user *)(s64)handler;
|
|
err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
|
|
err |= __get_user(mask, &act->sa_mask.sig[0]);
|
|
if (err)
|
|
return -EFAULT;
|
|
|
|
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(oact, sizeof(*oact)))
|
|
return -EFAULT;
|
|
err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
|
|
err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
|
|
&oact->sa_handler);
|
|
err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
|
|
err |= __put_user(0, &oact->sa_mask.sig[1]);
|
|
err |= __put_user(0, &oact->sa_mask.sig[2]);
|
|
err |= __put_user(0, &oact->sa_mask.sig[3]);
|
|
if (err)
|
|
return -EFAULT;
|
|
}
|
|
|
|
return ret;
|
|
}
|