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/