version 1.8, 1995/03/13 09:17:29
|
version 1.10, 1995/10/16 18:33:10
|
Line 15
|
Line 15
|
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <signal.h> |
#include <signal.h> |
|
#include <string.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#ifndef apollo |
#ifndef apollo |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
Line 570 long key_avail (stream)
|
Line 571 long key_avail (stream)
|
long chars_avail = pending; |
long chars_avail = pending; |
int result; |
int result; |
|
|
|
if(!terminal_prepped) prep_terminal(); |
|
|
#if defined (FIONREAD) |
#if defined (FIONREAD) |
result = ioctl (tty, FIONREAD, &chars_avail); |
result = ioctl (tty, FIONREAD, &chars_avail); |
#endif |
#endif |
Line 605 unsigned char getkey(stream)
|
Line 608 unsigned char getkey(stream)
|
int result; |
int result; |
unsigned char c; |
unsigned char c; |
|
|
|
if(!terminal_prepped) prep_terminal(); |
|
|
while (pending < 0) |
while (pending < 0) |
{ |
{ |
result = read (fileno (stream), &c, sizeof (char)); |
result = read (fileno (stream), &c, sizeof (char)); |
Line 615 unsigned char getkey(stream)
|
Line 620 unsigned char getkey(stream)
|
/* If zero characters are returned, then the file that we are |
/* If zero characters are returned, then the file that we are |
reading from is empty! Return EOF in that case. */ |
reading from is empty! Return EOF in that case. */ |
if (result == 0) |
if (result == 0) |
return (0); |
return CTRL('D'); |
|
|
/* If the error that we received was SIGINT, then try again, |
/* If the error that we received was SIGINT, then try again, |
this is simply an interrupted system call to read (). |
this is simply an interrupted system call to read (). |
Line 670 int main()
|
Line 675 int main()
|
} |
} |
#endif |
#endif |
|
|
/* signal handling taken from pfe by Dirk Zoller (Copylefted) - anton */ |
|
/* !! needs cleanup */ |
/* signal handling adapted from pfe by Dirk Zoller (Copylefted) - anton */ |
char * |
|
sigmsg (int sig) |
|
{ |
|
static char buf [25]; |
|
static char *msg [] = |
|
{ |
|
"Hangup", /* These strings are cited from */ |
|
"Interrupt", /* Rochkind: Advanced UNIX programming */ |
|
"Quit", |
|
"Illegal Instruction", |
|
"Trace Trap", |
|
"IOT instruction", |
|
"EMT instruction", |
|
"Floating point exception", |
|
"Kill", |
|
"Bus error", |
|
"Segmentation Violation", |
|
"Bad arg to system call", |
|
"Broken pipe", |
|
"Alarm clock", |
|
"Terminate signal", |
|
"User signal 1", |
|
"User signal 2", |
|
}; |
|
|
|
if ((unsigned)sig <= 17) |
|
return msg [sig - 1]; |
|
sprintf (buf, "signal %d received", sig); |
|
return buf; |
|
} |
|
|
|
static void |
static void |
graceful_exit (int sig) |
graceful_exit (int sig) |
{ |
{ |
deprep_terminal(); |
deprep_terminal(); |
if ((unsigned)sig <= 17) |
fprintf (stderr, "\n\n%s.\n", strsignal (sig)); |
fprintf (stderr, "\n\n%s.\n", sigmsg (sig)); |
|
else |
|
fprintf (stderr, "\n\nSignal %d received, terminated.\n", sig); |
|
exit (0x80|sig); |
exit (0x80|sig); |
} |
} |
|
|
Line 719 jmp_buf throw_jmp_buf;
|
Line 691 jmp_buf throw_jmp_buf;
|
static void |
static void |
signal_throw(int sig) |
signal_throw(int sig) |
{ |
{ |
static int throw_codes[] = { |
int code; |
-256, |
struct { |
-28, |
int signal; |
-257, |
int throwcode; |
-258, |
} *p, throwtable[] = { |
-259, |
{ SIGINT, -28 }, |
-260, |
{ SIGFPE, -55 }, |
-261, |
{ SIGBUS, -23 }, |
-55, |
{ SIGSEGV, -9 }, |
-262, |
|
-23, |
|
-9, |
|
-263, |
|
-264, |
|
-265, |
|
-266, |
|
-267, |
|
-268, |
|
}; |
}; |
signal(sig,signal_throw); |
signal(sig,signal_throw); |
longjmp(throw_jmp_buf,throw_codes[sig-1]); /* or use siglongjmp ? */ |
for (code=-256-sig, p=throwtable; p<throwtable+(sizeof(throwtable)/sizeof(*p)); p++) |
|
if (sig == p->signal) { |
|
code = p->throwcode; |
|
break; |
|
} |
|
longjmp(throw_jmp_buf,code); /* or use siglongjmp ? */ |
} |
} |
|
|
static void |
static void |
termprep (int sig) |
termprep (int sig) |
{ |
{ |
terminal_prepped=0; prep_terminal(); |
terminal_prepped=0; |
signal(sig,termprep); |
signal(sig,termprep); |
} |
} |
|
|
void |
void |
install_signal_handlers (void) |
install_signal_handlers (void) |
{ |
{ |
/* !! These definitions seem to be system dependent |
|
We could have them in the machine.h file, |
#if 0 |
but I would like something more automatic - anton */ |
/* these signals are handled right by default, no need to handle them; |
#define SIGS_TO_IGNORE SIGCHLD |
they are listed here just for fun */ |
#define SIGS_TO_ABORT SIGINT, SIGILL, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, \ |
static short sigs_to_default [] = { |
SIGALRM, SIGBUS |
#ifdef SIGCHLD |
#define SIGS_TO_QUIT SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, \ |
SIGCHLD, |
SIGTERM |
#endif |
#define SIGS_TO_TERMPREP SIGCONT |
#ifdef SIGINFO |
|
SIGINFO, |
static short sigs_to_ignore [] = { SIGS_TO_IGNORE }; |
#endif |
static short sigs_to_abort [] = { SIGS_TO_ABORT }; |
#ifdef SIGIO |
static short sigs_to_quit [] = { SIGS_TO_QUIT }; |
SIGIO, |
static short sigs_to_termprep [] = { SIGS_TO_TERMPREP }; |
#endif |
|
#ifdef SIGLOST |
|
SIGLOST, |
|
#endif |
|
#ifdef SIGKILL |
|
SIGKILL, |
|
#endif |
|
#ifdef SIGSTOP |
|
SIGSTOP, |
|
#endif |
|
#ifdef SIGPWR |
|
SIGPWR, |
|
#endif |
|
#ifdef SIGMSG |
|
SIGMSG, |
|
#endif |
|
#ifdef SIGDANGER |
|
SIGDANGER, |
|
#endif |
|
#ifdef SIGMIGRATE |
|
SIGMIGRATE, |
|
#endif |
|
#ifdef SIGPRE |
|
SIGPRE, |
|
#endif |
|
#ifdef SIGVIRT |
|
SIGVIRT, |
|
#endif |
|
#ifdef SIGGRANT |
|
SIGGRANT, |
|
#endif |
|
#ifdef SIGRETRACT |
|
SIGRETRACT, |
|
#endif |
|
#ifdef SIGSOUND |
|
SIGSOUND, |
|
#endif |
|
#ifdef SIGSAK |
|
SIGSAK, |
|
#endif |
|
#ifdef SIGTSTP |
|
SIGTSTP, |
|
#endif |
|
#ifdef SIGTTIN |
|
SIGTTIN, |
|
#endif |
|
#ifdef SIGTTOU |
|
SIGTTOU, |
|
#endif |
|
#ifdef SIGWINCH |
|
SIGWINCH, |
|
#endif |
|
#ifdef SIGSTKFLT |
|
SIGSTKFLT, |
|
#endif |
|
#ifdef SIGUNUSED |
|
SIGUNUSED, |
|
#endif |
|
}; |
|
#endif |
|
|
|
static short sigs_to_throw [] = { |
|
#ifdef SIGBREAK |
|
SIGBREAK, |
|
#endif |
|
#ifdef SIGINT |
|
SIGINT, |
|
#endif |
|
#ifdef SIGILL |
|
SIGILL, |
|
#endif |
|
#ifdef SIGEMT |
|
SIGEMT, |
|
#endif |
|
#ifdef SIGFPE |
|
SIGFPE, |
|
#endif |
|
#ifdef SIGIOT |
|
SIGIOT, |
|
#endif |
|
#ifdef SIGSEGV |
|
SIGSEGV, |
|
#endif |
|
#ifdef SIGALRM |
|
SIGALRM, |
|
#endif |
|
#ifdef SIGPOLL |
|
SIGPOLL, |
|
#endif |
|
#ifdef SIGPROF |
|
SIGPROF, |
|
#endif |
|
#ifdef SIGBUS |
|
SIGBUS, |
|
#endif |
|
#ifdef SIGSYS |
|
SIGSYS, |
|
#endif |
|
#ifdef SIGTRAP |
|
SIGTRAP, |
|
#endif |
|
#ifdef SIGURG |
|
SIGURG, |
|
#endif |
|
#ifdef SIGUSR1 |
|
SIGUSR1, |
|
#endif |
|
#ifdef SIGUSR2 |
|
SIGUSR2, |
|
#endif |
|
#ifdef SIGVTALRM |
|
SIGVTALRM, |
|
#endif |
|
#ifdef SIGXFSZ |
|
SIGXFSZ, |
|
#endif |
|
}; |
|
static short sigs_to_quit [] = { |
|
#ifdef SIGHUP |
|
SIGHUP, |
|
#endif |
|
#ifdef SIGQUIT |
|
SIGQUIT, |
|
#endif |
|
#ifdef SIGABRT |
|
SIGABRT, |
|
#endif |
|
#ifdef SIGPIPE |
|
SIGPIPE, |
|
#endif |
|
#ifdef SIGTERM |
|
SIGTERM, |
|
#endif |
|
#ifdef SIGXCPU |
|
SIGXCPU, |
|
#endif |
|
}; |
|
static short sigs_to_termprep [] = { |
|
#ifdef SIGCONT |
|
SIGCONT, |
|
#endif |
|
}; |
int i; |
int i; |
|
|
#define DIM(X) (sizeof (X) / sizeof *(X)) |
#define DIM(X) (sizeof (X) / sizeof *(X)) |
|
/* |
for (i = 0; i < DIM (sigs_to_ignore); i++) |
for (i = 0; i < DIM (sigs_to_ignore); i++) |
if (sigs_to_ignore [i]) |
signal (sigs_to_ignore [i], SIG_IGN); |
signal (sigs_to_ignore [i], SIG_IGN); |
*/ |
for (i = 0; i < DIM (sigs_to_abort); i++) |
for (i = 0; i < DIM (sigs_to_throw); i++) |
signal (sigs_to_abort [i], signal_throw); /* !! change to throw */ |
signal (sigs_to_throw [i], signal_throw); |
for (i = 0; i < DIM (sigs_to_quit); i++) |
for (i = 0; i < DIM (sigs_to_quit); i++) |
signal (sigs_to_quit [i], graceful_exit); |
signal (sigs_to_quit [i], graceful_exit); |
for (i = 0; i < DIM (sigs_to_termprep); i++) |
for (i = 0; i < DIM (sigs_to_termprep); i++) |