patch-2.1.69 linux/arch/i386/kernel/signal.c
Next file: linux/arch/i386/kernel/sys_i386.c
Previous file: linux/arch/i386/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Mon Dec 1 11:27:58 1997
- Orig file:
v2.1.68/linux/arch/i386/kernel/signal.c
- Orig date:
Mon Dec 1 12:04:11 1997
diff -u --recursive --new-file v2.1.68/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
@@ -19,7 +19,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
-
+#include <asm/ucontext.h>
#include <asm/uaccess.h>
#define DEBUG_SIG 0
@@ -372,7 +372,7 @@
/* XXX: Check here if we need to switch stacks.. */
/* This is legacy signal stack switching. */
- if ((regs->xss & 0xffff) != USER_DS
+ if ((regs->xss & 0xffff) != __USER_DS
&& !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer)
frame = (struct sigframe *) ka->sa.sa_restorer;
@@ -409,13 +409,13 @@
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
{
- unsigned long seg = USER_DS;
+ unsigned long seg = __USER_DS;
__asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
- set_fs(seg);
+ set_fs(MAKE_MM_SEG(seg));
regs->xds = seg;
regs->xes = seg;
regs->xss = seg;
- regs->xcs = USER_CS;
+ regs->xcs = __USER_CS;
}
regs->eflags &= ~TF_MASK;
@@ -441,7 +441,7 @@
/* XXX: Check here if we need to switch stacks.. */
/* This is legacy signal stack switching. */
- if ((regs->xss & 0xffff) != USER_DS
+ if ((regs->xss & 0xffff) != __USER_DS
&& !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer)
frame = (struct rt_sigframe *) ka->sa.sa_restorer;
@@ -481,13 +481,13 @@
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
{
- unsigned long seg = USER_DS;
+ unsigned long seg = __USER_DS;
__asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
- set_fs(seg);
+ set_fs(MAKE_MM_SEG(seg));
regs->xds = seg;
regs->xes = seg;
regs->xss = seg;
- regs->xcs = USER_CS;
+ regs->xcs = __USER_CS;
}
regs->eflags &= ~TF_MASK;
@@ -560,9 +560,7 @@
*/
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
- sigset_t _oldset;
siginfo_t info;
- unsigned long signr, core = 0;
struct k_sigaction *ka;
/*
@@ -574,14 +572,19 @@
if ((regs->xcs & 3) != 3)
return 1;
- spin_lock_irq(¤t->sigmask_lock);
- if (!oldset) {
- _oldset = current->blocked;
- oldset = &_oldset;
- }
- while ((signr = dequeue_signal(¤t->blocked, &info)) != 0) {
+ if (!oldset)
+ oldset = ¤t->blocked;
+
+ for (;;) {
+ unsigned long signr;
+
+ spin_lock_irq(¤t->sigmask_lock);
+ signr = dequeue_signal(¤t->blocked, &info);
spin_unlock_irq(¤t->sigmask_lock);
+ if (!signr)
+ break;
+
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
@@ -591,12 +594,12 @@
/* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
- goto skip_signal;
+ continue;
current->exit_code = 0;
/* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
- goto skip_signal;
+ continue;
/* Update the siginfo structure. Is this good? */
if (signr != info.si_signo) {
@@ -610,41 +613,51 @@
/* If the (new) signal is now blocked, requeue it. */
if (sigismember(¤t->blocked, signr)) {
send_sig_info(signr, &info, current);
- goto skip_signal;
+ continue;
}
}
ka = ¤t->sig->action[signr-1];
+ if (ka->sa.sa_handler == SIG_IGN) {
+ if (signr != SIGCHLD)
+ continue;
+ /* Check for SIGCHLD: it's special. */
+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+ /* nothing */;
+ continue;
+ }
+
if (ka->sa.sa_handler == SIG_DFL) {
+ int exit_code = signr;
+
/* Init gets no signals it doesn't want. */
if (current->pid == 1)
- goto skip_signal;
+ continue;
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
- goto skip_signal;
+ continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
- goto skip_signal;
+ continue;
/* FALLTHRU */
case SIGSTOP:
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1]
- .sa.sa_flags & SA_NOCLDSTOP))
+ if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
- break;
+ continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
lock_kernel();
if (current->binfmt
&& current->binfmt->core_dump
- &¤t->binfmt->core_dump(signr, regs))
- core = 0x80;
+ && current->binfmt->core_dump(signr, regs))
+ exit_code |= 0x80;
unlock_kernel();
/* FALLTHRU */
@@ -652,21 +665,14 @@
lock_kernel();
sigaddset(¤t->signal, signr);
current->flags |= PF_SIGNALED;
- do_exit((signr & 0x7f) | core);
- }
- } else if (ka->sa.sa_handler == SIG_IGN) {
- if (signr == SIGCHLD) {
- /* Check for SIGCHLD: it's special. */
- while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
- /* nothing */;
+ do_exit(exit_code);
+ /* NOTREACHED */
}
- } else {
- /* Whee! Actually deliver the signal. */
- handle_signal(signr, ka, &info, oldset, regs);
- return 1;
}
- skip_signal:
- spin_lock_irq(¤t->sigmask_lock);
+
+ /* Whee! Actually deliver the signal. */
+ handle_signal(signr, ka, &info, oldset, regs);
+ return 1;
}
/* Did we come from a system call? */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov