home *** CD-ROM | disk | FTP | other *** search
- /* x_main.c - self spawning startup code:
- * from CLI - spawns a new process and returns to CLI
- * from spawned process - runs normally except no stdio files opened
- * from Workbench - runs normally
- */
-
- /* (notes from _main.c)
- * This is common startup code for both the CLI and the WorkBench.
- * When called from the WorkBench, argc is 0 and argv points to a
- * WBStartup type of structure.
- */
- /* _main.c is Copyright (C) 1986,1987 by Manx Software Systems, Inc. */
-
-
- #include <fcntl.h>
- #include <exec/alerts.h>
- #include <exec/memory.h>
- #include <libraries/dosextens.h>
- #include <workbench/startup.h>
- #include <functions.h>
-
-
- /* some statics are given values (even if 0) to prevent them from being
- placed into udata and zeroed by crt0 */
-
- extern long _savsp, _stkbase;
-
- extern int errno;
-
- extern int _argc, _arg_len;
- extern char **_argv, *_arg_lin;
- extern struct WBStartup *WBenchMsg;
-
- extern struct _dev *_devtab;
- extern short _numdev;
-
- static long seg=0;
- static char clistart;
-
- _main(alen, aptr)
- long alen;
- char *aptr;
- {
- register struct Process *pp, *_FindTask();
- void *_OpenLibrary(), *_GetMsg(), *_AllocMem();
- long _Input(), _Output(), _Open();
- static int t_argc=0, t_arg_len=0;
- static char **t_argv=0, *t_arg_lin=0;
- static BPTR t_cdir=0;
-
- if ((_devtab = _AllocMem(_numdev*(long)sizeof(struct _dev),
- MEMF_CLEAR)) == 0) {
- Alert(AG_NoMemory, 0L);
- #asm
- move.l __savsp,sp ;get back original stack pointer
- rts ;and exit
- #endasm
- }
-
- _devtab[0].mode = O_RDONLY;
- _devtab[1].mode = _devtab[2].mode = O_WRONLY;
-
- _stkbase = _savsp - *((long *)_savsp+1) + 8;
- *(long *)_stkbase = 0x4d414e58L;
-
- pp = _FindTask(0L);
- if (pp->pr_CLI) {
- struct CommandLineInterface *cli = (struct CommandLineInterface *) ((long)pp->pr_CLI << 2);
- long *bcpl;
- void *tmpdosbase;
-
- seg = cli->cli_Module;
-
- if ((tmpdosbase = OpenLibrary("dos.library", 33L)) == 0) { /* v1.1 compatibility */
- bcpl = (long *)*((long *)*((long *)*((long *)*((long *) _savsp+2)+1)-3)-3)+107;
- if (seg != *bcpl) _exit (1);
- }
- else {
- CloseLibrary(tmpdosbase);
- bcpl = 0;
- }
-
- /* bcpl = (long *)*((long *)*((long *)*((long *)*((long *)pp->pr_ReturnAddr+1)+1)-3)-3)+106; old stuff */
-
- _cli_parse(pp, alen, aptr);
- _devtab[0].mode |= O_STDIO; /* shouldn't close if CLI */
- _devtab[1].mode |= O_STDIO;
-
- t_arg_lin = _arg_lin;
- t_arg_len = _arg_len;
- t_argv = _argv;
- t_argc = _argc;
- if (pp->pr_CurrentDir) t_cdir = DupLock (pp->pr_CurrentDir);
- clistart = 1;
-
- _Forbid(); /* prevent starting new task until this one goes away (uses common data) */
- if (CreateProc (_argv[0], 0L, seg, cli->cli_DefaultStack * 4)) {
- _arg_lin = 0; /* prevent freeing these */
- if (bcpl) *bcpl = 0;
- cli->cli_Module = 0;
- }
-
- _exit(0);
- }
-
- if (t_argc) {
- _arg_lin = t_arg_lin;
- _arg_len = t_arg_len;
- _argc = t_argc;
- _argv = t_argv;
- _CurrentDir (t_cdir);
- }
- else {
- _WaitPort(&pp->pr_MsgPort);
- WBenchMsg = _GetMsg(&pp->pr_MsgPort);
- if (WBenchMsg->sm_ArgList)
- _CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
- _wb_parse(pp, WBenchMsg);
- _argv = (char **)WBenchMsg;
- }
- _devtab[0].fd = _Input();
- if (_devtab[1].fd = _Output())
- _devtab[2].fd = _Open("*", MODE_OLDFILE);
- main(_argc, _argv);
- exit(0);
- }
-
-
- extern void *MathBase, *MathTransBase, *MathIeeeDoubBasBase;
- void (*_cln)();
-
- _exit(code)
- {
- long ret = code;
- register int fd;
-
- if (_devtab) {
- for (fd = 0 ; fd < _numdev ; fd++)
- close(fd);
- _FreeMem(_devtab, _numdev*(long)sizeof(struct _dev));
- }
- if (_cln)
- (*_cln)();
- if (MathTransBase)
- _CloseLibrary(MathTransBase);
- if (MathBase)
- _CloseLibrary(MathBase);
- if (MathIeeeDoubBasBase)
- _CloseLibrary(MathIeeeDoubBasBase);
- {
- #asm
- mc68881
- move.l 4,a6 ;get ExecBase
- btst.b #4,$129(a6) ;check for 68881 flag in AttnFlags
- beq 1$ ;skip if not
- move.l a5,-(sp)
- lea 2$,a5
- jsr -30(a6) ;do it in supervisor mode
- move.l (sp)+,a5
- bra 1$
- 2$
- clr.l -(sp)
- frestore (sp)+ ;reset the ffp stuff
- rte ;and return
- 1$
- #endasm
- }
- if (WBenchMsg == 0) {
- if (_arg_lin) {
- _FreeMem(_arg_lin, (long)_arg_len);
- _FreeMem(_argv, (long)(_argc+1)*sizeof(*_argv));
- }
- if (!clistart) {
- BPTR oldcdir = CurrentDir(NULL);
-
- if (oldcdir) UnLock(oldcdir);
-
- _Forbid();
-
- if (seg) UnLoadSeg (seg);
- }
- }
- else {
- _Forbid();
- _ReplyMsg(WBenchMsg);
- }
- {
- #asm
- move.l -4(a5),d0 ;pick up return exit code
- move.l __savsp#,sp ;get back original stack pointer
- rts ;and exit
- #endasm
- }
- }
-
-