patch-2.0.1 linux/kernel/exit.c

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

diff -u --recursive --new-file v2.0.0/linux/kernel/exit.c linux/kernel/exit.c
@@ -75,8 +75,8 @@
 	if (!p || sig > 32)
 		return -EINVAL;
 	if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
-	    (current->euid ^ p->euid) && (current->euid ^ p->uid) &&
-	    (current->uid ^ p->euid) && (current->uid ^ p->uid) &&
+	    (current->euid ^ p->suid) && (current->euid ^ p->uid) &&
+	    (current->uid ^ p->suid) && (current->uid ^ p->uid) &&
 	    !suser())
 		return -EPERM;
 	if (!sig)
@@ -346,12 +346,12 @@
  * 
  * "I ask you, have you ever known what it is to be an orphan?"
  */
-int is_orphaned_pgrp(int pgrp)
+static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task)
 {
 	struct task_struct *p;
 
 	for_each_task(p) {
-		if ((p->pgrp != pgrp) || 
+		if ((p == ignored_task) || (p->pgrp != pgrp) || 
 		    (p->state == TASK_ZOMBIE) ||
 		    (p->p_pptr->pid == 1))
 			continue;
@@ -362,6 +362,11 @@
 	return(1);	/* (sighing) "Often!" */
 }
 
+int is_orphaned_pgrp(int pgrp)
+{
+	return will_become_orphaned_pgrp(pgrp, 0);
+}
+
 static inline int has_stopped_jobs(int pgrp)
 {
 	struct task_struct * p;
@@ -495,7 +500,7 @@
 	 */
 	if ((current->p_pptr->pgrp != current->pgrp) &&
 	    (current->p_pptr->session == current->session) &&
-	    is_orphaned_pgrp(current->pgrp) &&
+	    will_become_orphaned_pgrp(current->pgrp, current) &&
 	    has_stopped_jobs(current->pgrp)) {
 		kill_pg(current->pgrp,SIGHUP,1);
 		kill_pg(current->pgrp,SIGCONT,1);
@@ -607,6 +612,9 @@
 		if (flag)
 			return flag;
 	}
+	if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
+	    return -EINVAL;
+
 	add_wait_queue(&current->wait_chldexit,&wait);
 repeat:
 	flag=0;
@@ -666,12 +674,11 @@
 		retval = 0;
 		if (options & WNOHANG)
 			goto end_wait4;
-		current->state=TASK_INTERRUPTIBLE;
-		schedule();
-		current->signal &= ~(1<<(SIGCHLD-1));
 		retval = -ERESTARTSYS;
 		if (current->signal & ~current->blocked)
 			goto end_wait4;
+		current->state=TASK_INTERRUPTIBLE;
+		schedule();
 		goto repeat;
 	}
 	retval = -ECHILD;

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