home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / libnix-0.8-src.lha / libnix-0.8 / sources / misc / detach.c next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  3.0 KB  |  94 lines

  1. #include <exec/memory.h>
  2. #include <dos/dosextens.h>
  3. #include <dos/dostags.h>
  4. #ifdef __GNUC__
  5. #include <inline/exec.h>
  6. #include <inline/dos.h>
  7. #endif
  8. #include <stabs.h>
  9.  
  10. /* Sorry, but the assembler code produced by gcc for this function is too bad.
  11.  * This one is much better!
  12.  */
  13. #ifdef CreateNewProcTags
  14. #undef CreateNewProcTags
  15. static struct Process *CreateNewProcTags(ULONG Tag1,...)
  16. { return CreateNewProc((struct TagItem *)&Tag1); }
  17. #endif
  18.  
  19. extern struct WBStart *_WBenchMsg;
  20. extern char *__commandline;
  21. extern struct DosLibrary *DOSBase;
  22. extern struct ExecBase *SysBase;
  23. extern void *__SaveSP;
  24. extern char __dosname[];
  25.  
  26. extern char *__procname;
  27. extern long __priority;
  28. extern unsigned long __stack;
  29.  
  30. /* I must close a library after my child is running -
  31.  * and closing a library requires a working dispatcher (IMHO).
  32.  * Also semaphores are much smarter ;). Therefore:
  33.  */
  34. static struct SignalSemaphore *sem;
  35.  
  36. void __initdetach(void)
  37.   if(_WBenchMsg!=NULL)
  38.     return;
  39.  
  40.   if(sem!=NULL)           /* I must be the child process */
  41.   { 
  42.     ObtainSemaphore(sem); /* Assert that my parent is already dead */
  43.     ReleaseSemaphore(sem);
  44.     FreeMem(sem,sizeof(struct SignalSemaphore));
  45.     return;
  46.   }
  47.                           /* I must be the parent */
  48.   if((sem=(struct SignalSemaphore *)
  49.          AllocMem(sizeof(struct SignalSemaphore),MEMF_PUBLIC|MEMF_CLEAR))!=NULL)
  50.   { 
  51.     InitSemaphore(sem);
  52.     
  53.     if((DOSBase=(struct DosLibrary *)OpenLibrary(__dosname,37))!=NULL)
  54.     { 
  55.       struct CommandLineInterface *cli;
  56.       void *stack;
  57.  
  58.       cli=Cli();
  59.       
  60.       stack=__SaveSP;
  61.  
  62.       ObtainSemaphore(sem); /* Assert that my child is suspended until I'm finished */
  63.     
  64.         if(CreateNewProcTags(NP_Seglist,cli->cli_Module, /* child process gets my seglist */
  65.                              NP_FreeSeglist,1,           /* and must free it */
  66.                              NP_Cli,1,                   /* it must be a CLI process */
  67.                              NP_StackSize,__stack,       /* it gets a stack */
  68.                              NP_Name,(ULONG)__procname,  /* a name */
  69.                              NP_Priority,__priority,     /* a priority */
  70.                              NP_Arguments,(ULONG)__commandline,/* and my commandline Arguments */
  71.                              TAG_END)!=NULL)
  72.         { cli->cli_Module=0;            /* I'm no longer owner of this */
  73.           CloseLibrary((struct Library *)DOSBase);
  74.           DOSBase=NULL;
  75.  
  76.           /* Adjust stack, release semaphore and return 0 in one.
  77.            * Maybe the 3 movel are a bit too cautious, but they ARE working
  78.            */
  79.           asm("movel %0,sp;movel %1,a6;movel %2,a0;moveql #0,d0;jmp a6@(-570)"::
  80.               "r"(stack),"r"(SysBase),"r"(sem):"sp","a6","a0");
  81.         }
  82.  
  83.       ReleaseSemaphore(sem); /* Again only caution - you never know */
  84.  
  85.       CloseLibrary((struct Library *)DOSBase);
  86.     }
  87.     FreeMem(sem,sizeof(struct SignalSemaphore)); /* Couldn't start child :( */
  88.   }
  89.   exit(20);
  90. }
  91.   
  92. ADD2INIT(__initdetach,-70); /* A very high priority */
  93.