lkml.org 
[lkml]   [1999]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: Porting vfork()
Date
> 
> 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, &regs);
}

+asmlinkage int sys_vfork(struct pt_regs regs)
+{
+ int child;
+
+ child = do_fork(CLONE_VM | SIGCHLD, regs.esp, &regs);
+
+ if (child > 0) {
+ sleep_on(&current->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(&current->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(&current->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/

\
 
 \ /
  Last update: 2005-03-22 13:49    [W:0.073 / U:1.372 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site