Subject: vfork

From: Philip Blundell <[email-masked]>
Date: Fri, 29 Jan 1999 13:21:15 +0000

Andreas Schwab pointed out that in fact sys_vfork is necessary on 
architectures like m68k and ARM after all, for backwards compatibility 
reasons.  An implementation based purely in the libc is fine for new 
kernels but will cause all sorts of lossage when run under an old kernel.  
Since compatibility with 2.0 is desirable it looks like we really do need a 
syscall.

I've accordingly added it back in my tree.  The problem is that the versions 
of 2.2.0 and 2.2.1 currently on the ftp site do actually provide sys_vfork but 
the implementation is wrong owing to changes in the generic fork code.  
Although I haven't tried it I think that any program trying to use sys_vfork 
on such a kernel will deadlock.  A patch for sys_arm.c to update to the new 
semantics is below, but be warned I haven't yet tested this either.

So, the question is: do we care about this?  If so we need to change 
__NR_vfork to some new number.  Russell, what do you think?

I'd like to resolve this quickly if possible so that glibc 2.1 can have a 
working vfork implementation.

p.

--- clean/linux/arch/arm/kernel/sys_arm.c	Fri Jan 29 11:46:32 1999
+++ linux/arch/arm/kernel/sys_arm.c	Fri Jan 29 12:44:45 1999
@@ -234,18 +234,20 @@
 	return do_fork(clone_flags, newsp, regs);
 }
 
+/*
+ * This is trivial, and on the face of it looks like it
+ * could equally well be done in user mode.
+ *
+ * Unfortunately backwards compatibility concerns mean that
+ * we need a new system call.  If user space simply called
+ * clone() directly an old kernel might silently ignore
+ * the CLONE_VFORK flag which would be death.
+ *
+ * This is called indirectly via a small wrapper
+ */
 asmlinkage int sys_vfork(struct pt_regs *regs)
 {
-	int child;
-	struct semaphore sem = MUTEX_LOCKED;
-
-	current->vfork_sem = &sem;
-	child = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs);
-
-	if (child > 0)
-		down(&sem);
-
-	return child;
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs);
 }
 
 /* sys_execve() executes a new program.

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]