patch-2.2.17 linux/arch/sparc/kernel/signal.c
Next file: linux/arch/sparc/kernel/sparc_ksyms.c
Previous file: linux/arch/s390/tools/silo/silo.c
Back to the patch index
Back to the overall index
- Lines: 115
- Date:
Mon Sep 4 18:39:16 2000
- Orig file:
v2.2.16/arch/sparc/kernel/signal.c
- Orig date:
Mon Sep 4 18:37:46 2000
diff -u --recursive --new-file v2.2.16/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.91.2.1 1999/06/14 00:36:13 davem Exp $
+/* $Id: signal.c,v 1.91.2.2 2000/05/28 19:13:21 ecd Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -536,7 +536,7 @@
static inline void
new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset)
+ int signr, sigset_t *oldset)
{
struct new_signal_frame *sf;
int sigframe_size, err;
@@ -583,7 +583,7 @@
/* 3. signal handler back-trampoline and parameters */
regs->u_regs[UREG_FP] = (unsigned long) sf;
- regs->u_regs[UREG_I0] = signo;
+ regs->u_regs[UREG_I0] = signr;
regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
/* 4. signal handler */
@@ -617,7 +617,7 @@
static inline void
new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset, siginfo_t *info)
+ int signr, sigset_t *oldset, siginfo_t *info)
{
struct rt_signal_frame *sf;
int sigframe_size;
@@ -650,20 +650,77 @@
} else {
err |= __put_user(0, &sf->fpu_save);
}
- err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
-
+
+ /* Update the siginfo structure. Is this good? */
+ if (info->si_code == 0) {
+ info->si_signo = signr;
+ info->si_errno = 0;
+
+ switch (signr) {
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
+ case SIGEMT:
+ info->si_code = current->tss.sig_desc;
+ info->si_addr = (void *)current->tss.sig_address;
+ info->si_trapno = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ err = __put_user (info->si_signo, &sf->info.si_signo);
+ err |= __put_user (info->si_errno, &sf->info.si_errno);
+ err |= __put_user (info->si_code, &sf->info.si_code);
+ if (info->si_code < 0)
+ err |= __copy_to_user (sf->info._sifields._pad, info->_sifields._pad, SI_PAD_SIZE);
+ else {
+ int i = info->si_signo;
+ if (info->si_code == SI_USER)
+ i = SIGRTMIN;
+ switch (i) {
+ case SIGPOLL:
+ err |= __put_user (info->si_band, &sf->info.si_band);
+ err |= __put_user (info->si_fd, &sf->info.si_fd);
+ break;
+ case SIGCHLD:
+ err |= __put_user (info->si_pid, &sf->info.si_pid);
+ err |= __put_user (info->si_uid, &sf->info.si_uid);
+ err |= __put_user (info->si_status, &sf->info.si_status);
+ err |= __put_user (info->si_utime, &sf->info.si_utime);
+ err |= __put_user (info->si_stime, &sf->info.si_stime);
+ break;
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
+ case SIGEMT:
+ err |= __put_user ((long)info->si_addr, &sf->info.si_addr);
+ err |= __put_user (info->si_trapno, &sf->info.si_trapno);
+ break;
+ default:
+ err |= __put_user (info->si_pid, &sf->info.si_pid);
+ err |= __put_user (info->si_uid, &sf->info.si_uid);
+ break;
+ }
+ }
+
/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
-
+
+ err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
+
err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
sizeof (struct reg_window));
if (err)
goto sigsegv;
regs->u_regs[UREG_FP] = (unsigned long) sf;
- regs->u_regs[UREG_I0] = signo;
+ regs->u_regs[UREG_I0] = signr;
regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
regs->pc = (unsigned long) ka->sa.sa_handler;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)