Provide a new result value, TERMKEY_RES_ERROR to indicate an IO error - preserve errno

This commit is contained in:
Paul LeoNerd Evans 2011-08-18 11:20:41 +01:00
parent 01e5795098
commit 7a2b79a640
5 changed files with 41 additions and 11 deletions

22
demo.c
View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <getopt.h>
#include <errno.h>
#include "termkey.h"
@ -44,13 +45,22 @@ int main(int argc, char *argv[])
printf("\e[?%dhMouse mode active\n", mouse);
while((ret = termkey_waitkey(tk, &key)) != TERMKEY_RES_EOF) {
termkey_strfkey(tk, buffer, sizeof buffer, &key, format);
printf("%s\n", buffer);
if(ret == TERMKEY_RES_KEY) {
termkey_strfkey(tk, buffer, sizeof buffer, &key, format);
printf("%s\n", buffer);
if(key.type == TERMKEY_TYPE_UNICODE &&
key.modifiers & TERMKEY_KEYMOD_CTRL &&
(key.code.codepoint == 'C' || key.code.codepoint == 'c'))
break;
if(key.type == TERMKEY_TYPE_UNICODE &&
key.modifiers & TERMKEY_KEYMOD_CTRL &&
(key.code.codepoint == 'C' || key.code.codepoint == 'c'))
break;
}
else if(ret == TERMKEY_RES_ERROR) {
if(errno != EINTR) {
perror("termkey_waitkey");
break;
}
printf("Interrupted by signal\n");
}
}
if(mouse)

View File

@ -607,6 +607,7 @@ static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nb
/* fallthrough */
case TERMKEY_RES_EOF:
case TERMKEY_RES_ERROR:
return ret;
case TERMKEY_RES_AGAIN:
@ -673,6 +674,7 @@ static TermKeyResult peekkey_simple(TermKey *tk, TermKeyKey *key, int force, siz
case TERMKEY_RES_NONE:
case TERMKEY_RES_EOF:
case TERMKEY_RES_AGAIN:
case TERMKEY_RES_ERROR:
break;
}
@ -821,10 +823,13 @@ TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key)
switch(ret) {
case TERMKEY_RES_KEY:
case TERMKEY_RES_EOF:
case TERMKEY_RES_ERROR:
return ret;
case TERMKEY_RES_NONE:
termkey_advisereadable(tk);
ret = termkey_advisereadable(tk);
if(ret == TERMKEY_RES_ERROR)
return ret;
break;
case TERMKEY_RES_AGAIN:
@ -839,13 +844,17 @@ TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key)
fd.fd = tk->fd;
fd.events = POLLIN;
poll(&fd, 1, tk->waittime);
int pollret = poll(&fd, 1, tk->waittime);
if(pollret == -1)
return TERMKEY_RES_ERROR;
if(fd.revents & (POLLIN|POLLHUP|POLLERR))
ret = termkey_advisereadable(tk);
else
ret = TERMKEY_RES_NONE;
if(ret == TERMKEY_RES_ERROR)
return ret;
if(ret == TERMKEY_RES_NONE)
return termkey_getkey_force(tk, key);
}
@ -877,8 +886,12 @@ TermKeyResult termkey_advisereadable(TermKey *tk)
unsigned char buffer[64]; // Smaller than the default size
ssize_t len = read(tk->fd, buffer, sizeof buffer);
if(len == -1 && (errno == EAGAIN || errno == EINTR))
return TERMKEY_RES_NONE;
if(len == -1) {
if(errno == EAGAIN)
return TERMKEY_RES_NONE;
else
return TERMKEY_RES_ERROR;
}
else if(len < 1) {
tk->is_closed = 1;
return TERMKEY_RES_NONE;

View File

@ -102,7 +102,8 @@ typedef enum {
TERMKEY_RES_NONE,
TERMKEY_RES_KEY,
TERMKEY_RES_EOF,
TERMKEY_RES_AGAIN
TERMKEY_RES_AGAIN,
TERMKEY_RES_ERROR
} TermKeyResult;
typedef enum {

View File

@ -23,6 +23,9 @@ At least one byte was read.
.TP
.B TERMKEY_RES_NONE
No nore bytes were read.
.TP
.B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_getkey (3),

View File

@ -25,6 +25,9 @@ A key event as been provided.
.TP
.B TERMKEY_RES_EOF
No key events are ready and the terminal has been closed, so no more will arrive.
.TP
.B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved.
.SH EXAMPLE
The following example program prints details of every keypress until the user presses "Ctrl-C".
.PP