160786Sps/* 2240121Sdelphij * Copyright (C) 1984-2012 Mark Nudelman 360786Sps * 460786Sps * You may distribute under the terms of either the GNU General Public 560786Sps * License or the Less License, as specified in the README file. 660786Sps * 7240121Sdelphij * For more information, see the README file. 860786Sps */ 960786Sps 1063120Sps/* $FreeBSD$ */ 1160786Sps 1260786Sps/* 1360786Sps * Routines dealing with signals. 1460786Sps * 1560786Sps * A signal usually merely causes a bit to be set in the "signals" word. 1660786Sps * At some convenient time, the mainline code checks to see if any 1760786Sps * signals need processing by calling psignal(). 1860786Sps * If we happen to be reading from a file [in iread()] at the time 1960786Sps * the signal is received, we call intread to interrupt the iread. 2060786Sps */ 2160786Sps 2260786Sps#include "less.h" 2360786Sps#include <signal.h> 2460786Sps 2560786Sps/* 2660786Sps * "sigs" contains bits indicating signals which need to be processed. 2760786Sps */ 2860786Spspublic int sigs; 2960786Sps 3060786Spsextern int sc_width, sc_height; 3160786Spsextern int screen_trashed; 3260786Spsextern int lnloop; 3360786Spsextern int linenums; 3460786Spsextern int wscroll; 3560786Spsextern int reading; 36161478Sdelphijextern int quit_on_intr; 37170259Sdelphijextern int less_is_more; 38170259Sdelphijextern long jump_sline_fraction; 3960786Sps 4060786Sps/* 4160786Sps * Interrupt signal handler. 4260786Sps */ 4360786Sps /* ARGSUSED*/ 4460786Sps static RETSIGTYPE 4560786Spsu_interrupt(type) 4660786Sps int type; 4760786Sps{ 48191930Sdelphij bell(); 4960786Sps#if OS2 5060786Sps LSIGNAL(SIGINT, SIG_ACK); 5160786Sps#endif 5260786Sps LSIGNAL(SIGINT, u_interrupt); 5360786Sps sigs |= S_INTERRUPT; 5460786Sps#if MSDOS_COMPILER==DJGPPC 5560786Sps /* 5660786Sps * If a keyboard has been hit, it must be Ctrl-C 5760786Sps * (as opposed to Ctrl-Break), so consume it. 5860786Sps * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.) 5960786Sps */ 6060786Sps if (kbhit()) 6160786Sps getkey(); 6260786Sps#endif 63170259Sdelphij if (less_is_more) 6463120Sps quit(0); 6560786Sps if (reading) 66191930Sdelphij intread(); /* May longjmp */ 6760786Sps} 6860786Sps 6960786Sps#ifdef SIGTSTP 7060786Sps/* 7160786Sps * "Stop" (^Z) signal handler. 7260786Sps */ 7360786Sps /* ARGSUSED*/ 7460786Sps static RETSIGTYPE 7560786Spsstop(type) 7660786Sps int type; 7760786Sps{ 7860786Sps LSIGNAL(SIGTSTP, stop); 7960786Sps sigs |= S_STOP; 8060786Sps if (reading) 8160786Sps intread(); 8260786Sps} 8360786Sps#endif 8460786Sps 8560786Sps#ifdef SIGWINCH 8660786Sps/* 8760786Sps * "Window" change handler 8860786Sps */ 8960786Sps /* ARGSUSED*/ 9060786Sps public RETSIGTYPE 9160786Spswinch(type) 9260786Sps int type; 9360786Sps{ 9460786Sps LSIGNAL(SIGWINCH, winch); 9560786Sps sigs |= S_WINCH; 96172471Sdelphij if (reading) 97172471Sdelphij intread(); 9860786Sps} 9960786Sps#else 10060786Sps#ifdef SIGWIND 10160786Sps/* 10260786Sps * "Window" change handler 10360786Sps */ 10460786Sps /* ARGSUSED*/ 10560786Sps public RETSIGTYPE 10660786Spswinch(type) 10760786Sps int type; 10860786Sps{ 10960786Sps LSIGNAL(SIGWIND, winch); 11060786Sps sigs |= S_WINCH; 11160786Sps if (reading) 11260786Sps intread(); 11360786Sps} 11460786Sps#endif 11560786Sps#endif 11660786Sps 11760786Sps#if MSDOS_COMPILER==WIN32C 11860786Sps/* 11960786Sps * Handle CTRL-C and CTRL-BREAK keys. 12060786Sps */ 12160786Sps#include "windows.h" 12260786Sps 12360786Sps static BOOL WINAPI 12460786Spswbreak_handler(dwCtrlType) 12560786Sps DWORD dwCtrlType; 12660786Sps{ 12760786Sps switch (dwCtrlType) 12860786Sps { 12960786Sps case CTRL_C_EVENT: 13060786Sps case CTRL_BREAK_EVENT: 13160786Sps sigs |= S_INTERRUPT; 13260786Sps return (TRUE); 13360786Sps default: 13460786Sps break; 13560786Sps } 13660786Sps return (FALSE); 13760786Sps} 13860786Sps#endif 13960786Sps 14060786Sps/* 14160786Sps * Set up the signal handlers. 14260786Sps */ 14360786Sps public void 14460786Spsinit_signals(on) 14560786Sps int on; 14660786Sps{ 14760786Sps if (on) 14860786Sps { 14960786Sps /* 15060786Sps * Set signal handlers. 15160786Sps */ 15260786Sps (void) LSIGNAL(SIGINT, u_interrupt); 15360786Sps#if MSDOS_COMPILER==WIN32C 15460786Sps SetConsoleCtrlHandler(wbreak_handler, TRUE); 15560786Sps#endif 15660786Sps#ifdef SIGTSTP 15760786Sps (void) LSIGNAL(SIGTSTP, stop); 15860786Sps#endif 15960786Sps#ifdef SIGWINCH 16060786Sps (void) LSIGNAL(SIGWINCH, winch); 161170259Sdelphij#endif 16260786Sps#ifdef SIGWIND 16360786Sps (void) LSIGNAL(SIGWIND, winch); 16460786Sps#endif 16560786Sps#ifdef SIGQUIT 16660786Sps (void) LSIGNAL(SIGQUIT, SIG_IGN); 16760786Sps#endif 16860786Sps } else 16960786Sps { 17060786Sps /* 17160786Sps * Restore signals to defaults. 17260786Sps */ 17360786Sps (void) LSIGNAL(SIGINT, SIG_DFL); 17460786Sps#if MSDOS_COMPILER==WIN32C 17560786Sps SetConsoleCtrlHandler(wbreak_handler, FALSE); 17660786Sps#endif 17760786Sps#ifdef SIGTSTP 17860786Sps (void) LSIGNAL(SIGTSTP, SIG_DFL); 17960786Sps#endif 18060786Sps#ifdef SIGWINCH 18160786Sps (void) LSIGNAL(SIGWINCH, SIG_IGN); 18260786Sps#endif 18360786Sps#ifdef SIGWIND 18460786Sps (void) LSIGNAL(SIGWIND, SIG_IGN); 18560786Sps#endif 18660786Sps#ifdef SIGQUIT 18760786Sps (void) LSIGNAL(SIGQUIT, SIG_DFL); 18860786Sps#endif 18960786Sps } 19060786Sps} 19160786Sps 19260786Sps/* 19360786Sps * Process any signals we have received. 19460786Sps * A received signal cause a bit to be set in "sigs". 19560786Sps */ 19660786Sps public void 19760786Spspsignals() 19860786Sps{ 19960786Sps register int tsignals; 20060786Sps 20160786Sps if ((tsignals = sigs) == 0) 20260786Sps return; 20360786Sps sigs = 0; 20460786Sps 20560786Sps#ifdef SIGTSTP 20660786Sps if (tsignals & S_STOP) 20760786Sps { 20860786Sps /* 20960786Sps * Clean up the terminal. 21060786Sps */ 21160786Sps#ifdef SIGTTOU 21260786Sps LSIGNAL(SIGTTOU, SIG_IGN); 21360786Sps#endif 21460786Sps clear_bot(); 21560786Sps deinit(); 21660786Sps flush(); 21760786Sps raw_mode(0); 21860786Sps#ifdef SIGTTOU 21960786Sps LSIGNAL(SIGTTOU, SIG_DFL); 22060786Sps#endif 22160786Sps LSIGNAL(SIGTSTP, SIG_DFL); 22260786Sps kill(getpid(), SIGTSTP); 22360786Sps /* 22460786Sps * ... Bye bye. ... 22560786Sps * Hopefully we'll be back later and resume here... 22660786Sps * Reset the terminal and arrange to repaint the 22760786Sps * screen when we get back to the main command loop. 22860786Sps */ 22960786Sps LSIGNAL(SIGTSTP, stop); 23060786Sps raw_mode(1); 23160786Sps init(); 23260786Sps screen_trashed = 1; 23360786Sps tsignals |= S_WINCH; 23460786Sps } 23560786Sps#endif 23660786Sps#ifdef S_WINCH 23760786Sps if (tsignals & S_WINCH) 23860786Sps { 23960786Sps int old_width, old_height; 24060786Sps /* 24160786Sps * Re-execute scrsize() to read the new window size. 24260786Sps */ 24360786Sps old_width = sc_width; 24460786Sps old_height = sc_height; 24560786Sps get_term(); 24660786Sps if (sc_width != old_width || sc_height != old_height) 24760786Sps { 24860786Sps wscroll = (sc_height + 1) / 2; 249170259Sdelphij calc_jump_sline(); 250195941Sdelphij calc_shift_count(); 25160786Sps screen_trashed = 1; 25260786Sps } 25360786Sps } 25460786Sps#endif 25560786Sps if (tsignals & S_INTERRUPT) 25660786Sps { 257161478Sdelphij if (quit_on_intr) 258221715Sdelphij quit(QUIT_INTERRUPT); 25960786Sps } 26060786Sps} 261