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

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)