#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/ns.h>

/*
 * We only implement the rfork calls that don't have RFPROC.
 * Whenever someone calls rfork without RFPROC they ignore
 * the return value.  Hence, do not fail.  Instead, abort.
 * (Don't check malloc's return value, etc.)
 */
int
rfork(int flag)
{
	int handled;
	Fgrp *f, *nf;
	Pgrp *g;
	Proc *p;

	p = getproc();
	handled = 0;
	if(flag&RFFDG){
		if(flag&RFCFDG)
			abort();
		f = p->fgrp;
		nf = dupfgrp(f);
		p->fgrp = nf;
		closefgrp(f);
		handled |= RFFDG;
	}
	if(flag&RFCFDG){
		pm_lock(&p->lk);
		f = p->fgrp;
		nf = dupfgrp(nil);
		p->fgrp = nf;
		closefgrp(f);
		handled |= RFCFDG;
	}
	if(flag&(RFNAMEG|RFCNAMEG)){
		if((flag&(RFNAMEG|RFCNAMEG))==(RFNAMEG|RFCNAMEG))
			abort();
		g = p->pgrp;
		p->pgrp = newpgrp();
		if(flag&RFNAMEG)
			pgrpcpy(p->pgrp, g);
		p->pgrp->noattach = g->noattach;
		closepgrp(g);
		handled |= flag&(RFNAMEG|RFCNAMEG);
	}
	if(flag&RFNOMNT){
		p->pgrp->noattach = 1;
		handled |= RFNOMNT;
	}
	handled |= pm_sysrfork(flag);
	if(handled != flag){
		fprint(2, "pm_rfork: flag=0x%x handled=0x%x\n", flag, handled);
		abort();
	}
	return 0;
}
