Remove _bfd_dwarf2_find_nearest_line addr_size parameter
[external/binutils.git] / readline / signals.c
1 /* signals.c -- signal handling support for readline. */
2
3 /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library (Readline), a library
6    for reading lines of text with interactive input and history editing.      
7
8    Readline 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 3 of the License, or
11    (at your option) any later version.
12
13    Readline 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 Readline.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #include <stdio.h>              /* Just for NULL.  Yuck. */
29 #include <sys/types.h>
30 #include <signal.h>
31
32 #if defined (HAVE_UNISTD_H)
33 #  include <unistd.h>
34 #endif /* HAVE_UNISTD_H */
35
36 /* System-specific feature definitions and include files. */
37 #include "rldefs.h"
38
39 #if defined (GWINSZ_IN_SYS_IOCTL)
40 #  include <sys/ioctl.h>
41 #endif /* GWINSZ_IN_SYS_IOCTL */
42
43 /* Some standard library routines. */
44 #include "readline.h"
45 #include "history.h"
46
47 #include "rlprivate.h"
48
49 #if defined (HANDLE_SIGNALS)
50
51 #if !defined (RETSIGTYPE)
52 #  if defined (VOID_SIGHANDLER)
53 #    define RETSIGTYPE void
54 #  else
55 #    define RETSIGTYPE int
56 #  endif /* !VOID_SIGHANDLER */
57 #endif /* !RETSIGTYPE */
58
59 #if defined (VOID_SIGHANDLER)
60 #  define SIGHANDLER_RETURN return
61 #else
62 #  define SIGHANDLER_RETURN return (0)
63 #endif
64
65 /* This typedef is equivalent to the one for Function; it allows us
66    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
67 typedef RETSIGTYPE SigHandler ();
68
69 #if defined (HAVE_POSIX_SIGNALS)
70 typedef struct sigaction sighandler_cxt;
71 #  define rl_sigaction(s, nh, oh)       sigaction(s, nh, oh)
72 #else
73 typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
74 #  define sigemptyset(m)
75 #endif /* !HAVE_POSIX_SIGNALS */
76
77 #ifndef SA_RESTART
78 #  define SA_RESTART 0
79 #endif
80
81 static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
82 static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
83 static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *));
84
85 static RETSIGTYPE rl_signal_handler PARAMS((int));
86 static RETSIGTYPE _rl_handle_signal PARAMS((int));
87      
88 /* Exported variables for use by applications. */
89
90 /* If non-zero, readline will install its own signal handlers for
91    SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
92 int rl_catch_signals = 1;
93
94 /* If non-zero, readline will install a signal handler for SIGWINCH. */
95 #ifdef SIGWINCH
96 int rl_catch_sigwinch = 1;
97 #else
98 int rl_catch_sigwinch = 0;      /* for the readline state struct in readline.c */
99 #endif
100
101 /* Private variables. */
102 int _rl_interrupt_immediately = 0;
103 int volatile _rl_caught_signal = 0;     /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
104
105 /* If non-zero, print characters corresponding to received signals as long as
106    the user has indicated his desire to do so (_rl_echo_control_chars). */
107 int _rl_echoctl = 0;
108
109 int _rl_intr_char = 0;
110 int _rl_quit_char = 0;
111 int _rl_susp_char = 0;
112
113 static int signals_set_flag;
114 static int sigwinch_set_flag;
115
116 #if defined (HAVE_POSIX_SIGNALS)
117 sigset_t _rl_orig_sigset;
118 #endif /* !HAVE_POSIX_SIGNALS */
119
120 /* **************************************************************** */
121 /*                                                                  */
122 /*                         Signal Handling                          */
123 /*                                                                  */
124 /* **************************************************************** */
125
126 static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit;
127 #if defined (SIGTSTP)
128 static sighandler_cxt old_tstp, old_ttou, old_ttin;
129 #endif
130 #if defined (SIGWINCH)
131 static sighandler_cxt old_winch;
132 #endif
133
134 _rl_sigcleanup_func_t *_rl_sigcleanup;
135 void *_rl_sigcleanarg;
136
137 /* Readline signal handler functions. */
138
139 /* Called from RL_CHECK_SIGNALS() macro */
140 RETSIGTYPE
141 _rl_signal_handler (int sig)
142 {
143   _rl_caught_signal = 0;        /* XXX */
144
145 #if defined (SIGWINCH)
146   if (sig == SIGWINCH)
147     {
148       rl_resize_terminal ();
149       /* XXX - experimental for now */
150       /* Call a signal hook because though we called the original signal handler
151          in rl_sigwinch_handler below, we will not resend the signal to
152          ourselves. */
153       if (rl_signal_event_hook)
154         (*rl_signal_event_hook) ();
155     }
156   else
157 #endif
158     _rl_handle_signal (sig);
159
160   SIGHANDLER_RETURN;
161 }
162
163 static RETSIGTYPE
164 rl_signal_handler (int sig)
165 {
166   if (_rl_interrupt_immediately)
167     {
168       _rl_interrupt_immediately = 0;
169       _rl_handle_signal (sig);
170     }
171   else
172     _rl_caught_signal = sig;
173
174   SIGHANDLER_RETURN;
175 }
176
177 static RETSIGTYPE
178 _rl_handle_signal (int sig)
179 {
180 #if defined (HAVE_POSIX_SIGNALS)
181   sigset_t set;
182 #else /* !HAVE_POSIX_SIGNALS */
183 #  if defined (HAVE_BSD_SIGNALS)
184   long omask;
185 #  else /* !HAVE_BSD_SIGNALS */
186   sighandler_cxt dummy_cxt;     /* needed for rl_set_sighandler call */
187 #  endif /* !HAVE_BSD_SIGNALS */
188 #endif /* !HAVE_POSIX_SIGNALS */
189
190   RL_SETSTATE(RL_STATE_SIGHANDLER);
191
192 #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
193   /* Since the signal will not be blocked while we are in the signal
194      handler, ignore it until rl_clear_signals resets the catcher. */
195 #  if defined (SIGALRM)
196   if (sig == SIGINT || sig == SIGALRM)
197 #  else
198   if (sig == SIGINT)
199 #  endif
200     rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
201 #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
202
203   /* If there's a sig cleanup function registered, call it and `deregister'
204      the cleanup function to avoid multiple calls */
205   if (_rl_sigcleanup)
206     {
207       (*_rl_sigcleanup) (sig, _rl_sigcleanarg);
208       _rl_sigcleanup = 0;
209       _rl_sigcleanarg = 0;
210     }
211     
212   switch (sig)
213     {
214     case SIGINT:
215       _rl_reset_completion_state ();
216       rl_free_line_state ();
217 #if defined (READLINE_CALLBACKS)
218       rl_callback_sigcleanup ();
219 #endif
220
221       /* FALLTHROUGH */
222
223 #if defined (SIGTSTP)
224     case SIGTSTP:
225     case SIGTTIN:
226 #  if defined (HAVE_POSIX_SIGNALS)
227       /* Block SIGTTOU so we can restore the terminal settings to something
228          sane without stopping on SIGTTOU if we have been placed into the
229          background.  Even trying to get the current terminal pgrp with
230          tcgetpgrp() will generate SIGTTOU, so we don't bother.  Don't bother
231          doing this if we've been stopped on SIGTTOU; it's aready too late. */
232       sigemptyset (&set);
233       sigaddset (&set, SIGTTOU);
234       sigprocmask (SIG_BLOCK, &set, (sigset_t *)NULL);
235 #  endif
236     case SIGTTOU:
237 #endif /* SIGTSTP */
238     case SIGTERM:
239 #if defined (SIGHUP)
240     case SIGHUP:
241 #endif
242 #if defined (SIGALRM)
243     case SIGALRM:
244 #endif
245 #if defined (SIGQUIT)
246     case SIGQUIT:
247 #endif
248       rl_echo_signal_char (sig);
249       rl_cleanup_after_signal ();
250
251 #if defined (HAVE_POSIX_SIGNALS)
252 #  if defined (SIGTSTP)
253       /* Unblock SIGTTOU blocked above */
254       if (sig == SIGTTIN || sig == SIGTSTP)
255         sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL);
256 #  endif
257
258       sigemptyset (&set);
259       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
260       sigdelset (&set, sig);
261 #else /* !HAVE_POSIX_SIGNALS */
262 #  if defined (HAVE_BSD_SIGNALS)
263       omask = sigblock (0);
264 #  endif /* HAVE_BSD_SIGNALS */
265 #endif /* !HAVE_POSIX_SIGNALS */
266
267 #if defined (__EMX__)
268       signal (sig, SIG_ACK);
269 #endif
270
271 #if defined (HAVE_KILL)
272       kill (getpid (), sig);
273 #else
274       raise (sig);              /* assume we have raise */
275 #endif
276
277       /* Let the signal that we just sent through.  */
278 #if defined (HAVE_POSIX_SIGNALS)
279       sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
280 #else /* !HAVE_POSIX_SIGNALS */
281 #  if defined (HAVE_BSD_SIGNALS)
282       sigsetmask (omask & ~(sigmask (sig)));
283 #  endif /* HAVE_BSD_SIGNALS */
284 #endif /* !HAVE_POSIX_SIGNALS */
285
286       rl_reset_after_signal ();      
287     }
288
289   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
290   SIGHANDLER_RETURN;
291 }
292
293 #if defined (SIGWINCH)
294 static RETSIGTYPE
295 rl_sigwinch_handler (int sig)
296 {
297   SigHandler *oh;
298
299 #if defined (MUST_REINSTALL_SIGHANDLERS)
300   sighandler_cxt dummy_winch;
301
302   /* We don't want to change old_winch -- it holds the state of SIGWINCH
303      disposition set by the calling application.  We need this state
304      because we call the application's SIGWINCH handler after updating
305      our own idea of the screen size. */
306   rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
307 #endif
308
309   RL_SETSTATE(RL_STATE_SIGHANDLER);
310   _rl_caught_signal = sig;
311
312   /* If another sigwinch handler has been installed, call it. */
313   oh = (SigHandler *)old_winch.sa_handler;
314   if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
315     (*oh) (sig);
316
317   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
318   SIGHANDLER_RETURN;
319 }
320 #endif  /* SIGWINCH */
321
322 /* Functions to manage signal handling. */
323
324 #if !defined (HAVE_POSIX_SIGNALS)
325 static int
326 rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh)
327 {
328   oh->sa_handler = signal (sig, nh->sa_handler);
329   return 0;
330 }
331 #endif /* !HAVE_POSIX_SIGNALS */
332
333 /* Set up a readline-specific signal handler, saving the old signal
334    information in OHANDLER.  Return the old signal handler, like
335    signal(). */
336 static SigHandler *
337 rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
338 {
339   sighandler_cxt old_handler;
340 #if defined (HAVE_POSIX_SIGNALS)
341   struct sigaction act;
342
343   act.sa_handler = handler;
344 #  if defined (SIGWINCH)
345   act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
346 #  else
347   act.sa_flags = 0;
348 #  endif /* SIGWINCH */
349   sigemptyset (&act.sa_mask);
350   sigemptyset (&ohandler->sa_mask);
351   sigaction (sig, &act, &old_handler);
352 #else
353   old_handler.sa_handler = (SigHandler *)signal (sig, handler);
354 #endif /* !HAVE_POSIX_SIGNALS */
355
356   /* XXX -- assume we have memcpy */
357   /* If rl_set_signals is called twice in a row, don't set the old handler to
358      rl_signal_handler, because that would cause infinite recursion. */
359   if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
360     memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
361
362   return (ohandler->sa_handler);
363 }
364
365 /* Set disposition of SIG to HANDLER, returning old state in OHANDLER.  Don't
366    change disposition if OHANDLER indicates the signal was ignored. */
367 static void
368 rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
369 {
370   sighandler_cxt dummy;
371   SigHandler *oh;
372
373   sigemptyset (&dummy.sa_mask);
374   dummy.sa_flags = 0;
375   oh = rl_set_sighandler (sig, handler, ohandler);
376   if (oh == (SigHandler *)SIG_IGN)
377     rl_sigaction (sig, ohandler, &dummy);
378 }
379
380 /* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
381    signal was not being ignored.  MUST only be called for signals whose
382    disposition was changed using rl_maybe_set_sighandler or for which the
383    SIG_IGN check was performed inline (e.g., SIGALRM below). */
384 static void
385 rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler)
386 {
387   sighandler_cxt dummy;
388
389   sigemptyset (&dummy.sa_mask);
390   dummy.sa_flags = 0;
391   if (handler->sa_handler != SIG_IGN)
392     rl_sigaction (sig, handler, &dummy);
393 }
394
395 int
396 rl_set_signals (void)
397 {
398   sighandler_cxt dummy;
399   SigHandler *oh;
400 #if defined (HAVE_POSIX_SIGNALS)
401   static int sigmask_set = 0;
402   static sigset_t bset, oset;
403 #endif
404
405 #if defined (HAVE_POSIX_SIGNALS)
406   if (rl_catch_signals && sigmask_set == 0)
407     {
408       sigemptyset (&bset);
409
410       sigaddset (&bset, SIGINT);
411       sigaddset (&bset, SIGTERM);
412 #if defined (SIGHUP)
413       sigaddset (&bset, SIGHUP);
414 #endif
415 #if defined (SIGQUIT)
416       sigaddset (&bset, SIGQUIT);
417 #endif
418 #if defined (SIGALRM)
419       sigaddset (&bset, SIGALRM);
420 #endif
421 #if defined (SIGTSTP)
422       sigaddset (&bset, SIGTSTP);
423 #endif
424 #if defined (SIGTTIN)
425       sigaddset (&bset, SIGTTIN);
426 #endif
427 #if defined (SIGTTOU)
428       sigaddset (&bset, SIGTTOU);
429 #endif
430       sigmask_set = 1;
431     }      
432 #endif /* HAVE_POSIX_SIGNALS */
433
434   if (rl_catch_signals && signals_set_flag == 0)
435     {
436 #if defined (HAVE_POSIX_SIGNALS)
437       sigemptyset (&_rl_orig_sigset);
438       sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset);
439 #endif
440
441       rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
442       rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
443 #if defined (SIGHUP)
444       rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
445 #endif
446 #if defined (SIGQUIT)
447       rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
448 #endif
449
450 #if defined (SIGALRM)
451       oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
452       if (oh == (SigHandler *)SIG_IGN)
453         rl_sigaction (SIGALRM, &old_alrm, &dummy);
454 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
455       /* If the application using readline has already installed a signal
456          handler with SA_RESTART, SIGALRM will cause reads to be restarted
457          automatically, so readline should just get out of the way.  Since
458          we tested for SIG_IGN above, we can just test for SIG_DFL here. */
459       if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
460         rl_sigaction (SIGALRM, &old_alrm, &dummy);
461 #endif /* HAVE_POSIX_SIGNALS */
462 #endif /* SIGALRM */
463
464 #if defined (SIGTSTP)
465       rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
466 #endif /* SIGTSTP */
467
468 #if defined (SIGTTOU)
469       rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
470 #endif /* SIGTTOU */
471
472 #if defined (SIGTTIN)
473       rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
474 #endif /* SIGTTIN */
475
476       signals_set_flag = 1;
477
478 #if defined (HAVE_POSIX_SIGNALS)
479       sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL);
480 #endif
481     }
482   else if (rl_catch_signals == 0)
483     {
484 #if defined (HAVE_POSIX_SIGNALS)
485       sigemptyset (&_rl_orig_sigset);
486       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset);
487 #endif
488     }
489
490 #if defined (SIGWINCH)
491   if (rl_catch_sigwinch && sigwinch_set_flag == 0)
492     {
493       rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
494       sigwinch_set_flag = 1;
495     }
496 #endif /* SIGWINCH */
497
498   return 0;
499 }
500
501 int
502 rl_clear_signals (void)
503 {
504   sighandler_cxt dummy;
505
506   if (rl_catch_signals && signals_set_flag == 1)
507     {
508       /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
509          we should in theory not have to restore a handler where
510          old_xxx.sa_handler == SIG_IGN.  That's what rl_maybe_restore_sighandler
511          does.  Fewer system calls should reduce readline's per-line
512          overhead */
513       rl_maybe_restore_sighandler (SIGINT, &old_int);
514       rl_maybe_restore_sighandler (SIGTERM, &old_term);
515 #if defined (SIGHUP)
516       rl_maybe_restore_sighandler (SIGHUP, &old_hup);
517 #endif
518 #if defined (SIGQUIT)
519       rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
520 #endif
521 #if defined (SIGALRM)
522       rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
523 #endif
524
525 #if defined (SIGTSTP)
526       rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
527 #endif /* SIGTSTP */
528
529 #if defined (SIGTTOU)
530       rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
531 #endif /* SIGTTOU */
532
533 #if defined (SIGTTIN)
534       rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
535 #endif /* SIGTTIN */
536
537       signals_set_flag = 0;
538     }
539
540 #if defined (SIGWINCH)
541   if (rl_catch_sigwinch && sigwinch_set_flag == 1)
542     {
543       sigemptyset (&dummy.sa_mask);
544       rl_sigaction (SIGWINCH, &old_winch, &dummy);
545       sigwinch_set_flag = 0;
546     }
547 #endif
548
549   return 0;
550 }
551
552 /* Clean up the terminal and readline state after catching a signal, before
553    resending it to the calling application. */
554 void
555 rl_cleanup_after_signal (void)
556 {
557   _rl_clean_up_for_exit ();
558   if (rl_deprep_term_function)
559     (*rl_deprep_term_function) ();
560   rl_clear_pending_input ();
561   rl_clear_signals ();
562 }
563
564 /* Reset the terminal and readline state after a signal handler returns. */
565 void
566 rl_reset_after_signal (void)
567 {
568   if (rl_prep_term_function)
569     (*rl_prep_term_function) (_rl_meta_flag);
570   rl_set_signals ();
571 }
572
573 /* Free up the readline variable line state for the current line (undo list,
574    any partial history entry, any keyboard macros in progress, and any
575    numeric arguments in process) after catching a signal, before calling
576    rl_cleanup_after_signal(). */ 
577 void
578 rl_free_line_state (void)
579 {
580   register HIST_ENTRY *entry;
581
582   rl_free_undo_list ();
583
584   entry = current_history ();
585   if (entry)
586     entry->data = (char *)NULL;
587
588   _rl_kill_kbd_macro ();
589   rl_clear_message ();
590   _rl_reset_argument ();
591 }
592
593 int
594 rl_pending_signal (void)
595 {
596   return (_rl_caught_signal);
597 }
598
599 void
600 rl_check_signals (void)
601 {
602   RL_CHECK_SIGNALS ();
603 }
604 #endif  /* HANDLE_SIGNALS */
605
606 /* **************************************************************** */
607 /*                                                                  */
608 /*                         SIGINT Management                        */
609 /*                                                                  */
610 /* **************************************************************** */
611
612 #if defined (HAVE_POSIX_SIGNALS)
613 static sigset_t sigint_set, sigint_oset;
614 static sigset_t sigwinch_set, sigwinch_oset;
615 #else /* !HAVE_POSIX_SIGNALS */
616 #  if defined (HAVE_BSD_SIGNALS)
617 static int sigint_oldmask;
618 static int sigwinch_oldmask;
619 #  endif /* HAVE_BSD_SIGNALS */
620 #endif /* !HAVE_POSIX_SIGNALS */
621
622 static int sigint_blocked;
623 static int sigwinch_blocked;
624
625 /* Cause SIGINT to not be delivered until the corresponding call to
626    release_sigint(). */
627 void
628 _rl_block_sigint (void)
629 {
630   if (sigint_blocked)
631     return;
632
633   sigint_blocked = 1;
634 }
635
636 /* Allow SIGINT to be delivered. */
637 void
638 _rl_release_sigint (void)
639 {
640   if (sigint_blocked == 0)
641     return;
642
643   sigint_blocked = 0;
644   RL_CHECK_SIGNALS ();
645 }
646
647 /* Cause SIGWINCH to not be delivered until the corresponding call to
648    release_sigwinch(). */
649 void
650 _rl_block_sigwinch (void)
651 {
652   if (sigwinch_blocked)
653     return;
654
655 #if defined (SIGWINCH)
656
657 #if defined (HAVE_POSIX_SIGNALS)
658   sigemptyset (&sigwinch_set);
659   sigemptyset (&sigwinch_oset);
660   sigaddset (&sigwinch_set, SIGWINCH);
661   sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
662 #else /* !HAVE_POSIX_SIGNALS */
663 #  if defined (HAVE_BSD_SIGNALS)
664   sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
665 #  else /* !HAVE_BSD_SIGNALS */
666 #    if defined (HAVE_USG_SIGHOLD)
667   sighold (SIGWINCH);
668 #    endif /* HAVE_USG_SIGHOLD */
669 #  endif /* !HAVE_BSD_SIGNALS */
670 #endif /* !HAVE_POSIX_SIGNALS */
671
672 #endif /* SIGWINCH */
673
674   sigwinch_blocked = 1;
675 }
676
677 /* Allow SIGWINCH to be delivered. */
678 void
679 _rl_release_sigwinch (void)
680 {
681   if (sigwinch_blocked == 0)
682     return;
683
684 #if defined (SIGWINCH)
685
686 #if defined (HAVE_POSIX_SIGNALS)
687   sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
688 #else
689 #  if defined (HAVE_BSD_SIGNALS)
690   sigsetmask (sigwinch_oldmask);
691 #  else /* !HAVE_BSD_SIGNALS */
692 #    if defined (HAVE_USG_SIGHOLD)
693   sigrelse (SIGWINCH);
694 #    endif /* HAVE_USG_SIGHOLD */
695 #  endif /* !HAVE_BSD_SIGNALS */
696 #endif /* !HAVE_POSIX_SIGNALS */
697
698 #endif /* SIGWINCH */
699
700   sigwinch_blocked = 0;
701 }
702
703 /* **************************************************************** */
704 /*                                                                  */
705 /*              Echoing special control characters                  */
706 /*                                                                  */
707 /* **************************************************************** */
708 void
709 rl_echo_signal_char (int sig)
710 {
711   char cstr[3];
712   int cslen, c;
713
714   if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
715     return;
716
717   switch (sig)
718     {
719     case SIGINT:  c = _rl_intr_char; break;
720 #if defined (SIGQUIT)
721     case SIGQUIT: c = _rl_quit_char; break;
722 #endif
723 #if defined (SIGTSTP)
724     case SIGTSTP: c = _rl_susp_char; break;
725 #endif
726     default: return;
727     }
728
729   if (CTRL_CHAR (c) || c == RUBOUT)
730     {
731       cstr[0] = '^';
732       cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
733       cstr[cslen = 2] = '\0';
734     }
735   else
736     {
737       cstr[0] = c;
738       cstr[cslen = 1] = '\0';
739     }
740
741   _rl_output_some_chars (cstr, cslen);
742 }