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