Messages in this thread Patch in this message | | | From | Perry Harrington <> | Subject | Re: Porting vfork() | Date | Fri, 8 Jan 1999 13:36:11 -0800 (PST) |
| |
> > On Fri, 8 Jan 1999, Linus Torvalds wrote: > > > > > > > On Fri, 8 Jan 1999, Perry Harrington wrote: > > > > > > > > Hmm... I do wonder about what happens to signals while vfork() is blocking > > > > the parent, though. Ick. The parent invoking signal handlers isn't much > > > > better then the child invoking signal handlers. One longjmp(), and > > > > everything gets confused. Temporarily block all signals to the parent but > > > > SIGKILL? Perhaps the only solution. And how does the child cleanly release > > > > the wait_queue in its parent if its parent may have been killed in the > > > > meantime? > > > > > > That's a good question, do you want to temporarily block signals to the parent? > > > > No need to. If you use sleep_on(), the parent won't be getting any signals > > anyway (only sleep_on_interruptible() cares about signals). > > Of course, but is that a good thing? The parent will be unkillable until > the child does something. Assuming the child wants to deny service in this > manner, you can always kill the parent by killing the child first, but > will process killers (human or automated) grok this? Is there anything > else in common use that causes this sort of behaviour? > > It's a little more work, but it might be nice to make the parent listen to > SIGKILL.
The parent doesn't listen to SIGKILL, SIGKILL it an unmaskable signal that is handled by the process management system of the kernel. If you issue a SIGKILL to the parent, it'll take care of the children (clone() creates a dependency which causes the kernel to kill processes clone()d, if I'm right).
> > Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126) >
Attached is my patch, the explanations and such should hit LK sometime, when the first rev goes through.
**********************************************************************************
diff -u --recursive linux.vanilla/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- linux.vanilla/arch/i386/kernel/entry.S Thu Jan 7 19:21:54 1999 +++ linux/arch/i386/kernel/entry.S Thu Jan 7 20:38:18 1999 @@ -559,13 +559,14 @@ .long SYMBOL_NAME(sys_sendfile) .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ + .long SYMBOL_NAME(sys_vfork) /* 190 */
/* - * NOTE!! This doesn' thave to be exact - we just have + * NOTE!! This doesn't have to be exact - we just have * to make sure we have _enough_ of the "sys_ni_syscall" * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-189 + .rept NR_syscalls-190 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive linux.vanilla/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- linux.vanilla/arch/i386/kernel/process.c Thu Jan 7 19:21:54 1999 +++ linux/arch/i386/kernel/process.c Thu Jan 7 20:33:23 1999 @@ -781,6 +781,19 @@ return do_fork(clone_flags, newsp, ®s); } +asmlinkage int sys_vfork(struct pt_regs regs) +{ + int child; + + child = do_fork(CLONE_VM | SIGCHLD, regs.esp, ®s); + + if (child > 0) { + sleep_on(¤t->vfork_sleep); + } + + return child; +} + /* * sys_execve() executes a new program. */ diff -u --recursive linux.vanilla/fs/exec.c linux/fs/exec.c --- linux.vanilla/fs/exec.c Sun Nov 15 09:52:27 1998 +++ linux/fs/exec.c Fri Jan 8 10:58:07 1999 @@ -808,6 +808,9 @@ int retval; int i;
+ /* vfork semantics say wakeup on exec or exit */ + wake_up(¤t->p_opptr->vfork_sleep); + bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ bprm.page[i] = 0; diff -u --recursive linux.vanilla/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- linux.vanilla/include/asm-i386/unistd.h Tue Nov 24 09:50:48 1998 +++ linux/include/asm-i386/unistd.h Fri Jan 8 10:59:29 1999 @@ -194,6 +194,7 @@ #define __NR_sendfile 187 #define __NR_getpmsg 188 /* some people actually want streams */ #define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190
/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
diff -u --recursive linux.vanilla/include/linux/sched.h linux/include/linux/sched.h --- linux.vanilla/include/linux/sched.h Thu Jan 7 19:27:44 1999 +++ linux/include/linux/sched.h Thu Jan 7 21:57:20 1999 @@ -258,6 +258,10 @@ struct task_struct **tarray_ptr;
struct wait_queue *wait_chldexit; /* for wait4() */ + +/* sleep in vfork parent */ + struct wait_queue *vfork_sleep; + unsigned long policy, rt_priority; unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; @@ -298,6 +302,7 @@ struct files_struct *files; /* memory management info */ struct mm_struct *mm; + /* signal handlers */ spinlock_t sigmask_lock; /* Protects signal and blocked */ struct signal_struct *sig; @@ -349,6 +354,7 @@ /* pidhash */ NULL, NULL, \ /* tarray */ &task[0], \ /* chld wait */ NULL, \ +/* vfork sleep */ NULL, \ /* timeout */ SCHED_OTHER,0,0,0,0,0,0,0, \ /* timer */ { NULL, NULL, 0, 0, it_real_fn }, \ /* utime */ {0,0,0,0},0, \ diff -u --recursive linux.vanilla/kernel/exit.c linux/kernel/exit.c --- linux.vanilla/kernel/exit.c Tue Nov 24 09:57:10 1998 +++ linux/kernel/exit.c Fri Jan 8 10:58:37 1999 @@ -292,6 +292,10 @@ kill_pg(current->pgrp,SIGHUP,1); kill_pg(current->pgrp,SIGCONT,1); } + + /* notify parent sleeping on vfork() */ + wake_up(¤t->p_opptr->vfork_sleep); + /* Let father know we died */ notify_parent(current, current->exit_signal);
diff -u --recursive linux.vanilla/kernel/fork.c linux/kernel/fork.c --- linux.vanilla/kernel/fork.c Thu Jan 7 19:27:29 1999 +++ linux/kernel/fork.c Thu Jan 7 20:24:53 1999 @@ -521,6 +521,7 @@ p->p_pptr = p->p_opptr = current; p->p_cptr = NULL; init_waitqueue(&p->wait_chldexit); + init_waitqueue(&p->vfork_sleep);
p->sigpending = 0; sigemptyset(&p->signal); ********************************************************************************** -- Perry Harrington Linux rules all OSes. APSoft () email: perry@apsoft.com Think Blue. /\
- 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/
| |