(again..) PATCH: CLONE_PPID and friends - comments>?

Message ID 199908100653.BAA12955@isunix.it.ilstu.edu
State New, archived
Headers show
Series
  • (again..) PATCH: CLONE_PPID and friends - comments>?
Related show

Commit Message

Tim Hockin Aug. 10, 1999, 6:53 a.m. UTC
Here is the (latest edition of the) final CLONE_PPID patch.  I reworked
sys_wait4, and few other comments I received.

Anyone see anything wrong with this?  Else I will make a 2.3.x diff and
pass it on to Linus before the 2.4 freeze..


Tim




-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

Patch

diff -ru clean-linux-2.2.10/fs/exec.c clone-linux-2.2.10/fs/exec.c
--- clean-linux-2.2.10/fs/exec.c	Sun Jun 13 10:50:04 1999
+++ clone-linux-2.2.10/fs/exec.c	Thu Jul 22 03:17:00 1999
@@ -846,9 +846,12 @@ 
 
 	if (retval >= 0)
 		retval = search_binary_handler(&bprm,regs);
-	if (retval >= 0)
+	if (retval >= 0) {
+		/* clear any thread-special bits - JIC */
+		current->flags &= ~(PF_PPIDOK | PF_CLWAIT);
 		/* execve success */
 		return retval;
+	}
 
 	/* Something went wrong, return the inode and free the argument pages*/
 	if (bprm.dentry)
diff -ru clean-linux-2.2.10/include/linux/sched.h clone-linux-2.2.10/include/linux/sched.h
--- clean-linux-2.2.10/include/linux/sched.h	Tue May 11 10:35:45 1999
+++ clone-linux-2.2.10/include/linux/sched.h	Thu Jul 22 02:51:17 1999
@@ -34,6 +34,10 @@ 
 #define CLONE_PID	0x00001000	/* set if pid shared */
 #define CLONE_PTRACE	0x00002000	/* set if we want to let tracing continue on the child too */
 #define CLONE_VFORK	0x00004000	/* set if the parent wants the child to wake it up on mm_release */
+#define CLONE_PPIDOK	0x00008000	/* set if the child should be able to create siblings */
+#define CLONE_PPID	0x00010000	/* set if we want to create a sibling, not a child */
+#define CLONE_WAIT 	0x00020000	/* set if child is allowed to wait() for siblings */
+#define CLONE_SUSPENDED	0x00040000	/* create a process in the stopped state */
 
 /*
  * These are the constant used to fake the fixed-point load-average
@@ -332,6 +336,8 @@ 
 
 #define PF_USEDFPU	0x00100000	/* task used FPU this quantum (SMP) */
 #define PF_DTRACE	0x00200000	/* delayed trace (used on m68k, i386) */
+#define PF_PPIDOK	0x00400000	/* task is allowed to use CLONE_PPID */
+#define PF_CLWAIT	0x00800000	/* allowed to wait for siblings */
 
 /*
  * Limit the stack by to some sane default: root can always
diff -ru clean-linux-2.2.10/kernel/exit.c clone-linux-2.2.10/kernel/exit.c
--- clean-linux-2.2.10/kernel/exit.c	Fri Apr 30 08:13:37 1999
+++ clone-linux-2.2.10/kernel/exit.c	Sun Aug  8 16:28:33 1999
@@ -145,6 +145,7 @@ 
 	read_lock(&tasklist_lock);
 	for_each_task(p) {
 		if (p->p_opptr == father) {
+			p->flags &= ~(PF_PPIDOK | PF_CLWAIT);
 			p->exit_signal = SIGCHLD;
 			p->p_opptr = child_reaper; /* init */
 			if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
@@ -407,16 +408,22 @@ 
 {
 	int flag, retval;
 	struct wait_queue wait = { current, NULL };
+	struct wait_queue wait_sib = { current, NULL };
 	struct task_struct *p;
+	struct task_struct *start;
 
 	if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
 		return -EINVAL;
 
 	add_wait_queue(&current->wait_chldexit,&wait);
+	if (current->flags & PF_CLWAIT)
+		add_wait_queue(&current->p_pptr->wait_chldexit,&wait_sib);
+
+	start = current->p_cptr;
 repeat:
 	flag = 0;
 	read_lock(&tasklist_lock);
- 	for (p = current->p_cptr ; p ; p = p->p_osptr) {
+ 	for (p = start ; p ; p = p->p_osptr) {
 		if (pid>0) {
 			if (p->pid != pid)
 				continue;
@@ -484,10 +491,19 @@ 
 		current->state=TASK_INTERRUPTIBLE;
 		schedule();
 		goto repeat;
+	} else {
+		/* try the siblings ? */
+		if ((current->flags & PF_CLWAIT) && (start != current->p_pptr->p_cptr)) {
+			start = current->p_pptr->p_cptr;
+			goto repeat;
+		}
 	}
 	retval = -ECHILD;
 end_wait4:
 	remove_wait_queue(&current->wait_chldexit,&wait);
+	if (current->flags & PF_CLWAIT)
+		remove_wait_queue(&current->p_pptr->wait_chldexit,&wait_sib);
+
 	return retval;
 }
 
diff -ru clean-linux-2.2.10/kernel/fork.c clone-linux-2.2.10/kernel/fork.c
--- clean-linux-2.2.10/kernel/fork.c	Mon Apr 12 12:44:26 1999
+++ clone-linux-2.2.10/kernel/fork.c	Thu Jul 29 10:08:13 1999
@@ -517,12 +517,18 @@ 
 {
 	unsigned long new_flags = p->flags;
 
-	new_flags &= ~(PF_SUPERPRIV | PF_USEDFPU | PF_VFORK);
+	new_flags &= ~(PF_SUPERPRIV | PF_USEDFPU | PF_VFORK 
+		       | PF_PPIDOK | PF_CLWAIT);
 	new_flags |= PF_FORKNOEXEC;
 	if (!(clone_flags & CLONE_PTRACE))
 		new_flags &= ~(PF_PTRACED|PF_TRACESYS);
 	if (clone_flags & CLONE_VFORK)
 		new_flags |= PF_VFORK;
+	if (clone_flags & CLONE_PPIDOK)
+		new_flags |= PF_PPIDOK;
+	if (clone_flags & CLONE_WAIT)
+		new_flags |= PF_CLWAIT;
+
 	p->flags = new_flags;
 }
 
@@ -587,7 +593,14 @@ 
 	p->next_run = p;
 	p->prev_run = p;
 
-	p->p_pptr = p->p_opptr = current;
+	if (!(clone_flags & CLONE_PPID)) {
+		p->p_pptr = p->p_opptr = current;
+	} else if (current->flags & PF_PPIDOK) {
+		p->p_pptr = p->p_opptr = current->p_opptr;
+	} else {
+		retval = -EPERM;
+		goto bad_fork_cleanup;
+	}
 	p->p_cptr = NULL;
 	init_waitqueue(&p->wait_chldexit);
 	p->vfork_sem = NULL;
@@ -668,7 +681,10 @@ 
 
 		p->next_run = NULL;
 		p->prev_run = NULL;
-		wake_up_process(p);		/* do this last */
+		if (!(clone_flags & CLONE_SUSPENDED))
+			wake_up_process(p);	/* do this last */
+		else
+			p->state = TASK_STOPPED;
 	}
 	++total_forks;
 bad_fork: