Messages in this thread Patch in this message | | | From | Tim Hockin <> | Subject | (again..) PATCH: CLONE_PPID and friends - comments>? | Date | Tue, 10 Aug 1999 01:53:42 -0500 (CDT) |
| |
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
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(¤t->wait_chldexit,&wait); + if (current->flags & PF_CLWAIT) + add_wait_queue(¤t->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(¤t->wait_chldexit,&wait); + if (current->flags & PF_CLWAIT) + remove_wait_queue(¤t->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: - 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/
| |