home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / texinfo-3.7-src.tgz / tar.out / fsf / texinfo / info / signals.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  174 lines

  1. /* signals.c -- Install and maintain Info signal handlers. */
  2.  
  3. /* This file is part of GNU Info, a program for reading online documentation
  4.    stored in Info format.
  5.  
  6.    Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
  7.  
  8.    This program is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2, or (at your option)
  11.    any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21.  
  22.    Written by Brian Fox (bfox@ai.mit.edu). */
  23.  
  24. #include "info.h"
  25. #include "signals.h"
  26.  
  27. /* **************************************************************** */
  28. /*                                    */
  29. /*        Pretending That We Have POSIX Signals            */
  30. /*                                    */
  31. /* **************************************************************** */
  32.  
  33. #if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK)
  34. /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
  35. static void
  36. sigprocmask (operation, newset, oldset)
  37.      int operation, *newset, *oldset;
  38. {
  39.   switch (operation)
  40.     {
  41.     case SIG_UNBLOCK:
  42.       sigsetmask (sigblock (0) & ~(*newset));
  43.       break;
  44.  
  45.     case SIG_BLOCK:
  46.       *oldset = sigblock (*newset);
  47.       break;
  48.  
  49.     case SIG_SETMASK:
  50.       sigsetmask (*newset);
  51.       break;
  52.  
  53.     default:
  54.       abort ();
  55.     }
  56. }
  57. #endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */
  58.  
  59. /* **************************************************************** */
  60. /*                                    */
  61. /*            Signal Handling for Info                */
  62. /*                                    */
  63. /* **************************************************************** */
  64.  
  65. typedef void SigHandlerType;
  66. typedef SigHandlerType SigHandler ();
  67.  
  68. static SigHandlerType info_signal_handler ();
  69. static SigHandler *old_TSTP, *old_TTOU, *old_TTIN;
  70. static SigHandler *old_WINCH, *old_INT;
  71.  
  72. void
  73. initialize_info_signal_handler ()
  74. {
  75. #if defined (SIGTSTP)
  76.   old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler);
  77.   old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler);
  78.   old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler);
  79. #endif /* SIGTSTP */
  80.  
  81. #if defined (SIGWINCH)
  82.   old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler);
  83. #endif
  84.  
  85. #if defined (SIGINT)
  86.   old_INT = (SigHandler *) signal (SIGINT, info_signal_handler);
  87. #endif
  88. }
  89.  
  90. static void
  91. redisplay_after_signal ()
  92. {
  93.   terminal_clear_screen ();
  94.   display_clear_display (the_display);
  95.   window_mark_chain (windows, W_UpdateWindow);
  96.   display_update_display (windows);
  97.   display_cursor_at_point (active_window);
  98.   fflush (stdout);
  99. }
  100.  
  101. static SigHandlerType
  102. info_signal_handler (sig)
  103.      int sig;
  104. {
  105.   SigHandler **old_signal_handler;
  106.  
  107.   switch (sig)
  108.     {
  109. #if defined (SIGTSTP)
  110.     case SIGTSTP:
  111.     case SIGTTOU:
  112.     case SIGTTIN:
  113. #endif
  114. #if defined (SIGINT)
  115.     case SIGINT:
  116. #endif
  117.       {
  118. #if defined (SIGTSTP)
  119.     if (sig == SIGTSTP)
  120.       old_signal_handler = &old_TSTP;
  121.     if (sig == SIGTTOU)
  122.       old_signal_handler = &old_TTOU;
  123.     if (sig == SIGTTIN)
  124.       old_signal_handler = &old_TTIN;
  125. #endif /* SIGTSTP */
  126.     if (sig == SIGINT)
  127.       old_signal_handler = &old_INT;
  128.  
  129.     /* For stop signals, restore the terminal IO, leave the cursor
  130.        at the bottom of the window, and stop us. */
  131.     terminal_goto_xy (0, screenheight - 1);
  132.     terminal_clear_to_eol ();
  133.     fflush (stdout);
  134.     terminal_unprep_terminal ();
  135.     signal (sig, *old_signal_handler);
  136.      UNBLOCK_SIGNAL (sig);
  137.     kill (getpid (), sig);
  138.  
  139.     /* The program is returning now.  Restore our signal handler,
  140.        turn on terminal handling, redraw the screen, and place the
  141.        cursor where it belongs. */
  142.     terminal_prep_terminal ();
  143.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  144.     redisplay_after_signal ();
  145.     fflush (stdout);
  146.       }
  147.       break;
  148.  
  149. #if defined (SIGWINCH)
  150.     case SIGWINCH:
  151.       {
  152.     /* Turn off terminal IO, tell our parent that the window has changed,
  153.        then reinitialize the terminal and rebuild our windows. */
  154.     old_signal_handler = &old_WINCH;
  155.     terminal_goto_xy (0, 0);
  156.     fflush (stdout);
  157.     terminal_unprep_terminal ();
  158.     signal (sig, *old_signal_handler);
  159.      UNBLOCK_SIGNAL (sig);
  160.     kill (getpid (), sig);
  161.  
  162.     /* After our old signal handler returns... */
  163.     terminal_get_screen_size ();
  164.     terminal_prep_terminal ();
  165.     display_initialize_display (screenwidth, screenheight);
  166.     window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
  167.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  168.     redisplay_after_signal ();
  169.       }
  170.       break;
  171. #endif /* SIGWINCH */
  172.     }
  173. }
  174.