/* ** File: hey_signal.c ** Desc: Sets up signals for C version of hey ** Auth: Cian Synnott ** Date: Mon Nov 16 01:27:24 GMT 1998 */ #include #include #include #include "hey_signal.h" #include "aux.h" #include "config.h" /* Print out some haikus on certain signals - why not? ;o) ** the TERM & INT ones are mine; the SEGV one comes from a haiku_errors.txt ** of some sort; I believe it's under http://www.gnu.org/fun/ somewhere? */ RETSIGTYPE hey_signal_handler(int sig) { switch (sig) { case SIGTERM: printerr_exit(" \"to all men comes death\n" " a termination signal -\n" " this process must die\"\n"); case SIGSEGV: printerr_exit("\n \"wind catches lily\n" " scatt'ring petals o'er water -\n" " segmentation fault\"\n\n" " If you could, I'd appreciate you copying down the input\n" " that produced this fault and mailing it to me at\n" " pooka@redbrick.dcu.ie\n" " Thanks, if you try a slight variation on that input is should work.\n\n"); case SIGINT: printerr_exit("\n \"continuation\n" " is for this process a dream -\n" " interruption caught\"\n\n"); default: printerr_exit("Dodgy unwaited-for signal caught. Bailing out.\n"); } return; } /* Just setup all the signal handlers - ignore silly ones ... */ void hey_signal_setup(void) { sigset_t set; /* Start with a full set */ sigfillset(&set); /* Delete the ones we're interested in from it */ sigdelset(&set, SIGINT); sigdelset(&set, SIGSEGV); sigdelset(&set, SIGTERM); sigdelset(&set, SIGTSTP); /* Block all the signals remaining in the set */ sigprocmask(SIG_BLOCK, &set, NULL); /* Catch the others */ signal(SIGINT, hey_signal_handler); signal(SIGSEGV, hey_signal_handler); signal(SIGTERM, hey_signal_handler); return; } /* ** Functions & global for fiddling about with terminal settings ** Put them here because I'm really doing it as a signals problem, ** namely that ^S from the keyboard (easy to type instead of EOF, ^D) ** would suspend the process & wait for ^Q, which many people are ** unaware of. */ struct termios saved_term; /* The atexit() cleanup to put the terminal back in it's normal state. */ void hey_terminal_cleanup(void) { tcsetattr(STDIN_FILENO, TCSANOW, &saved_term); return; } /* The terminal setup routine - removes the possibility of using CTRL-S as ** SIGSTOP */ void hey_terminal_setup(void) { struct termios change; tcgetattr(STDIN_FILENO, &saved_term); memcpy(&change, &saved_term, sizeof(struct termios)); /* Change the ^Q & ^S keys to do nothing special... */ change.c_cc[VSTART] = 0; change.c_cc[VSTOP] = 0; tcsetattr(STDIN_FILENO, TCSANOW, &change); /* Register the cleanup routine that puts the terminal back ** in it's initial state ... */ if (atexit(hey_terminal_cleanup)) printerr_exit("hey: failed to register terminal atexit()\n"); return; }