aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul LeoNerd Evans <leonerd@leonerd.org.uk>2011-08-18 11:20:41 +0100
committerPaul LeoNerd Evans <leonerd@leonerd.org.uk>2011-08-18 11:20:41 +0100
commit7a2b79a6402979b4895e78657d59a770d5b082b3 (patch)
tree06105525116545218b02d5b995d80f451f8e3536
parent01e5795098bea0fecb29e69e702225cb236dd6f8 (diff)
downloadtermo-7a2b79a6402979b4895e78657d59a770d5b082b3.tar.gz
termo-7a2b79a6402979b4895e78657d59a770d5b082b3.tar.xz
termo-7a2b79a6402979b4895e78657d59a770d5b082b3.zip
Provide a new result value, TERMKEY_RES_ERROR to indicate an IO error - preserve errno
-rw-r--r--demo.c22
-rw-r--r--termkey.c21
-rw-r--r--termkey.h.in3
-rw-r--r--termkey_advisereadable.33
-rw-r--r--termkey_waitkey.3.sh3
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 <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)
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