From 7a2b79a6402979b4895e78657d59a770d5b082b3 Mon Sep 17 00:00:00 2001 From: Paul LeoNerd Evans Date: Thu, 18 Aug 2011 11:20:41 +0100 Subject: [PATCH] Provide a new result value, TERMKEY_RES_ERROR to indicate an IO error - preserve errno --- demo.c | 22 ++++++++++++++++------ termkey.c | 21 +++++++++++++++++---- termkey.h.in | 3 ++- termkey_advisereadable.3 | 3 +++ termkey_waitkey.3.sh | 3 +++ 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/demo.c b/demo.c index de3f511..11d85f2 100644 --- a/demo.c +++ b/demo.c @@ -1,5 +1,6 @@ #include #include +#include #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) diff --git a/termkey.c b/termkey.c index 60d76e8..dd1020b 100644 --- a/termkey.c +++ b/termkey.c @@ -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; diff --git a/termkey.h.in b/termkey.h.in index c91f954..33360d8 100644 --- a/termkey.h.in +++ b/termkey.h.in @@ -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 { diff --git a/termkey_advisereadable.3 b/termkey_advisereadable.3 index 8b4b6af..ba859ca 100644 --- a/termkey_advisereadable.3 +++ b/termkey_advisereadable.3 @@ -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), diff --git a/termkey_waitkey.3.sh b/termkey_waitkey.3.sh index 14f4f71..81d9f6e 100644 --- a/termkey_waitkey.3.sh +++ b/termkey_waitkey.3.sh @@ -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