/* * To obey the protocol, we must use NP_ExitCode to set up code that clears * the proc pointer, indicating that we ain't got a blanker any more. * In addition, This code sends a CTRL-C signal to the utility, so that it * will exit, so we need a pointer to our task. Finally, proc must be * protected by a semaphore, so that's out here as well. * * Copyright 1991, Mike Meyer * All Rights Reserved * * See the file "ShadowMaster:Distribution" for information on distribution. */ static struct Process *proc = NULL ; static struct Task *me = NULL ; static struct SignalSemaphore guard ; #ifdef LOOPS #include #include struct IntuitionBase *IntuitionBase ; #endif #define FIRST 1 #define REST 2 #define CLEANUP 3 /* * This is the starting point. It sets up the world, and calls your * utility routine (doutility()), then cleans up after itself when you * return. Nothing in here should need changing. * * This gets included into the utility file at the appropriate place. */ #define done(x) do { status = x; goto out; } while (0) ; int __saveds start(void) { int status = RETURN_OK ; #ifdef LOOPS struct Screen *screen = NULL ; static struct ColorSpec colors[] = {{0, 0, 0, 0}, {1, 0, 0, 0}, {-1} } ; static struct TagItem screen_tags[] = { {SA_Depth, 1}, {SA_DisplayID, LORES_KEY}, {SA_Quiet, TRUE}, {SA_Colors, &colors}, {TAG_END, 0} } ; #endif #ifdef TEMPLATE struct RDArgs *args = NULL ; #endif int tripno = FIRST ; proctags[0].ti_Data = 0 ; SysBase = *((struct ExecBase **) 4); if ((DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37)) == NULL) done(RETURN_FAIL) ; #ifdef LOOPS if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)) == NULL) done(RETURN_FAIL) ; #endif InitSemaphore(&guard) ; me = FindTask(0L) ; /* Do the magic that you do so well */ #ifdef TEMPLATE if ((args = ReadArgs(TEMPLATE, opts, NULL)) == NULL) done(RETURN_ERROR) ; #endif /* Let's get the show on the road... */ #ifdef LOOPS for (;;) { #endif proctags[1].ti_Data = (long) doutility(tripno) ; #ifdef LOOPS if (tripno != FIRST && proctags[1].ti_Data) screen = OpenScreenTagList(NULL, screen_tags) ; ObtainSemaphore(&guard) ; while (proc) { Signal((struct Task *) proc, SIGBREAKF_CTRL_C) ; ReleaseSemaphore(&guard) ; Wait(SIGBREAKF_CTRL_C) ; /* From procend */ ObtainSemaphore(&guard) ; } ReleaseSemaphore(&guard) ; #endif if (proctags[1].ti_Data == NULL || ((proctags[0].ti_Data = (long) LoadSeg((char *) proctags[1].ti_Data)) == NULL) /* At this point, proc isn't running, so we don't need a guard... */ || ((proc = CreateNewProc(proctags)) == NULL)) { #ifdef LOOPS doutility(CLEANUP) ; /* So they can clean up */ #endif done(RETURN_FAIL) ; } proctags[0].ti_Data = NULL ; /* The process will unload itself */ #ifdef LOOPS if (screen) { Delay(1) ; /* Force a task switch */ CloseScreen(screen) ; } screen = NULL ; tripno = REST ; } #else Wait(SIGBREAKF_CTRL_C) ; /* Someone says die */ ObtainSemaphore(&guard) ; while (proc) { Signal((struct Task *) proc, SIGBREAKF_CTRL_C) ; ReleaseSemaphore(&guard) ; Wait(SIGBREAKF_CTRL_C) ; /* From procend */ ObtainSemaphore(&guard) ; } ReleaseSemaphore(&guard) ; #endif /* Here's how we exit this mess */ out: if (proctags[0].ti_Data) UnLoadSeg(proctags[1].ti_Data) ; #ifdef LOOPS if (screen) CloseScreen(screen) ; #endif #ifdef TEMPLATE if (args) FreeArgs(args) ; #endif if (DOSBase) CloseLibrary((struct Library *) DOSBase) ; return status ; } /* Make sure we don't screw up any following code... */ #undef done /* The routine that ends all procs */ static void __saveds procend(void) { ObtainSemaphore(&guard) ; proc = NULL ; Signal(me, SIGBREAKF_CTRL_C) ; ReleaseSemaphore(&guard) ; }