Avoiding SIGINT
node
changes the meaning of CTRL-C by unsetting its interrupt character VINTR
(usually CTRL-C) to avoid the interrupt signal that it would otherwise get.
After starting up, rlwrap
is sleeping all the time, until something happens on your terminal or on the pseudo-terminal (pty
) used by e.g. node
. This "something" can be a keypress by you, or output from node
.
Every time this happens, rlwrap
will copy nodes
s terminal settings (including VINTR
) ) to its own tty.
However, if node
only changes its terminal settings, this, by itself, won't wake up rlwrap
, which will thus keep the old settings on its own tty. Transparency will then be broken: When you press CTRL-C rlwrap
will still interpret it as a SIGINT
, while node
would have understood a .break
command.
There ia a special, very obscure, pty
mode (EXTPROC) that allows the pty master (rlwrap
) to be woken up by a slave's changes in terminal settings, but this is very un-portable. This is why, since version 0.41, rlwrap
has the much less elegant --polling
option that makes it wake up every 40 milliseconds and copy the slave's terminal settings.
Forward CTRL-C
Starting with version 0.43, rlwrap
can directly forward special keys even when in readline mode by binding
such a key to rlwrap-direct-keypress
in ~/.inputrc
:
$if node
"\C-c": rlwrap-direct-keypress
$endif
However, node
only gives CTRL+C special treatment when it itself uses readline (try NODE_NO_READLINE=1 node
and then type CTRL-C) to see what I mean)
In such cases (i.e. when a command does its own line editing), one has to force rlwrap
into readline mode:
$ rlwrap --always-readline node
This has the unfortunate and unavoidable drawback that whanever a command asks for single
keypresses (Continue? Y/N
) one has to type an
extra Enter.
And then there still is the problem sketched above: if the terminal's interrupt character is not changed, node
will never see the CTRL-C (but get a SIGINT
instead)
There are two solutions. Either:
stty intr undef # disable interrupt character
rlwrap --always-readline node
stty intr '^c' # re-enable CTRL-C
or:
rlwrap --polling --always-readline node # --polling means: continually wake up and wacth node's interrupt character
Wrapping up
To make a long story short:
- Add
"\C-c": rlwrap-direct-keypress
to your inputc
- Temporarily unset the terminal's interrupt character, or use
rlwrap --polling --always-readline
as above
- Try to live with the extra Enter for single keypresses
rlwrap-direct-keypress
without success. – Jackass