home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 103.lha / Spawn / x_main.c < prev   
C/C++ Source or Header  |  1986-11-21  |  5KB  |  196 lines

  1. /* x_main.c - self spawning startup code:
  2.  *   from CLI - spawns a new process and returns to CLI
  3.  *   from spawned process - runs normally except no stdio files opened
  4.  *   from Workbench - runs normally
  5.  */
  6.  
  7. /*    (notes from _main.c)
  8.  *    This is common startup code for both the CLI and the WorkBench.
  9.  *    When called from the WorkBench, argc is 0 and argv points to a
  10.  *    WBStartup type of structure.
  11.  */
  12. /* _main.c is Copyright (C) 1986,1987 by Manx Software Systems, Inc. */
  13.  
  14.  
  15. #include <fcntl.h>
  16. #include <exec/alerts.h>
  17. #include <exec/memory.h>
  18. #include <libraries/dosextens.h>
  19. #include <workbench/startup.h>
  20. #include <functions.h>
  21.  
  22.  
  23. /* some statics are given values (even if 0) to prevent them from being
  24.    placed into udata and zeroed by crt0 */
  25.  
  26. extern long _savsp, _stkbase;
  27.  
  28. extern int errno;
  29.  
  30. extern int _argc, _arg_len;
  31. extern char **_argv, *_arg_lin;
  32. extern struct WBStartup *WBenchMsg;
  33.  
  34. extern struct _dev *_devtab;
  35. extern short _numdev;
  36.  
  37. static long seg=0;
  38. static char clistart;
  39.  
  40. _main(alen, aptr)
  41. long alen;
  42. char *aptr;
  43. {
  44.     register struct Process *pp, *_FindTask();
  45.     void *_OpenLibrary(), *_GetMsg(), *_AllocMem();
  46.     long _Input(), _Output(), _Open();
  47.     static int t_argc=0, t_arg_len=0;
  48.     static char **t_argv=0, *t_arg_lin=0;
  49.     static BPTR t_cdir=0;
  50.  
  51.     if ((_devtab = _AllocMem(_numdev*(long)sizeof(struct _dev),
  52.                                                     MEMF_CLEAR)) == 0) {
  53.         Alert(AG_NoMemory, 0L);
  54. #asm
  55.         move.l    __savsp,sp        ;get back original stack pointer
  56.         rts                        ;and exit
  57. #endasm
  58.     }
  59.  
  60.     _devtab[0].mode = O_RDONLY;
  61.     _devtab[1].mode = _devtab[2].mode = O_WRONLY;
  62.  
  63.     _stkbase = _savsp - *((long *)_savsp+1) + 8;
  64.     *(long *)_stkbase = 0x4d414e58L;
  65.  
  66.     pp = _FindTask(0L);
  67.     if (pp->pr_CLI) {
  68.         struct CommandLineInterface *cli = (struct CommandLineInterface *) ((long)pp->pr_CLI << 2);
  69.         long *bcpl;
  70.         void *tmpdosbase;
  71.  
  72.         seg = cli->cli_Module;
  73.  
  74.         if ((tmpdosbase = OpenLibrary("dos.library", 33L)) == 0) {      /* v1.1 compatibility */
  75.             bcpl = (long *)*((long *)*((long *)*((long *)*((long *) _savsp+2)+1)-3)-3)+107;
  76.             if (seg != *bcpl) _exit (1);
  77.         }
  78.         else {
  79.             CloseLibrary(tmpdosbase);
  80.             bcpl = 0;
  81.         }
  82.  
  83.         /*      bcpl = (long *)*((long *)*((long *)*((long *)*((long *)pp->pr_ReturnAddr+1)+1)-3)-3)+106;   old stuff */
  84.  
  85.         _cli_parse(pp, alen, aptr);
  86.         _devtab[0].mode |= O_STDIO;        /* shouldn't close if CLI */
  87.         _devtab[1].mode |= O_STDIO;
  88.  
  89.         t_arg_lin = _arg_lin;
  90.         t_arg_len = _arg_len;
  91.         t_argv = _argv;
  92.         t_argc = _argc;
  93.         if (pp->pr_CurrentDir) t_cdir = DupLock (pp->pr_CurrentDir);
  94.         clistart = 1;
  95.  
  96.         _Forbid();        /* prevent starting new task until this one goes away (uses common data) */
  97.         if (CreateProc (_argv[0], 0L, seg, cli->cli_DefaultStack * 4)) {
  98.             _arg_lin = 0;        /* prevent freeing these */
  99.             if (bcpl) *bcpl = 0;
  100.             cli->cli_Module = 0;
  101.         }
  102.  
  103.         _exit(0);
  104.     }
  105.  
  106.     if (t_argc) {
  107.         _arg_lin = t_arg_lin;
  108.         _arg_len = t_arg_len;
  109.         _argc = t_argc;
  110.         _argv = t_argv;
  111.         _CurrentDir (t_cdir);
  112.     }
  113.     else {
  114.         _WaitPort(&pp->pr_MsgPort);
  115.         WBenchMsg = _GetMsg(&pp->pr_MsgPort);
  116.         if (WBenchMsg->sm_ArgList)
  117.             _CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  118.         _wb_parse(pp, WBenchMsg);
  119.         _argv = (char **)WBenchMsg;
  120.     }
  121.     _devtab[0].fd = _Input();
  122.     if (_devtab[1].fd = _Output())
  123.         _devtab[2].fd = _Open("*", MODE_OLDFILE);
  124.     main(_argc, _argv);
  125.     exit(0);
  126. }
  127.  
  128.  
  129. extern void *MathBase, *MathTransBase, *MathIeeeDoubBasBase;
  130. void (*_cln)();
  131.  
  132. _exit(code)
  133. {
  134.     long ret = code;
  135.     register int fd;
  136.  
  137.     if (_devtab) {
  138.         for (fd = 0 ; fd < _numdev ; fd++)
  139.             close(fd);
  140.         _FreeMem(_devtab, _numdev*(long)sizeof(struct _dev));
  141.     }
  142.     if (_cln)
  143.         (*_cln)();
  144.     if (MathTransBase)
  145.         _CloseLibrary(MathTransBase);
  146.     if (MathBase)
  147.         _CloseLibrary(MathBase);
  148.     if (MathIeeeDoubBasBase)
  149.         _CloseLibrary(MathIeeeDoubBasBase);
  150.     {
  151. #asm
  152.     mc68881
  153.     move.l    4,a6                ;get ExecBase
  154.     btst.b    #4,$129(a6)            ;check for 68881 flag in AttnFlags
  155.     beq        1$                    ;skip if not
  156.     move.l    a5,-(sp)
  157.     lea        2$,a5
  158.     jsr        -30(a6)             ;do it in supervisor mode
  159.     move.l    (sp)+,a5
  160.     bra        1$
  161. 2$
  162.     clr.l    -(sp)
  163.     frestore (sp)+                ;reset the ffp stuff
  164.     rte                            ;and return
  165. 1$
  166. #endasm
  167.     }
  168.     if (WBenchMsg == 0) {
  169.         if (_arg_lin) {
  170.             _FreeMem(_arg_lin, (long)_arg_len);
  171.             _FreeMem(_argv, (long)(_argc+1)*sizeof(*_argv));
  172.         }
  173.         if (!clistart) {
  174.             BPTR oldcdir = CurrentDir(NULL);
  175.  
  176.             if (oldcdir) UnLock(oldcdir);
  177.  
  178.             _Forbid();
  179.  
  180.             if (seg) UnLoadSeg (seg);
  181.         }
  182.     }
  183.     else {
  184.         _Forbid();
  185.         _ReplyMsg(WBenchMsg);
  186.     }
  187.     {
  188. #asm
  189.         move.l    -4(a5),d0        ;pick up return exit code
  190.         move.l    __savsp#,sp        ;get back original stack pointer
  191.         rts                        ;and exit
  192. #endasm
  193.     }
  194. }
  195.  
  196.