home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / OS2 / gnuinfo.zip / info / signals.c < prev    next >
C/C++ Source or Header  |  1997-07-15  |  5KB  |  173 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 RETSIGTYPE signal_handler ();
  66.  
  67. static RETSIGTYPE info_signal_handler ();
  68. static signal_handler *old_TSTP, *old_TTOU, *old_TTIN;
  69. static signal_handler *old_WINCH, *old_INT;
  70.  
  71. void
  72. initialize_info_signal_handler ()
  73. {
  74. #if defined (SIGTSTP)
  75.   old_TSTP = (signal_handler *) signal (SIGTSTP, info_signal_handler);
  76.   old_TTOU = (signal_handler *) signal (SIGTTOU, info_signal_handler);
  77.   old_TTIN = (signal_handler *) signal (SIGTTIN, info_signal_handler);
  78. #endif /* SIGTSTP */
  79.  
  80. #if defined (SIGWINCH)
  81.   old_WINCH = (signal_handler *) signal (SIGWINCH, info_signal_handler);
  82. #endif
  83.  
  84. #if defined (SIGINT)
  85.   old_INT = (signal_handler *) signal (SIGINT, info_signal_handler);
  86. #endif
  87. }
  88.  
  89. static void
  90. redisplay_after_signal ()
  91. {
  92.   terminal_clear_screen ();
  93.   display_clear_display (the_display);
  94.   window_mark_chain (windows, W_UpdateWindow);
  95.   display_update_display (windows);
  96.   display_cursor_at_point (active_window);
  97.   fflush (stdout);
  98. }
  99.  
  100. static RETSIGTYPE
  101. info_signal_handler (sig)
  102.      int sig;
  103. {
  104.   signal_handler **old_signal_handler;
  105.  
  106.   switch (sig)
  107.     {
  108. #if defined (SIGTSTP)
  109.     case SIGTSTP:
  110.     case SIGTTOU:
  111.     case SIGTTIN:
  112. #endif
  113. #if defined (SIGINT)
  114.     case SIGINT:
  115. #endif
  116.       {
  117. #if defined (SIGTSTP)
  118.         if (sig == SIGTSTP)
  119.           old_signal_handler = &old_TSTP;
  120.         if (sig == SIGTTOU)
  121.           old_signal_handler = &old_TTOU;
  122.         if (sig == SIGTTIN)
  123.           old_signal_handler = &old_TTIN;
  124. #endif /* SIGTSTP */
  125.         if (sig == SIGINT)
  126.           old_signal_handler = &old_INT;
  127.  
  128.         /* For stop signals, restore the terminal IO, leave the cursor
  129.            at the bottom of the window, and stop us. */
  130.         terminal_goto_xy (0, screenheight - 1);
  131.         terminal_clear_to_eol ();
  132.         fflush (stdout);
  133.         terminal_unprep_terminal ();
  134.         signal (sig, *old_signal_handler);
  135.         UNBLOCK_SIGNAL (sig);
  136.         kill (getpid (), sig);
  137.  
  138.         /* The program is returning now.  Restore our signal handler,
  139.            turn on terminal handling, redraw the screen, and place the
  140.            cursor where it belongs. */
  141.         terminal_prep_terminal ();
  142.         *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler);
  143.         redisplay_after_signal ();
  144.         fflush (stdout);
  145.       }
  146.       break;
  147.  
  148. #if defined (SIGWINCH)
  149.     case SIGWINCH:
  150.       {
  151.         /* Turn off terminal IO, tell our parent that the window has changed,
  152.            then reinitialize the terminal and rebuild our windows. */
  153.         old_signal_handler = &old_WINCH;
  154.         terminal_goto_xy (0, 0);
  155.         fflush (stdout);
  156.         terminal_unprep_terminal ();
  157.         signal (sig, *old_signal_handler);
  158.         UNBLOCK_SIGNAL (sig);
  159.         kill (getpid (), sig);
  160.  
  161.         /* After our old signal handler returns... */
  162.         terminal_get_screen_size ();
  163.         terminal_prep_terminal ();
  164.         display_initialize_display (screenwidth, screenheight);
  165.         window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
  166.         *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler);
  167.         redisplay_after_signal ();
  168.       }
  169.       break;
  170. #endif /* SIGWINCH */
  171.     }
  172. }
  173.