patch-2.4.19 linux-2.4.19/arch/sparc64/kernel/signal.c
Next file: linux-2.4.19/arch/sparc64/kernel/signal32.c
Previous file: linux-2.4.19/arch/sparc64/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 140
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/sparc64/kernel/signal.c
- Orig date:
Sun Mar 25 18:14:21 2001
diff -urN linux-2.4.18/arch/sparc64/kernel/signal.c linux-2.4.19/arch/sparc64/kernel/signal.c
@@ -411,6 +411,7 @@
struct rt_signal_frame *sf;
unsigned long tpc, tnpc, tstate;
__siginfo_fpu_t *fpu_save;
+ mm_segment_t old_fs;
sigset_t set;
stack_t st;
int err;
@@ -455,7 +456,10 @@
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
do_sigaltstack(&st, NULL, (unsigned long)sf);
+ set_fs(old_fs);
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(¤t->sigmask_lock);
@@ -574,6 +578,12 @@
regs->u_regs[UREG_I0] = signo;
regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+ /* The sigcontext is passed in this way because of how it
+ * is defined in GLIBC's /usr/include/bits/sigcontext.h
+ * for sparc64. It includes the 128 bytes of siginfo_t.
+ */
+ regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
+
/* 5. signal handler */
regs->tpc = (unsigned long) ka->sa.sa_handler;
regs->tnpc = (regs->tpc + 4);
@@ -709,9 +719,23 @@
signr = dequeue_signal(¤t->blocked, &info);
spin_unlock_irq(¤t->sigmask_lock);
- if (!signr) break;
+ if (!signr)
+ break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+ /* Do the syscall restart before we let the debugger
+ * look at the child registers.
+ */
+ if (restart_syscall &&
+ (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ regs->u_regs[UREG_I0] = orig_i0;
+ regs->tpc -= 4;
+ regs->tnpc -= 4;
+ restart_syscall = 0;
+ }
+
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
@@ -740,8 +764,8 @@
ka = ¤t->sig->action[signr-1];
- if(ka->sa.sa_handler == SIG_IGN) {
- if(signr != SIGCHLD)
+ if (ka->sa.sa_handler == SIG_IGN) {
+ if (signr != SIGCHLD)
continue;
/* sys_wait4() grabs the master kernel lock, so
@@ -749,16 +773,16 @@
* threaded and would not be that difficult to
* do anyways.
*/
- while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
;
continue;
}
- if(ka->sa.sa_handler == SIG_DFL) {
+ if (ka->sa.sa_handler == SIG_DFL) {
unsigned long exit_code = signr;
- if(current->pid == 1)
+ if (current->pid == 1)
continue;
- switch(signr) {
+ switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
@@ -771,8 +795,8 @@
continue;
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();
continue;
@@ -791,8 +815,8 @@
struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
unsigned long ins[8];
- while(rw &&
- !(((unsigned long) rw) & 0x3)) {
+ while (rw &&
+ !(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
@@ -806,22 +830,19 @@
#endif
/* fall through */
default:
- sigaddset(¤t->pending.signal, signr);
- recalc_sigpending(current);
- current->flags |= PF_SIGNALED;
- do_exit(exit_code);
+ sig_exit(signr, exit_code, &info);
/* NOT REACHED */
}
}
- if(restart_syscall)
+ if (restart_syscall)
syscall_restart(orig_i0, regs, &ka->sa);
handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
- if(restart_syscall &&
- (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
- regs->u_regs[UREG_I0] == ERESTARTSYS ||
- regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ if (restart_syscall &&
+ (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)