patch-2.0.33 linux/kernel/exit.c

Next file: linux/kernel/fork.c
Previous file: linux/include/net/route.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.32/linux/kernel/exit.c linux/kernel/exit.c
@@ -28,6 +28,7 @@
 
 static inline void generate(unsigned long sig, struct task_struct * p)
 {
+	unsigned long flags;
 	unsigned long mask = 1 << (sig-1);
 	struct sigaction * sa = sig + p->sig->action - 1;
 
@@ -36,18 +37,24 @@
 	 * be handled immediately (ie non-blocked and untraced)
 	 * and that is ignored (either explicitly or by default)
 	 */
+	save_flags(flags); cli();
 	if (!(mask & p->blocked) && !(p->flags & PF_PTRACED)) {
 		/* don't bother with ignored signals (but SIGCHLD is special) */
-		if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
+		if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) {
+			restore_flags(flags);
 			return;
+		}
 		/* some signals are ignored by default.. (but SIGCONT already did its deed) */
 		if ((sa->sa_handler == SIG_DFL) &&
-		    (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG))
+		    (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG)) {
+			restore_flags(flags);
 			return;
+		}
 	}
 	p->signal |= mask;
 	if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked))
 		wake_up_process(p);
+	restore_flags(flags);
 }
 
 /*
@@ -58,20 +65,26 @@
 {
 	sig--;
 	if (p->sig) {
+		unsigned long flags;
 		unsigned long mask = 1UL << sig;
 		struct sigaction *sa = p->sig->action + sig;
+
+		save_flags(flags); cli();
 		p->signal |= mask;
 		p->blocked &= ~mask;
 		if (sa->sa_handler == SIG_IGN)
 			sa->sa_handler = SIG_DFL;
 		if (p->state == TASK_INTERRUPTIBLE)
 			wake_up_process(p);
+		restore_flags(flags);
 	}
 }
 		
 
 int send_sig(unsigned long sig,struct task_struct * p,int priv)
 {
+	unsigned long flags;
+
 	if (!p || sig > 32)
 		return -EINVAL;
 	if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
@@ -86,6 +99,7 @@
 	 */
 	if (!p->sig)
 		return 0;
+	save_flags(flags); cli();
 	if ((sig == SIGKILL) || (sig == SIGCONT)) {
 		if (p->state == TASK_STOPPED)
 			wake_up_process(p);
@@ -95,6 +109,8 @@
 	}
 	if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
 		p->signal &= ~(1<<(SIGCONT-1));
+	restore_flags(flags);
+
 	/* Actually generate the signal */
 	generate(sig,p);
 	return 0;
@@ -402,8 +418,13 @@
 		if (i >= NR_OPEN)
 			break;
 		while (set) {
-			if (set & 1)
-				close_fp(files->fd[i]);
+			if (set & 1) {
+				struct file * file = files->fd[i];
+				if (file) {
+					files->fd[i] = NULL;
+					close_fp(file);
+				}
+			}
 			i++;
 			set >>= 1;
 		}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov