/************************************************************* * File: lib/signal.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 971007 This has a prob because longjmp will xfer to inactive * context. It does work, but it also crashes (sometimes). */ #include #include #include /* * This is a somewhat skeletal implementation of signal, it is * only intended to make the porting of benchmarks to the * LR33000 a little more straightforward. */ #ifdef TEST /*-------------------------------------------------------------*/ main() { char buf[100]; int gotsig(); if (signal(SIGINT,gotsig) == -1) { printf("signal: Bad return code\n"); exit(-1); } setjmp(sjbuf); printf("Waiting for signal.\n"); for (;;) { printf("> "); gets(buf); if (buf[0] == '.') break; printf("%s\n",buf); } } gotsig() { printf("Got a signal\n"); if (signal(SIGINT,gotsig) == -1) { printf("signal: Bad return code\n"); exit(-1); } longjmp(sjbuf,0); } #endif /*-------------------------------------------------------------*/ vFunc *signal(op,func) int op; vFunc *func; { static vFunc *sigintfunc,*savedintr; static jmp_buf sigintbuf; vFunc *tmp; if (op == SIGINT) { if (func == SIG_IGN) { /* ignore the SIGINT */ ioctl(STDIN,GETINTR,&savedintr); ioctl(STDIN,SETINTR,0); /* ignore */ return(savedintr); } else if (func == SIG_DFL) { if (!savedintr) return(SIG_ERR); ioctl(STDIN,GETINTR,&tmp); ioctl(STDIN,SETINTR,savedintr); return(tmp); } else { ioctl(STDIN,GETINTR,&savedintr); sigintfunc = func; if (setjmp(sigintbuf)) { /* when INTR occurs */ ioctl(STDIN,SETINTR,savedintr); (*sigintfunc)(); } else { /* when signal was called */ ioctl(STDIN,SETINTR,sigintbuf); return(0); } } } errno = EINVAL; return((vFunc *)-1); }