home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / info / signals.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  199 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 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., 675 Mass Ave, Cambridge, MA 02139, 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 (_POSIX_VERSION)
  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. #if defined (HAVE_SIGSETMASK)
  43.       sigsetmask (sigblock (0) & ~(*newset));
  44. #endif /* HAVE_SIGSETMASK */
  45.       break;
  46.  
  47.     case SIG_BLOCK:
  48.       *oldset = sigblock (*newset);
  49.       break;
  50.  
  51.     case SIG_SETMASK:
  52. #if defined (HAVE_SIGSETMASK)
  53.       sigsetmask (*newset);
  54. #endif /* HAVE_SIGSETMASK */
  55.       break;
  56.  
  57.     default:
  58.       abort ();
  59.     }
  60. }
  61. #endif /* !_POSIX_VERSION */
  62.  
  63. /* **************************************************************** */
  64. /*                                    */
  65. /*            Signal Handling for Info                */
  66. /*                                    */
  67. /* **************************************************************** */
  68.  
  69. typedef void SigHandlerType;
  70. typedef SigHandlerType SigHandler ();
  71.  
  72. static SigHandlerType info_signal_handler ();
  73. static SigHandler *old_TSTP, *old_TTOU, *old_TTIN;
  74. static SigHandler *old_WINCH, *old_INT;
  75.  
  76. void
  77. initialize_info_signal_handler ()
  78. {
  79. #if defined (SIGTSTP)
  80.   old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler);
  81.   old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler);
  82.   old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler);
  83. #endif /* SIGTSTP */
  84.  
  85. #if defined (SIGWINCH)
  86.   old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler);
  87. #endif
  88.  
  89. #if defined (SIGINT)
  90.   old_INT = (SigHandler *) signal (SIGINT, info_signal_handler);
  91. #endif
  92. }
  93.  
  94. void
  95. clear_info_signal_handler ()
  96. {
  97. #if defined (SIGTSTP)
  98.   signal (SIGTSTP, old_TSTP);
  99.   signal (SIGTTOU, old_TTOU);
  100.   signal (SIGTTIN, old_TTIN);
  101. #endif /* SIGTSTP */
  102.  
  103. #if defined (SIGWINCH)
  104.   signal (SIGWINCH, old_WINCH);
  105. #endif
  106.  
  107. #if defined (SIGINT)
  108.   signal (SIGINT, old_INT);
  109. #endif
  110. }
  111.  
  112. static void
  113. redisplay_after_signal ()
  114. {
  115.   terminal_clear_screen ();
  116.   display_clear_display (the_display);
  117.   window_mark_chain (windows, W_UpdateWindow);
  118.   display_update_display (windows);
  119.   display_cursor_at_point (active_window);
  120.   fflush (stdout);
  121. }
  122.  
  123. static SigHandlerType
  124. info_signal_handler (sig)
  125.      int sig;
  126. {
  127.   SigHandler **old_signal_handler;
  128.  
  129.   switch (sig)
  130.     {
  131. #if defined (SIGTSTP)
  132.     case SIGTSTP:
  133.     case SIGTTOU:
  134.     case SIGTTIN:
  135. #endif
  136. #if defined (SIGINT)
  137.     case SIGINT:
  138. #endif
  139.       {
  140. #if defined (SIGTSTP)
  141.     if (sig == SIGTSTP)
  142.       old_signal_handler = &old_TSTP;
  143.     else if (sig == SIGTTOU)
  144.       old_signal_handler = &old_TTOU;
  145.     else if (sig == SIGTTIN)
  146.       old_signal_handler = &old_TTIN;
  147. #endif /* SIGTSTP */
  148. #if defined (SIGINT)
  149.     else if (sig == SIGINT)
  150.       old_signal_handler = &old_INT;
  151. #endif
  152.  
  153.     /* For stop signals, restore the terminal IO, leave the cursor
  154.        at the bottom of the window, and stop us. */
  155.     terminal_goto_xy (0, screenheight - 1);
  156.     terminal_clear_to_eol ();
  157.     fflush (stdout);
  158.     terminal_unprep_terminal ();
  159.      UNBLOCK_SIGNAL (sig);
  160.     signal (sig, *old_signal_handler);
  161.     kill (getpid (), sig);
  162.  
  163.     /* The program is returning now.  Restore our signal handler,
  164.        turn on terminal handling, redraw the screen, and place the
  165.        cursor where it belongs. */
  166.     
  167.     terminal_prep_terminal ();
  168.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  169.     redisplay_after_signal ();
  170.     fflush (stdout);
  171.       }
  172.       break;
  173.  
  174. #if defined (SIGWINCH)
  175.     case SIGWINCH:
  176.       {
  177.     /* Turn off terminal IO, tell our parent that the window has changed,
  178.        then reinitialize the terminal and rebuild our windows. */
  179.     old_signal_handler = &old_WINCH;
  180.     terminal_goto_xy (0, 0);
  181.     fflush (stdout);
  182.     terminal_unprep_terminal ();
  183.     signal (sig, *old_signal_handler);
  184.      UNBLOCK_SIGNAL (sig);
  185.     kill (getpid (), sig);
  186.  
  187.     /* After our old signal handler returns... */
  188.     terminal_get_screen_size ();
  189.     terminal_prep_terminal ();
  190.     display_initialize_display (screenwidth, screenheight);
  191.     window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
  192.     *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
  193.     redisplay_after_signal ();
  194.       }
  195.       break;
  196. #endif /* SIGWINCH */
  197.     }
  198. }
  199.