Provide a flag to return RES_ERROR even on signal (EINTR); without it, retry the operation

This commit is contained in:
Paul LeoNerd Evans 2011-08-25 10:48:41 +01:00
parent 7a2b79a640
commit 1b8234e342
5 changed files with 19 additions and 5 deletions

View File

@ -841,12 +841,17 @@ TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key)
struct pollfd fd; struct pollfd fd;
retry:
fd.fd = tk->fd; fd.fd = tk->fd;
fd.events = POLLIN; fd.events = POLLIN;
int pollret = poll(&fd, 1, tk->waittime); int pollret = poll(&fd, 1, tk->waittime);
if(pollret == -1) if(pollret == -1) {
if(errno == EINTR && !(tk->flags & TERMKEY_FLAG_EINTR))
goto retry;
return TERMKEY_RES_ERROR; return TERMKEY_RES_ERROR;
}
if(fd.revents & (POLLIN|POLLHUP|POLLERR)) if(fd.revents & (POLLIN|POLLHUP|POLLERR))
ret = termkey_advisereadable(tk); ret = termkey_advisereadable(tk);
@ -884,11 +889,16 @@ void termkey_pushinput(TermKey *tk, const unsigned char *input, size_t inputlen)
TermKeyResult termkey_advisereadable(TermKey *tk) TermKeyResult termkey_advisereadable(TermKey *tk)
{ {
unsigned char buffer[64]; // Smaller than the default size unsigned char buffer[64]; // Smaller than the default size
ssize_t len = read(tk->fd, buffer, sizeof buffer); ssize_t len;
retry:
len = read(tk->fd, buffer, sizeof buffer);
if(len == -1) { if(len == -1) {
if(errno == EAGAIN) if(errno == EAGAIN)
return TERMKEY_RES_NONE; return TERMKEY_RES_NONE;
else if(errno == EINTR && !(tk->flags & TERMKEY_FLAG_EINTR))
goto retry;
else else
return TERMKEY_RES_ERROR; return TERMKEY_RES_ERROR;
} }

View File

@ -145,7 +145,8 @@ enum {
TERMKEY_FLAG_UTF8 = 1 << 3, // Input is definitely UTF-8 TERMKEY_FLAG_UTF8 = 1 << 3, // Input is definitely UTF-8
TERMKEY_FLAG_NOTERMIOS = 1 << 4, // Do not make initial termios calls on construction TERMKEY_FLAG_NOTERMIOS = 1 << 4, // Do not make initial termios calls on construction
TERMKEY_FLAG_SPACESYMBOL = 1 << 5, // Space is symbolic rather than Unicode TERMKEY_FLAG_SPACESYMBOL = 1 << 5, // Space is symbolic rather than Unicode
TERMKEY_FLAG_CTRLC = 1 << 6 // Allow Ctrl-C to be read as normal, disabling SIGINT TERMKEY_FLAG_CTRLC = 1 << 6, // Allow Ctrl-C to be read as normal, disabling SIGINT
TERMKEY_FLAG_EINTR = 1 << 7 // Return ERROR on signal (EINTR) rather than retry
}; };
void termkey_check_version(int major, int minor); void termkey_check_version(int major, int minor);

View File

@ -25,7 +25,7 @@ At least one byte was read.
No nore bytes were read. No nore bytes were read.
.TP .TP
.B TERMKEY_RES_ERROR .B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved. An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR termkey_new (3), .BR termkey_new (3),
.BR termkey_getkey (3), .BR termkey_getkey (3),

View File

@ -42,6 +42,9 @@ Report space as being a symbolic key rather than a Unicode codepoint.
.TP .TP
.B TERMKEY_FLAG_CTRLC .B TERMKEY_FLAG_CTRLC
Disable the \fBSIGINT\fP behaviour of \fICtrl-C\fP. If this flag is provided, then \fICtrl-C\fP will be available as a normal keypress, rather than sending the process group a \fBSIGINT\fP. This flag only takes effect without \fBTERMKEY_FLAG_NOTERMIOS\fP; with it, none of the signal keys are disabled anyway. Disable the \fBSIGINT\fP behaviour of \fICtrl-C\fP. If this flag is provided, then \fICtrl-C\fP will be available as a normal keypress, rather than sending the process group a \fBSIGINT\fP. This flag only takes effect without \fBTERMKEY_FLAG_NOTERMIOS\fP; with it, none of the signal keys are disabled anyway.
.TP
.B TERMKEY_FLAG_EINTR
Without this flag, IO operations are retried when interrupted by a signal (\fBEINTR\fP). With this flag the \fBTERMKEY_RES_ERROR\fP result is returned instead.
.PP .PP
When the constructor is invoked, it attempts to detect if the current locale is UTF-8 aware or not, and sets either the \fBTERMKEY_FLAG_UTF8\fP or \fBTERMKEY_FLAG_RAW\fP flag. One of these two bits will always be in effect. The current flags in effect can be obtained by \fBtermkey_get_flags\fP(3). When the constructor is invoked, it attempts to detect if the current locale is UTF-8 aware or not, and sets either the \fBTERMKEY_FLAG_UTF8\fP or \fBTERMKEY_FLAG_RAW\fP flag. One of these two bits will always be in effect. The current flags in effect can be obtained by \fBtermkey_get_flags\fP(3).
.SH VERSION CHECK MACRO .SH VERSION CHECK MACRO

View File

@ -27,7 +27,7 @@ A key event as been provided.
No key events are ready and the terminal has been closed, so no more will arrive. No key events are ready and the terminal has been closed, so no more will arrive.
.TP .TP
.B TERMKEY_RES_ERROR .B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved. An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead.
.SH EXAMPLE .SH EXAMPLE
The following example program prints details of every keypress until the user presses "Ctrl-C". The following example program prints details of every keypress until the user presses "Ctrl-C".
.PP .PP