> this is fine for most calls, however rfork() explicitly sets up->nerrlab
> to zero rather than copying it and memmove()ing up->errlab from the parent
> proc to the child:
> 
>        /sys/src/9/port/sysproc.c:90
> 
> Surely this means that rfork will always fail with a "bad errstack [19]: -1 
> extra"
> error?  

long
sysrfork(ulong *arg)
{
        ...

        /* Craft a return frame which will cause the child to pop out of
         * the scheduler in user mode with the return register zero
         */
        forkchild(p, up->dbgreg);
        ...
        ready(p);
        ...
}

void
forkchild(Proc *p, Ureg *ureg)
{
        Ureg *cureg;

        /*
         * Add 2*BY2WD to the stack to account for
         *  - the return PC
         *  - trap's argument (ur)
         */
        p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2WD);
        p->sched.pc = (ulong)forkret;

        cureg = (Ureg*)(p->sched.sp+2*BY2WD);
        memmove(cureg, ureg, sizeof(Ureg));
        /* return value of syscall in child */
        cureg->ax = 0;

        /* Things from bottom of syscall which were never executed */
        p->psstate = 0;
        p->insyscall = 0;
}

TEXT forkret(SB), $0
        POPL    AX
        POPAL
        POPL    GS
        POPL    FS
        POPL    ES
        POPL    DS
        ADDL    $8, SP                  /* pop error code and trap type */
        IRETL


Reply via email to