/* Create a new process with a given address as the entry point. MUST be * called from a process (not a plain task). */ #include #include #include #include #include #include long fork_stacksize = 0; /* what stack size to use; 0 = from parent */ #define myproc ((struct Process *)mytask) #define pproc ((struct Process *)parent) /* forkproc() entry point */ static __geta4 void fork_entry() { struct Task *mytask = FindTask(NULL), *parent; __stkargs void (*entry)(void *); void *entrydata; char *s; int i; long ptr; s = mytask->tc_Node.ln_Name; ptr = 0; for (i = 0; i < 8; ++i) { ptr = (ptr<<4) | (*s++ & 0x0F); } parent = (struct Task *)ptr; mytask->tc_Node.ln_Name = parent->tc_Node.ln_Name; entrydata = (void *)myproc->pr_ConsoleTask; myproc->pr_ConsoleTask = pproc->pr_ConsoleTask; entry = (void (*)())myproc->pr_WindowPtr; myproc->pr_WindowPtr = pproc->pr_WindowPtr; entry(entrydata); } #undef myproc #undef pproc struct Process *forkproc(__stkargs void (*entry)(void *), void *entrydata) { long tags[] = { NP_Entry, (long)fork_entry, NP_Input, 0, NP_Output, 0, NP_Error, 0, NP_CloseInput, FALSE, NP_CloseOutput, FALSE, NP_CloseError, FALSE, NP_StackSize, 0, NP_Name, 0, /* pass our TCB here */ NP_WindowPtr, 0, /* pass entry point here */ NP_ConsoleTask, 0, /* pass entry data here */ NP_Cli, FALSE, TAG_END }; struct Task *mytask = FindTask(NULL); char s[9]; int i; long ptr; tags[1] = (long)fork_entry; tags[3] = fdtofh(fileno(stdin)); tags[5] = fdtofh(fileno(stdout)); tags[7] = fdtofh(fileno(stderr)); if (fork_stacksize) tags[15] = fork_stacksize; else tags[15] = mytask->tc_SPUpper - mytask->tc_SPLower; ptr = (long)mytask; for (i = 0; i < 8; ++i) { s[i] = ((mytask >> 28) & 0x0F) | 0x30; mytask <<= 4; } s[8] = 0; tags[17] = (long)s; /* have to do this in a roundabout way * because CreateNewProc() makes a copy * of the title string */ tags[19] = (long)entry; tags[21] = (long)entrydata; return CreateNewProc(tags); }