/* * SIGNAL.C A program to allow processes created by RUN EXECUTE to * signal their parent processes (to indicate that they have * completed their tasks, or are ready to start, etc). * * Used in conjunction with WAITFOR.C * * Copyright (c) 1989 by Davide P. Cervone, all rights reserved. */ #include #include #include #include #define MAXCOUNT 10 /* Number of times to try to find port */ #define COUNTWAIT 100 /* Ticks to wait between tries */ #define ERROR_NONE 0 /* Normal exit status */ #define ERROR_CANCELLED 10 /* User pressed CTRL-C to cancel */ #define ERROR_BADPORTNAME 11 /* No port name on command line */ #define ERROR_PORTNOTFOUND 12 /* Specified port not found */ #define SIGBREAKF_ANY\ (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F) /* * DoExit() * * General purpose exit routine. In this case, since there's nothing * special that needs to be cleaned up, just call _exit() with the * proper return status. EXECUTE files will report the error codes, * but interactive users will get no message */ #define DoExit(status) _exit(status) extern struct MsgPort *FindPort(); extern long SetSignal(); /* * CheckForCTRLC() * * Checks to see if CTRL-C (or D,E or F) have been pressed. */ static int CheckForCTRLC() { long theSignals; theSignals = SetSignal(0L,0L); return(theSignals & SIGBREAKF_ANY); } /* * _main() * * Replaces the standard Lattice _main routine (since no IO is performed * we don't nee the usual overhead). _main expects the command line * (as entered by the user, including with the program) to be on the * stack as its PortName argument. * * First clear the DOS signals, in case any are set from before. * Check that the port name exists, and skip over the command name * in the command line, and any leading blanks. The port name will * be whatever remains on the command line, including blanks and * special characters. * * Next, look for the specified port. If it is not found, increment * count and wait a few seconds before trying again. Only try as MAXCOUNT * times, and error exit if the port can't be found in that many tries. * * If the port was found, signal the task. Note that no actual message * is passed. The message port simply acts as a convenient holding place * for the signal and the name of the port. The waiting process simply * removes the port when it receives the signal. * */ void _main(PortName) char *PortName; { struct MsgPort *thePort = NULL; int count; SetSignal(0L,SIGBREAKF_ANY); if (PortName == NULL) DoExit(ERROR_BADPORTNAME); while (*PortName != '\0' && *PortName != ' ') PortName++; if (*PortName == '\0' || *PortName == '\n') DoExit(ERROR_BADPORTNAME); while (*(++PortName) == ' '); for (count=0; count < MAXCOUNT && thePort == NULL; count++) { thePort = FindPort(PortName); if (thePort == NULL) { Delay(COUNTWAIT); if (CheckForCTRLC()) DoExit(ERROR_CANCELLED); } } if (thePort == NULL) DoExit(ERROR_PORTNOTFOUND); Signal(thePort->mp_SigTask,(1<mp_SigBit)); DoExit(ERROR_NONE); }