patch-2.1.23 linux/kernel/signal.c
Next file: linux/kernel/softirq.c
Previous file: linux/kernel/sched.c
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Sun Jan 26 12:07:49 1997
- Orig file:
v2.1.22/linux/kernel/signal.c
- Orig date:
Tue Nov 19 15:53:59 1996
diff -u --recursive --new-file v2.1.22/linux/kernel/signal.c linux/kernel/signal.c
@@ -12,6 +12,8 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -31,10 +33,11 @@
sigset_t new_set, old_set = current->blocked;
int error;
+ lock_kernel();
if (set) {
error = get_user(new_set, set);
if (error)
- return error;
+ goto out;
new_set &= _BLOCKABLE;
switch (how) {
case SIG_BLOCK:
@@ -47,15 +50,19 @@
current->blocked = new_set;
break;
default:
- return -EINVAL;
+ error = -EINVAL;
+ goto out;
}
}
if (oset) {
error = put_user(old_set, oset);
if (error)
- return error;
+ goto out;
}
- return 0;
+ error = 0;
+out:
+ unlock_kernel();
+ return error;
}
/*
@@ -63,14 +70,22 @@
*/
asmlinkage int sys_sgetmask(void)
{
- return current->blocked;
+ int ret;
+
+ lock_kernel();
+ ret = current->blocked;
+ unlock_kernel();
+ return ret;
}
asmlinkage int sys_ssetmask(int newmask)
{
- int old=current->blocked;
+ int old;
+ lock_kernel();
+ old = current->blocked;
current->blocked = newmask & _BLOCKABLE;
+ unlock_kernel();
return old;
}
@@ -78,8 +93,13 @@
asmlinkage int sys_sigpending(sigset_t *set)
{
+ int ret;
+
/* fill in "set" with signals pending but blocked. */
- return put_user(current->blocked & current->signal, set);
+ lock_kernel();
+ ret = put_user(current->blocked & current->signal, set);
+ unlock_kernel();
+ return ret;
}
/*
@@ -97,7 +117,7 @@
* isn't actually ignored, but does automatic child reaping, while
* SIG_DFL is explicitly said by POSIX to force the signal to be ignored..
*/
-static inline void check_pending(int signum)
+inline void check_pending(int signum)
{
struct sigaction *p;
@@ -120,17 +140,19 @@
*/
asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
{
- int err;
+ unsigned long err;
struct sigaction tmp;
+ lock_kernel();
+ err = -EINVAL;
if (signum<1 || signum>32)
- return -EINVAL;
+ goto out;
if (signum==SIGKILL || signum==SIGSTOP)
- return -EINVAL;
+ goto out;
if (handler != SIG_DFL && handler != SIG_IGN) {
err = verify_area(VERIFY_READ, handler, 1);
if (err)
- return err;
+ goto out;
}
memset(&tmp, 0, sizeof(tmp));
tmp.sa_handler = handler;
@@ -138,39 +160,52 @@
handler = current->sig->action[signum-1].sa_handler;
current->sig->action[signum-1] = tmp;
check_pending(signum);
- return (unsigned long) handler;
+ err = (unsigned long) handler;
+out:
+ unlock_kernel();
+ return err;
}
#endif
+#ifndef __sparc__
asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
struct sigaction * oldaction)
{
struct sigaction new_sa, *p;
+ int ret = -EINVAL;
+ lock_kernel();
if (signum<1 || signum>32)
- return -EINVAL;
+ goto out;
p = signum - 1 + current->sig->action;
if (action) {
- int err = verify_area(VERIFY_READ, action, sizeof(*action));
- if (err)
- return err;
+ ret = verify_area(VERIFY_READ, action, sizeof(*action));
+ if (ret)
+ goto out;
+ ret = -EINVAL;
if (signum==SIGKILL || signum==SIGSTOP)
- return -EINVAL;
+ goto out;
+ ret = -EFAULT;
if (copy_from_user(&new_sa, action, sizeof(struct sigaction)))
- return -EFAULT;
+ goto out;
if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
- err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
- if (err)
- return err;
+ ret = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
+ if (ret)
+ goto out;
}
}
+ ret = -EFAULT;
if (oldaction) {
if (copy_to_user(oldaction, p, sizeof(struct sigaction)))
- return -EFAULT;
+ goto out;
}
if (action) {
*p = new_sa;
check_pending(signum);
}
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov