Plan 9 from Bell Labs’s /usr/web/sources/contrib/cinap_lenrek/old/linuxemu.old/proc.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include "linux.h"

typedef struct Jmparg Jmparg;
struct Jmparg
{
	int		(*fn)(void *);
	void		*arg;
	int		ret;
	jmp_buf	jmp;
};

static jmp_buf	stkjmp;

void
set9stack(void *stack)
{
	Jmparg *x;

	if(!(x = (Jmparg*)setjmp(stkjmp))){
		if(stack)
			stkjmp[JMPBUFSP] = (ulong)stack - 16;
		return;
	}
	DPRINT("now in 9stack from x=0x%p pc=0x%lux sp=0x%lux...\n",
		x, x->jmp[JMPBUFPC], x->jmp[JMPBUFSP]);
	x->ret = x->fn(x->arg);
	DPRINT("jumping back from 9stack to x=0x%p pc=0x%lux sp=0x%lux...\n",
		x, x->jmp[JMPBUFPC], x->jmp[JMPBUFSP]);
	longjmp(x->jmp, (int)x);
	abort();
}

int
do9stack(int (*fn)(void *), void *arg)
{
	Jmparg a;
	a.fn = fn;
	a.arg = arg;
	if(!setjmp(a.jmp)){
		longjmp(stkjmp, (int)&a);
		abort();
	}
	return a.ret;
}


typedef struct Args Args;
struct Args
{
	int		flags;
	int		stacksize;
	void	(*fn)(void *);
	void	*arg;
};

static int
_freeandexitxproc(void *aux)
{
	free(aux);
	exits(0);
	return 0;
}

static void
_exitxproc(void)
{
	ulong *p;
	ulong *top, *bot;

	p = (ulong*)&p;
	p += 2;
	if(memcmp(p, "STACKBOT", 8) != 0)
		abort();
	p += 2;
	bot = p;
	top = (ulong*)*bot;
	if(memcmp(&top[1], "STACKTOP", 8) != 0)
		abort();
	if(*bot != (ulong)top)
		abort();
	if(*top != (ulong)bot)
		abort();
	do9stack(_freeandexitxproc, top);
}

static int
_createxproc(void *aux)
{
	int pid;
	Args a, *x;

	x = aux;

	/* 
	 * need to have a deep copy on stack because x will
	 * go away if parent returns after rfork.
	 */
	memcpy(&a, x, sizeof(a));

	pid = rfork(a.flags);
	if(pid < 0)
		return pid;

	if(pid == 0){
		jmp_buf jmp;
		int n;
		ulong *top, *bot, *p;

		n = a.stacksize + (4 + 8) * 2;
		top = malloc(n);
		bot = (ulong*)((uchar*)top + n - 4);
		*top = (ulong)bot;
		*bot = (ulong)top;

		memcpy(&top[1], "STACKTOP", 8);

		p = bot;

		p -= 2;
		memcpy(p, "STACKBOT", 8);
		*--p = (ulong)a.arg;
		*--p = (ulong)_exitxproc;
		*--p = 0;

		jmp[JMPBUFSP] = (ulong)p;
		jmp[JMPBUFPC] = (ulong)a.fn;

		longjmp(jmp, 1);

		abort();
	}

	return pid;
}

int
createxproc(void (*fn)(void *), void *arg, int flags, int stacksize)
{
	Args a;

	a.fn = fn;
	a.arg = arg;
	a.flags = flags;
	a.stacksize = stacksize;

	return do9stack(_createxproc, &a);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.