Just popping in
Joined: 2007/6/5 14:51 Last Login
: 9/4 22:03
From Brisbane, AUSTRALIA
Group:
Registered Users
|
The subprocess is still running in the code space loaded for the parent. The parent exits, unloads the code, subprocess crashes. That's pretty well outlines your problem.
Two basic ways to fix this....
1) Use NP_Child tag and make the parent Wait()/WaitMsg() until the child exits, see; NP_NotifyOnDeathMessage and NP_NotifyOnDeathSigTask. Set up a message/signal and only allow the parent to leave only when the child notifies you of its death. However, this means that the parent must go to sleep until the child exits, which means that if the parent was a shell process, the CLI will be "dead" until the child ends.
2) If you wish to affect a complete detachment of the child and allow the parent to completely exit while allowing the child to continue execution in the old code space, then the resources that are shared by the child MUST also be detached.
This can be a little more complicated and not really for the beginner. Nevertheless, here's an outline of what needs to be done.
The easiest way is to call CreateNewProc() with no tags for the NP_Input,NP_Output,NP_Error, these will then open a default "NIL:" stream for the child (and 0 for the error stream). (and with NP_Child,FALSE)
With that taken care of, (here's the tricky part), because as the seglist is being shared, you must make sure it is not freed by the parent process on exit,
You can transfer ownership to the child process, so that it frees it on exit instead, so it is not done by the parent. To do this, you need to determine who loaded the original, this can be the shell or 'other'. If the shell loaded it, you need to stop it from unloading the command on exit.
Here's some pseudocode.....
============
BPTR seg = ZERO; struct CommandLineInterface *cli = IDOS->Cli(); if( cli ) { seg = cli->cli_Module; cli->cli_Module = ZERO; /* stop shell freeing the seg */ } else /* not a cli, try 'other' load methods */ { seg = IDOS->GetProcSegList(NULL,GPSLF_SEG); if( seg ) { struct Process *me = (struct Process *)FindTask(0); me->pr_Flags &= (~PRF_FREESEGLIST); } /* clear the flag for parent to free seglist */ }
if( seg ) /* did we find a loadsegged seglist ? */ { IDOS->CreateNewProcTags( NP_Entry, child_entry_func, /* entry() here */ NP_SegList, seg, /* free this seg on exit */ NP_FreeSegList,TRUE, /* make it so */ ... TAG_END); } else { PutStr("ERROR: Cannot find loaded seglist..\n"); }
NOTE WELL: You cannot call newlib functions in the child process unless you re-open the library within the child process itself, and set the childProc->pr_CLibData to the newlib base as there will be no default library context available to the child.
Better to just use the IDOS-> functions while inside the child process.
Also note that as the child is now responsible for freeing the seglist on exit, you MUST make sure the parent now exits BEFORE the child does, otherwise you will find yourself in the same situation.
|