Last week saw a new version of
Term::TermKey (0.09), and also the underlying
libtermkey (0.9). This contains a fairly small new feature, giving control of the way that
EINTR is handled.
Version 0.8 added graceful handling of
EINTR to restart IO operations rather than fail with an error. This had unfortunate knock-on effects for the Perl-level wrapping of it, because of the deferred nature of Perl's safe signals. On a signal (such as the not-so-unlikely
SIGWINCH) a flag would be set, but the
termkey_waitkey(3) operation would be restarted, not returning back to Perl's control until a keypress event was actually received. This upset programs that wish to respond to
SIGWINCH and redraw the terminal to the new size.
Version 0.9 of
libtermkey now therefore has a new flag,
TERMKEY_FLAG_EINTR whose presence makes the blocking IO operations (
termkey_waitkey(3) and
termkey_advisereadable(3)) to return a new result code,
TERMKEY_RES_ERROR after which the caller can inspect the value of
errno, to observe an
EINTR.
Again because of Perl's safe signal handling, the Perl wrapping of
libtermkey has to always enable this flag, so it can invoke the
$SIG{WINCH} signal handler, for example. The
Term::TermKey module therefore now always sets
TERMKEY_FLAG_EINTR on the underlying
TermKey instance, and emulates the presence or absence of this flag at the Perl level, by optionally restarting its IO operation, or itself returning
TERMKEY_RES_ERROR.
An unfortunate bug here in the emulation and hiding of this flag from the Perl level means that
Term::TermKey 0.09 fails to correctly read the
TermKey flags back out of the underlying object. In particular it fails to be able to check on the presence of
TERMKEY_FLAG_UTF8 that
libtermkey itself may have enabled, after detecting a
UTF-8 locale. This causes
Tickit's unit tests to break with the familiar
"Wide character in syswrite at ..." error.
This bug has now been fixed in the source code repository, and will be present in the next version, 0.10.
Tickit 0.10 also has an independent fix for the same bug, by using Perl's
${^UTF8LOCALE} instead of reading the
TermKey flags back out again.
Also upcoming in
libtermkey 0.10, will be some Solaris portability fixes, and a new canonicalisation flag, which turns a
TERMKEY_SYM_DEL key into
TERMKEY_SYM_BACKSPACE, for those terminals that send
DEL on Backspace.