signals.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /* signals.c -- signal handling support for readline. */
  2. /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
  3. This file is part of the GNU Readline Library (Readline), a library
  4. for reading lines of text with interactive input and history editing.
  5. Readline is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. Readline is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Readline. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #define READLINE_LIBRARY
  17. #if defined (HAVE_CONFIG_H)
  18. # include <config.h>
  19. #endif
  20. #include <stdio.h> /* Just for NULL. Yuck. */
  21. #include <sys/types.h>
  22. #include <signal.h>
  23. #if defined (HAVE_UNISTD_H)
  24. # include <unistd.h>
  25. #endif /* HAVE_UNISTD_H */
  26. /* System-specific feature definitions and include files. */
  27. #include "rldefs.h"
  28. #if defined (GWINSZ_IN_SYS_IOCTL)
  29. # include <sys/ioctl.h>
  30. #endif /* GWINSZ_IN_SYS_IOCTL */
  31. /* Some standard library routines. */
  32. #include "readline.h"
  33. #include "history.h"
  34. #include "rlprivate.h"
  35. #if defined (HANDLE_SIGNALS)
  36. #if !defined (RETSIGTYPE)
  37. # if defined (VOID_SIGHANDLER)
  38. # define RETSIGTYPE void
  39. # else
  40. # define RETSIGTYPE int
  41. # endif /* !VOID_SIGHANDLER */
  42. #endif /* !RETSIGTYPE */
  43. #if defined (VOID_SIGHANDLER)
  44. # define SIGHANDLER_RETURN return
  45. #else
  46. # define SIGHANDLER_RETURN return (0)
  47. #endif
  48. /* This typedef is equivalent to the one for Function; it allows us
  49. to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
  50. typedef RETSIGTYPE SigHandler ();
  51. #if defined (HAVE_POSIX_SIGNALS)
  52. typedef struct sigaction sighandler_cxt;
  53. # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
  54. #else
  55. typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
  56. # define sigemptyset(m)
  57. #endif /* !HAVE_POSIX_SIGNALS */
  58. #ifndef SA_RESTART
  59. # define SA_RESTART 0
  60. #endif
  61. static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
  62. static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
  63. static RETSIGTYPE rl_signal_handler PARAMS((int));
  64. static RETSIGTYPE _rl_handle_signal PARAMS((int));
  65. /* Exported variables for use by applications. */
  66. /* If non-zero, readline will install its own signal handlers for
  67. SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
  68. int rl_catch_signals = 1;
  69. /* If non-zero, readline will install a signal handler for SIGWINCH. */
  70. #ifdef SIGWINCH
  71. int rl_catch_sigwinch = 1;
  72. #else
  73. int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
  74. #endif
  75. /* Private variables. */
  76. int _rl_interrupt_immediately = 0;
  77. int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
  78. /* If non-zero, print characters corresponding to received signals as long as
  79. the user has indicated his desire to do so (_rl_echo_control_chars). */
  80. int _rl_echoctl = 0;
  81. int _rl_intr_char = 0;
  82. int _rl_quit_char = 0;
  83. int _rl_susp_char = 0;
  84. static int signals_set_flag;
  85. static int sigwinch_set_flag;
  86. /* **************************************************************** */
  87. /* */
  88. /* Signal Handling */
  89. /* */
  90. /* **************************************************************** */
  91. static sighandler_cxt old_int, old_term, old_alrm, old_quit;
  92. #if defined (SIGTSTP)
  93. static sighandler_cxt old_tstp, old_ttou, old_ttin;
  94. #endif
  95. #if defined (SIGWINCH)
  96. static sighandler_cxt old_winch;
  97. #endif
  98. /* Readline signal handler functions. */
  99. /* Called from RL_CHECK_SIGNALS() macro */
  100. RETSIGTYPE
  101. _rl_signal_handler (sig)
  102. int sig;
  103. {
  104. _rl_caught_signal = 0; /* XXX */
  105. _rl_handle_signal (sig);
  106. SIGHANDLER_RETURN;
  107. }
  108. static RETSIGTYPE
  109. rl_signal_handler (sig)
  110. int sig;
  111. {
  112. if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK))
  113. {
  114. _rl_interrupt_immediately = 0;
  115. _rl_handle_signal (sig);
  116. }
  117. else
  118. _rl_caught_signal = sig;
  119. SIGHANDLER_RETURN;
  120. }
  121. static RETSIGTYPE
  122. _rl_handle_signal (sig)
  123. int sig;
  124. {
  125. #if defined (HAVE_POSIX_SIGNALS)
  126. sigset_t set;
  127. #else /* !HAVE_POSIX_SIGNALS */
  128. # if defined (HAVE_BSD_SIGNALS)
  129. long omask;
  130. # else /* !HAVE_BSD_SIGNALS */
  131. sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
  132. # endif /* !HAVE_BSD_SIGNALS */
  133. #endif /* !HAVE_POSIX_SIGNALS */
  134. RL_SETSTATE(RL_STATE_SIGHANDLER);
  135. #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
  136. /* Since the signal will not be blocked while we are in the signal
  137. handler, ignore it until rl_clear_signals resets the catcher. */
  138. # if defined (SIGALRM)
  139. if (sig == SIGINT || sig == SIGALRM)
  140. # else
  141. if (sig == SIGINT)
  142. # endif
  143. rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
  144. #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
  145. switch (sig)
  146. {
  147. case SIGINT:
  148. _rl_reset_completion_state ();
  149. rl_free_line_state ();
  150. /* FALLTHROUGH */
  151. case SIGTERM:
  152. #if defined (SIGTSTP)
  153. case SIGTSTP:
  154. case SIGTTOU:
  155. case SIGTTIN:
  156. #endif /* SIGTSTP */
  157. #if defined (SIGALRM)
  158. case SIGALRM:
  159. #endif
  160. #if defined (SIGQUIT)
  161. case SIGQUIT:
  162. #endif
  163. rl_echo_signal_char (sig);
  164. rl_cleanup_after_signal ();
  165. #if defined (HAVE_POSIX_SIGNALS)
  166. sigemptyset (&set);
  167. sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
  168. sigdelset (&set, sig);
  169. #else /* !HAVE_POSIX_SIGNALS */
  170. # if defined (HAVE_BSD_SIGNALS)
  171. omask = sigblock (0);
  172. # endif /* HAVE_BSD_SIGNALS */
  173. #endif /* !HAVE_POSIX_SIGNALS */
  174. #if defined (__EMX__)
  175. signal (sig, SIG_ACK);
  176. #endif
  177. #if defined (HAVE_KILL)
  178. kill (getpid (), sig);
  179. #else
  180. raise (sig); /* assume we have raise */
  181. #endif
  182. /* Let the signal that we just sent through. */
  183. #if defined (HAVE_POSIX_SIGNALS)
  184. sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
  185. #else /* !HAVE_POSIX_SIGNALS */
  186. # if defined (HAVE_BSD_SIGNALS)
  187. sigsetmask (omask & ~(sigmask (sig)));
  188. # endif /* HAVE_BSD_SIGNALS */
  189. #endif /* !HAVE_POSIX_SIGNALS */
  190. rl_reset_after_signal ();
  191. }
  192. RL_UNSETSTATE(RL_STATE_SIGHANDLER);
  193. SIGHANDLER_RETURN;
  194. }
  195. #if defined (SIGWINCH)
  196. static RETSIGTYPE
  197. rl_sigwinch_handler (sig)
  198. int sig;
  199. {
  200. SigHandler *oh;
  201. #if defined (MUST_REINSTALL_SIGHANDLERS)
  202. sighandler_cxt dummy_winch;
  203. /* We don't want to change old_winch -- it holds the state of SIGWINCH
  204. disposition set by the calling application. We need this state
  205. because we call the application's SIGWINCH handler after updating
  206. our own idea of the screen size. */
  207. rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
  208. #endif
  209. RL_SETSTATE(RL_STATE_SIGHANDLER);
  210. rl_resize_terminal ();
  211. /* If another sigwinch handler has been installed, call it. */
  212. oh = (SigHandler *)old_winch.sa_handler;
  213. if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
  214. (*oh) (sig);
  215. RL_UNSETSTATE(RL_STATE_SIGHANDLER);
  216. SIGHANDLER_RETURN;
  217. }
  218. #endif /* SIGWINCH */
  219. /* Functions to manage signal handling. */
  220. #if !defined (HAVE_POSIX_SIGNALS)
  221. static int
  222. rl_sigaction (sig, nh, oh)
  223. int sig;
  224. sighandler_cxt *nh, *oh;
  225. {
  226. oh->sa_handler = signal (sig, nh->sa_handler);
  227. return 0;
  228. }
  229. #endif /* !HAVE_POSIX_SIGNALS */
  230. /* Set up a readline-specific signal handler, saving the old signal
  231. information in OHANDLER. Return the old signal handler, like
  232. signal(). */
  233. static SigHandler *
  234. rl_set_sighandler (sig, handler, ohandler)
  235. int sig;
  236. SigHandler *handler;
  237. sighandler_cxt *ohandler;
  238. {
  239. sighandler_cxt old_handler;
  240. #if defined (HAVE_POSIX_SIGNALS)
  241. struct sigaction act;
  242. act.sa_handler = handler;
  243. # if defined (SIGWINCH)
  244. act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
  245. # else
  246. act.sa_flags = 0;
  247. # endif /* SIGWINCH */
  248. sigemptyset (&act.sa_mask);
  249. sigemptyset (&ohandler->sa_mask);
  250. sigaction (sig, &act, &old_handler);
  251. #else
  252. old_handler.sa_handler = (SigHandler *)signal (sig, handler);
  253. #endif /* !HAVE_POSIX_SIGNALS */
  254. /* XXX -- assume we have memcpy */
  255. /* If rl_set_signals is called twice in a row, don't set the old handler to
  256. rl_signal_handler, because that would cause infinite recursion. */
  257. if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
  258. memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
  259. return (ohandler->sa_handler);
  260. }
  261. static void
  262. rl_maybe_set_sighandler (sig, handler, ohandler)
  263. int sig;
  264. SigHandler *handler;
  265. sighandler_cxt *ohandler;
  266. {
  267. sighandler_cxt dummy;
  268. SigHandler *oh;
  269. sigemptyset (&dummy.sa_mask);
  270. oh = rl_set_sighandler (sig, handler, ohandler);
  271. if (oh == (SigHandler *)SIG_IGN)
  272. rl_sigaction (sig, ohandler, &dummy);
  273. }
  274. int
  275. rl_set_signals ()
  276. {
  277. sighandler_cxt dummy;
  278. SigHandler *oh;
  279. #if defined (HAVE_POSIX_SIGNALS)
  280. static int sigmask_set = 0;
  281. static sigset_t bset, oset;
  282. #endif
  283. #if defined (HAVE_POSIX_SIGNALS)
  284. if (rl_catch_signals && sigmask_set == 0)
  285. {
  286. sigemptyset (&bset);
  287. sigaddset (&bset, SIGINT);
  288. sigaddset (&bset, SIGTERM);
  289. #if defined (SIGQUIT)
  290. sigaddset (&bset, SIGQUIT);
  291. #endif
  292. #if defined (SIGALRM)
  293. sigaddset (&bset, SIGALRM);
  294. #endif
  295. #if defined (SIGTSTP)
  296. sigaddset (&bset, SIGTSTP);
  297. #endif
  298. #if defined (SIGTTIN)
  299. sigaddset (&bset, SIGTTIN);
  300. #endif
  301. #if defined (SIGTTOU)
  302. sigaddset (&bset, SIGTTOU);
  303. #endif
  304. sigmask_set = 1;
  305. }
  306. #endif /* HAVE_POSIX_SIGNALS */
  307. if (rl_catch_signals && signals_set_flag == 0)
  308. {
  309. #if defined (HAVE_POSIX_SIGNALS)
  310. sigemptyset (&oset);
  311. sigprocmask (SIG_BLOCK, &bset, &oset);
  312. #endif
  313. rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
  314. rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
  315. #if defined (SIGQUIT)
  316. rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
  317. #endif
  318. #if defined (SIGALRM)
  319. oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
  320. if (oh == (SigHandler *)SIG_IGN)
  321. rl_sigaction (SIGALRM, &old_alrm, &dummy);
  322. #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
  323. /* If the application using readline has already installed a signal
  324. handler with SA_RESTART, SIGALRM will cause reads to be restarted
  325. automatically, so readline should just get out of the way. Since
  326. we tested for SIG_IGN above, we can just test for SIG_DFL here. */
  327. if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
  328. rl_sigaction (SIGALRM, &old_alrm, &dummy);
  329. #endif /* HAVE_POSIX_SIGNALS */
  330. #endif /* SIGALRM */
  331. #if defined (SIGTSTP)
  332. rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
  333. #endif /* SIGTSTP */
  334. #if defined (SIGTTOU)
  335. rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
  336. #endif /* SIGTTOU */
  337. #if defined (SIGTTIN)
  338. rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
  339. #endif /* SIGTTIN */
  340. signals_set_flag = 1;
  341. #if defined (HAVE_POSIX_SIGNALS)
  342. sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  343. #endif
  344. }
  345. #if defined (SIGWINCH)
  346. if (rl_catch_sigwinch && sigwinch_set_flag == 0)
  347. {
  348. rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
  349. sigwinch_set_flag = 1;
  350. }
  351. #endif /* SIGWINCH */
  352. return 0;
  353. }
  354. int
  355. rl_clear_signals ()
  356. {
  357. sighandler_cxt dummy;
  358. if (rl_catch_signals && signals_set_flag == 1)
  359. {
  360. sigemptyset (&dummy.sa_mask);
  361. rl_sigaction (SIGINT, &old_int, &dummy);
  362. rl_sigaction (SIGTERM, &old_term, &dummy);
  363. #if defined (SIGQUIT)
  364. rl_sigaction (SIGQUIT, &old_quit, &dummy);
  365. #endif
  366. #if defined (SIGALRM)
  367. rl_sigaction (SIGALRM, &old_alrm, &dummy);
  368. #endif
  369. #if defined (SIGTSTP)
  370. rl_sigaction (SIGTSTP, &old_tstp, &dummy);
  371. #endif /* SIGTSTP */
  372. #if defined (SIGTTOU)
  373. rl_sigaction (SIGTTOU, &old_ttou, &dummy);
  374. #endif /* SIGTTOU */
  375. #if defined (SIGTTIN)
  376. rl_sigaction (SIGTTIN, &old_ttin, &dummy);
  377. #endif /* SIGTTIN */
  378. signals_set_flag = 0;
  379. }
  380. #if defined (SIGWINCH)
  381. if (rl_catch_sigwinch && sigwinch_set_flag == 1)
  382. {
  383. sigemptyset (&dummy.sa_mask);
  384. rl_sigaction (SIGWINCH, &old_winch, &dummy);
  385. sigwinch_set_flag = 0;
  386. }
  387. #endif
  388. return 0;
  389. }
  390. /* Clean up the terminal and readline state after catching a signal, before
  391. resending it to the calling application. */
  392. void
  393. rl_cleanup_after_signal ()
  394. {
  395. _rl_clean_up_for_exit ();
  396. if (rl_deprep_term_function)
  397. (*rl_deprep_term_function) ();
  398. rl_clear_pending_input ();
  399. rl_clear_signals ();
  400. }
  401. /* Reset the terminal and readline state after a signal handler returns. */
  402. void
  403. rl_reset_after_signal ()
  404. {
  405. if (rl_prep_term_function)
  406. (*rl_prep_term_function) (_rl_meta_flag);
  407. rl_set_signals ();
  408. }
  409. /* Free up the readline variable line state for the current line (undo list,
  410. any partial history entry, any keyboard macros in progress, and any
  411. numeric arguments in process) after catching a signal, before calling
  412. rl_cleanup_after_signal(). */
  413. void
  414. rl_free_line_state ()
  415. {
  416. register HIST_ENTRY *entry;
  417. rl_free_undo_list ();
  418. entry = current_history ();
  419. if (entry)
  420. entry->data = (char *)NULL;
  421. _rl_kill_kbd_macro ();
  422. rl_clear_message ();
  423. _rl_reset_argument ();
  424. }
  425. #endif /* HANDLE_SIGNALS */
  426. /* **************************************************************** */
  427. /* */
  428. /* SIGINT Management */
  429. /* */
  430. /* **************************************************************** */
  431. #if defined (HAVE_POSIX_SIGNALS)
  432. static sigset_t sigint_set, sigint_oset;
  433. static sigset_t sigwinch_set, sigwinch_oset;
  434. #else /* !HAVE_POSIX_SIGNALS */
  435. # if defined (HAVE_BSD_SIGNALS)
  436. static int sigint_oldmask;
  437. static int sigwinch_oldmask;
  438. # endif /* HAVE_BSD_SIGNALS */
  439. #endif /* !HAVE_POSIX_SIGNALS */
  440. static int sigint_blocked;
  441. static int sigwinch_blocked;
  442. /* Cause SIGINT to not be delivered until the corresponding call to
  443. release_sigint(). */
  444. void
  445. _rl_block_sigint ()
  446. {
  447. if (sigint_blocked)
  448. return;
  449. #if defined (HAVE_POSIX_SIGNALS)
  450. sigemptyset (&sigint_set);
  451. sigemptyset (&sigint_oset);
  452. sigaddset (&sigint_set, SIGINT);
  453. sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
  454. #else /* !HAVE_POSIX_SIGNALS */
  455. # if defined (HAVE_BSD_SIGNALS)
  456. sigint_oldmask = sigblock (sigmask (SIGINT));
  457. # else /* !HAVE_BSD_SIGNALS */
  458. # if defined (HAVE_USG_SIGHOLD)
  459. sighold (SIGINT);
  460. # endif /* HAVE_USG_SIGHOLD */
  461. # endif /* !HAVE_BSD_SIGNALS */
  462. #endif /* !HAVE_POSIX_SIGNALS */
  463. sigint_blocked = 1;
  464. }
  465. /* Allow SIGINT to be delivered. */
  466. void
  467. _rl_release_sigint ()
  468. {
  469. if (sigint_blocked == 0)
  470. return;
  471. #if defined (HAVE_POSIX_SIGNALS)
  472. sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
  473. #else
  474. # if defined (HAVE_BSD_SIGNALS)
  475. sigsetmask (sigint_oldmask);
  476. # else /* !HAVE_BSD_SIGNALS */
  477. # if defined (HAVE_USG_SIGHOLD)
  478. sigrelse (SIGINT);
  479. # endif /* HAVE_USG_SIGHOLD */
  480. # endif /* !HAVE_BSD_SIGNALS */
  481. #endif /* !HAVE_POSIX_SIGNALS */
  482. sigint_blocked = 0;
  483. }
  484. #ifdef SIGWINCH
  485. /* Cause SIGWINCH to not be delivered until the corresponding call to
  486. release_sigwinch(). */
  487. void
  488. _rl_block_sigwinch ()
  489. {
  490. if (sigwinch_blocked)
  491. return;
  492. #if defined (HAVE_POSIX_SIGNALS)
  493. sigemptyset (&sigwinch_set);
  494. sigemptyset (&sigwinch_oset);
  495. sigaddset (&sigwinch_set, SIGWINCH);
  496. sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
  497. #else /* !HAVE_POSIX_SIGNALS */
  498. # if defined (HAVE_BSD_SIGNALS)
  499. sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
  500. # else /* !HAVE_BSD_SIGNALS */
  501. # if defined (HAVE_USG_SIGHOLD)
  502. sighold (SIGWINCH);
  503. # endif /* HAVE_USG_SIGHOLD */
  504. # endif /* !HAVE_BSD_SIGNALS */
  505. #endif /* !HAVE_POSIX_SIGNALS */
  506. sigwinch_blocked = 1;
  507. }
  508. /* Allow SIGWINCH to be delivered. */
  509. void
  510. _rl_release_sigwinch ()
  511. {
  512. if (sigwinch_blocked == 0)
  513. return;
  514. #if defined (HAVE_POSIX_SIGNALS)
  515. sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
  516. #else
  517. # if defined (HAVE_BSD_SIGNALS)
  518. sigsetmask (sigwinch_oldmask);
  519. # else /* !HAVE_BSD_SIGNALS */
  520. # if defined (HAVE_USG_SIGHOLD)
  521. sigrelse (SIGWINCH);
  522. # endif /* HAVE_USG_SIGHOLD */
  523. # endif /* !HAVE_BSD_SIGNALS */
  524. #endif /* !HAVE_POSIX_SIGNALS */
  525. sigwinch_blocked = 0;
  526. }
  527. #endif /* SIGWINCH */
  528. /* **************************************************************** */
  529. /* */
  530. /* Echoing special control characters */
  531. /* */
  532. /* **************************************************************** */
  533. void
  534. rl_echo_signal_char (sig)
  535. int sig;
  536. {
  537. char cstr[3];
  538. int cslen, c;
  539. if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
  540. return;
  541. switch (sig)
  542. {
  543. case SIGINT: c = _rl_intr_char; break;
  544. #if defined (SIGQUIT)
  545. case SIGQUIT: c = _rl_quit_char; break;
  546. #endif
  547. #if defined (SIGTSTP)
  548. case SIGTSTP: c = _rl_susp_char; break;
  549. #endif
  550. default: return;
  551. }
  552. if (CTRL_CHAR (c) || c == RUBOUT)
  553. {
  554. cstr[0] = '^';
  555. cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
  556. cstr[cslen = 2] = '\0';
  557. }
  558. else
  559. {
  560. cstr[0] = c;
  561. cstr[cslen = 1] = '\0';
  562. }
  563. _rl_output_some_chars (cstr, cslen);
  564. }