Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Feb 1998 06:26:04 -0500 (EST)
From:      "John S. Dyson" <dyson@FreeBSD.ORG>
To:        perlsta@sunyit.edu (Alfred Perlstein)
Cc:        hackers@FreeBSD.ORG
Subject:   Re: implementing linux's clone()
Message-ID:  <199802041126.GAA00964@dyson.iquest.net>
In-Reply-To: <199802041111.GAA01268@demeter.sunyit.edu> from Alfred Perlstein at "Feb 4, 98 06:01:29 am"

next in thread | previous in thread | raw e-mail | index | archive | help
Alfred Perlstein said:
> is there any function that offers the clone() call that linux has?
> 
> specifically i have to set the new process's stack frame to a specific
> place,
> and implement the linux clone features, all this is in an attempt to port
> wine to freebsd and also make building programs that use clone() possible
> under freebsd.
>
In FreeBSD-current there is such a function, but you have to be careful
about setting up the stack (with the philosophy of minimizing what is
in the kernel.)

> 
> rfork() seems to be what i need, however i'm not totally sure of the
> differences between it and clone() as clone seems to have more options,
> plus i don't know how to set the stack to point towards something else in
> the child process, however i have done some reading up on it:
> 
Take a look at my rf.S for an example.  errno is problematical with the
default C lib stuff.

-- 
John                  | Never try to teach a pig to sing,
dyson@freebsd.org     | it just makes you look stupid,
jdyson@nc.com         | and it irritates the pig.


	.file	"rf.S"
#include <sys/syscall.h>
#include "DEFS.h"
#include "SYS.h"
#define KERNEL
#include <sys/errno.h>
#undef KERNEL

#undef DEBUG

/*
 *        8      12     16        20        24       28
 * _rfork(flags, stack, startrtn, startarg, userrtn, arg);
 *
 * flags: RF* flags for rfork in unistd.h.
 * subr:  subroutine to run as a thread.
 * stack: top of stack for thread.
 * arg:   argument to thread.
 */
.stabs "rf.S",100,0,0,Ltext0
	.text
Ltext0:
	.type	_thrfork,@function
	.stabd 68,0,1
ENTRY(thrfork)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%esi

	/*
	 * Push thread info onto the new thread's stack
	 */
	movl	12(%ebp), %esi	/ get stack addr

	subl	$4, %esi
	movl	28(%ebp), %eax	/ get user argument
	movl	%eax, (%esi)

	subl	$4, %esi
	movl	24(%ebp), %eax	/ get user thread address
	movl	%eax, (%esi)

	subl	$4, %esi
	movl	20(%ebp), %eax	/ get internal argument
	movl	%eax, (%esi)

	subl	$4, %esi
	movl	16(%ebp), %eax	/ get internal subroutine
	movl	%eax, (%esi)

	.stabd 68,0,2
	/*
	 * Prepare and execute rfork
	 */
	pushl	8(%ebp)
	pushl	%esi
	leal	SYS_rfork, %eax
	KERNCALL
	jb 	2f

	.stabd 68,0,3
	/*
	 * Check to see if we are in the parent or child
	 */
	cmpl	$0, %edx
	jnz	1f
	addl	$8, %esp
	popl	%esi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.p2align 2

	/*
	 * If we are in the child (new thread), then
	 * set-up the call to the internal subroutine.  If it
	 * returns, then call __exit.
	 */
	.stabd 68,0,4
1:
	movl	%esi,%esp
#ifdef DEBUG
	movl	%esp, _stackaddr
	movl	(%esp), %eax
	movl	%eax, _stack
	movl	4(%esp), %eax
	movl	%eax,_stack+4
	movl	8(%esp), %eax
	movl	%eax,_stack+8
	movl	12(%esp), %eax
	movl	%eax,_stack+12
#endif
	popl	%eax 
#ifdef DEBUG
	movl	%eax,_fcn
#endif
	call	%eax
	addl	$12, %esp

	/*
	 * Exit system call
	 */
	pushl	%eax
	pushl	$SYS_exit
	call	_syscall

	.stabd 68,0,5
2:	movl	$EAGAIN, _errno
	movl	$-1, %eax
	leave
	ret
.stabs "thrfork:f67",36,0,6,_thrfork
Lfe1:
	.size	 _thrfork,Lfe1-_thrfork

#ifdef DEBUG
	.data
	.globl	_stack
_stack:	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.globl	_stackaddr
_stackaddr:	.long	0
	.globl	_fcn
_fcn:	.long	0
#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802041126.GAA00964>