Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Feb 1998 12:18:17 -0500
From:      "Alfred Perlstein" <perlsta@sunyit.edu>
To:        <dyson@FreeBSD.ORG>
Cc:        <hackers@FreeBSD.ORG>
Subject:   Re: implementing linux's clone()
Message-ID:  <199802041722.MAA18385@demeter.sunyit.edu>

next in thread | raw e-mail | index | archive | help
hmmm very interesting, thank you.

before i cvsup to -current i was wondering if the fuction is "clone-like"
or really just like clone(), will i be disapointed by its functionality
because of what i need from it?

and what do you mean, you have to be careful what you pass it on the stack?
that doesn't mean you can crash BSD with an innapropriate call does it? 
just that if you give bad args your program will segfault or something?

also, if i modded the below asm stuff not to __exit after return would that
"work" or is there something i'm not seeing? and what is the "arg"
parameter, a pointer to the thread function's arguments?

thanks for the help,
-Alfred

> 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?199802041722.MAA18385>