home *** CD-ROM | disk | FTP | other *** search
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* |_o_o|\\ Copyright (c) 1988 The Software Distillery. All Rights Reserved */
- /* |. o.| || This program may not be distributed without the permission of */
- /* | . | || the authors. */
- /* | o | || Dave Baker Ed Burnette Stan Chow Jay Denebeim */
- /* | . |// Gordon Keener Jack Rouse John Toebes Doug Walker */
- /* ====== BBS:(919)-471-6436 VOICE:(919)-469-4210 */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /* C version of a new cback.a for PopCLI */
- /* This code should be put in the throwaway segment. It will clone the */
- /* second segment of this process into an independent seglist, and do */
- /* a CreateProc for it. */
-
- #include <exec/types.h>
- #include <exec/alerts.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/ports.h>
- #include <exec/libraries.h>
- #include <exec/tasks.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <workbench/startup.h>
- #include <string.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include "cback.h"
-
- /* Constants for the new process: */
- #define PROCNAME "PopCLI IV"
- #define STACKSIZE 4096
- #define PRIORITY 20
-
- struct Segment {
- ULONG sm_len;
- BPTR sm_next;
- };
-
- /* Get a Task pointer from the MsgPort pointer returned by CreateProc */
- #define GETTASK(m) (((struct Task *)m)-1)
-
- void __far _main(void);
-
- void __asm start(register __a0 char *cmd, register __d0 char *cmdlen)
- {
- struct DosLibrary *DOSBase;
- struct Process *us;
- struct MemList memlist, *ml;
- struct Segment *segment;
- char *newseg;
- struct cbackstr *msg;
- BPTR cwd;
- int sig;
- struct MsgPort *procmsg;
- struct WBStartup *wbmsg;
- BPTR stdin;
-
- DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
-
- us = (struct Process *)FindTask(0);
-
- msg = AllocMem( sizeof(struct cbackstr),
- MEMF_PUBLIC|MEMF_CLEAR );
-
- msg->msgpart.mn_Length = sizeof(struct cbackstr);
-
- cwd = us->pr_CurrentDir;
- if (us->pr_CLI)
- {
- /* Run from CLI. We need to duplicate the lock for the */
- /* current working directory. */
- cwd = DupLock(cwd);
-
- /* Find the _main()'s segment. We need to clone it */
- /* KLUDGE WARNING: to find _main's segment, back up 8 */
- /* bytes from the address of _main. */
- segment = (struct Segment *) (((char *)_main)-8);
-
- memlist.ml_NumEntries = 1;
- memlist.ml_ME[0].me_Reqs = MEMF_PUBLIC;
- memlist.ml_ME[0].me_Length = segment->sm_len;
-
- ml = AllocEntry( &memlist );
- newseg = (char *) ml->ml_ME[0].me_Addr;
-
- memcpy( newseg, (char *)(&(segment->sm_next)),
- segment->sm_len );
- *((long *)newseg) = 0;
-
- /* set up the message fields we now need */
- msg->stdout = Open("*", MODE_OLDFILE);
- msg->SyncProcess = us;
- msg->SyncSignal = sig = AllocSignal(-1);
- msg->cmd = cmd;
- msg->cmdlen = cmdlen;
-
- /* Start up the new proc */
- Forbid();
- procmsg = CreateProc(
- PROCNAME,
- PRIORITY,
- (BPTR)((ULONG)newseg>>2),
- STACKSIZE
- );
- if (procmsg)
- {
- AddTail( &(GETTASK(procmsg)->tc_MemEntry),
- (struct Node *)ml );
- }
- Permit();
-
- /* Let 'em go, but wait until they let us go */
- if (procmsg && sig >= 0)
- {
- PutMsg( procmsg, (struct Message *)msg );
- Wait(1<<sig);
- }
- }
- else
- {
- /* We're a WorkBench process. Don't fork, but get the */
- /* workbench message and use stuff from it. */
- WaitPort( &us->pr_MsgPort );
- wbmsg = (struct WBStartup *)GetMsg( &us->pr_MsgPort );
- cwd = CurrentDir( wbmsg->sm_ArgList->wa_Lock );
-
- /* Stuff to get cmdline & stuff */
-
- stdin = Open( wbmsg->sm_ToolWindow, MODE_OLDFILE );
-
- /* Send ourselves the message, since we're going to be */
- /* waiting for it */
- PutMsg( &us->pr_MsgPort, (struct Message *)msg );
-
- /* Call the main routine */
- _main();
-
- Close(stdin);
- /* Forbid(); is this really necessary???? */
- ReplyMsg((struct Message *)wbmsg);
- }
-
- UnLock(cwd);
- CloseLibrary((struct Library *)DOSBase);
- }
-
-