readline: Readline Signal Handling
2.5 Readline Signal Handling
============================
Signals are asynchronous events sent to a process by the Unix kernel,
sometimes on behalf of another process. They are intended to indicate
exceptional events, like a user pressing the interrupt key on his
terminal, or a network connection being broken. There is a class of
signals that can be sent to the process currently reading input from the
keyboard. Since Readline changes the terminal attributes when it is
called, it needs to perform special processing when such a signal is
received in order to restore the terminal to a sane state, or provide
application writers with functions to do so manually.
Readline contains an internal signal handler that is installed for a
number of signals ('SIGINT', 'SIGQUIT', 'SIGTERM', 'SIGHUP', 'SIGALRM',
'SIGTSTP', 'SIGTTIN', and 'SIGTTOU'). When one of these signals is
received, the signal handler will reset the terminal attributes to those
that were in effect before 'readline()' was called, reset the signal
handling to what it was before 'readline()' was called, and resend the
signal to the calling application. If and when the calling
application's signal handler returns, Readline will reinitialize the
terminal and continue to accept input. When a 'SIGINT' is received, the
Readline signal handler performs some additional work, which will cause
any partially-entered line to be aborted (see the description of
'rl_free_line_state()' below).
There is an additional Readline signal handler, for 'SIGWINCH', which
the kernel sends to a process whenever the terminal's size changes (for
example, if a user resizes an 'xterm'). The Readline 'SIGWINCH' handler
updates Readline's internal screen size information, and then calls any
'SIGWINCH' signal handler the calling application has installed.
Readline calls the application's 'SIGWINCH' signal handler without
resetting the terminal to its original state. If the application's
signal handler does more than update its idea of the terminal size and
return (for example, a 'longjmp' back to a main processing loop), it
_must_ call 'rl_cleanup_after_signal()' (described below), to restore
the terminal state.
When an application is using the callback interface (Alternate
Interface), Readline installs signal handlers only for the duration of
the call to 'rl_callback_read_char'. Applications using the callback
interface should be prepared to clean up Readline's state if they wish
to handle the signal before the line handler completes and restores the
terminal state.
If an application using the callback interface wishes to have
Readline install its signal handlers at the time the application calls
'rl_callback_handler_install' and remove them only when a complete line
of input has been read, it should set the
'rl_persistent_signal_handlers' variable to a non-zero value. This
allows an application to defer all of the handling of the signals
Readline catches to Readline. Applications should use this variable
with care; it can result in Readline catching signals and not acting on
them (or allowing the application to react to them) until the
application calls 'rl_callback_read_char'. This can result in an
application becoming less responsive to keyboard signals like SIGINT. If
an application does not want or need to perform any signal handling, or
does not need to do any processing between calls to
'rl_callback_read_char', setting this variable may be desirable.
Readline provides two variables that allow application writers to
control whether or not it will catch certain signals and act on them
when they are received. It is important that applications change the
values of these variables only when calling 'readline()', not in a
signal handler, so Readline's internal signal state is not corrupted.
-- Variable: int rl_catch_signals
If this variable is non-zero, Readline will install signal handlers
for 'SIGINT', 'SIGQUIT', 'SIGTERM', 'SIGHUP', 'SIGALRM', 'SIGTSTP',
'SIGTTIN', and 'SIGTTOU'.
The default value of 'rl_catch_signals' is 1.
-- Variable: int rl_catch_sigwinch
If this variable is set to a non-zero value, Readline will install
a signal handler for 'SIGWINCH'.
The default value of 'rl_catch_sigwinch' is 1.
-- Variable: int rl_persistent_signal_handlers
If an application using the callback interface wishes Readline's
signal handlers to be installed and active during the set of calls
to 'rl_callback_read_char' that constitutes an entire single line,
it should set this variable to a non-zero value.
The default value of 'rl_persistent_signal_handlers' is 0.
-- Variable: int rl_change_environment
If this variable is set to a non-zero value, and Readline is
handling 'SIGWINCH', Readline will modify the LINES and COLUMNS
environment variables upon receipt of a 'SIGWINCH'
The default value of 'rl_change_environment' is 1.
If an application does not wish to have Readline catch any signals,
or to handle signals other than those Readline catches ('SIGHUP', for
example), Readline provides convenience functions to do the necessary
terminal and internal state cleanup upon receipt of a signal.
-- Function: int rl_pending_signal (void)
Return the signal number of the most recent signal Readline
received but has not yet handled, or 0 if there is no pending
signal.
-- Function: void rl_cleanup_after_signal (void)
This function will reset the state of the terminal to what it was
before 'readline()' was called, and remove the Readline signal
handlers for all signals, depending on the values of
'rl_catch_signals' and 'rl_catch_sigwinch'.
-- Function: void rl_free_line_state (void)
This will free any partial state associated with the current input
line (undo information, any partial history entry, any
partially-entered keyboard macro, and any partially-entered numeric
argument). This should be called before
'rl_cleanup_after_signal()'. The Readline signal handler for
'SIGINT' calls this to abort the current input line.
-- Function: void rl_reset_after_signal (void)
This will reinitialize the terminal and reinstall any Readline
signal handlers, depending on the values of 'rl_catch_signals' and
'rl_catch_sigwinch'.
If an application does not wish Readline to catch 'SIGWINCH', it may
call 'rl_resize_terminal()' or 'rl_set_screen_size()' to force Readline
to update its idea of the terminal size when a 'SIGWINCH' is received.
-- Function: void rl_echo_signal_char (int sig)
If an application wishes to install its own signal handlers, but
still have readline display characters that generate signals,
calling this function with SIG set to 'SIGINT', 'SIGQUIT', or
'SIGTSTP' will display the character generating that signal.
-- Function: void rl_resize_terminal (void)
Update Readline's internal screen size by reading values from the
kernel.
-- Function: void rl_set_screen_size (int rows, int cols)
Set Readline's idea of the terminal size to ROWS rows and COLS
columns. If either ROWS or COLUMNS is less than or equal to 0,
Readline's idea of that terminal dimension is unchanged.
If an application does not want to install a 'SIGWINCH' handler, but
is still interested in the screen dimensions, Readline's idea of the
screen size may be queried.
-- Function: void rl_get_screen_size (int *rows, int *cols)
Return Readline's idea of the terminal's size in the variables
pointed to by the arguments.
-- Function: void rl_reset_screen_size (void)
Cause Readline to reobtain the screen size and recalculate its
dimensions.
The following functions install and remove Readline's signal
handlers.
-- Function: int rl_set_signals (void)
Install Readline's signal handler for 'SIGINT', 'SIGQUIT',
'SIGTERM', 'SIGHUP', 'SIGALRM', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU',
and 'SIGWINCH', depending on the values of 'rl_catch_signals' and
'rl_catch_sigwinch'.
-- Function: int rl_clear_signals (void)
Remove all of the Readline signal handlers installed by
'rl_set_signals()'.