Make the raw input console non-blocking with a timeout, allows handling
authorhpa <hpa>
Mon, 20 Dec 2004 22:28:30 +0000 (22:28 +0000)
committerhpa <hpa>
Mon, 20 Dec 2004 22:28:30 +0000 (22:28 +0000)
the [Esc] key.

com32/include/sys/times.h [new file with mode: 0644]
com32/lib/Makefile
com32/lib/fread.c
com32/lib/fwrite.c
com32/lib/sys/ansicon_write.c
com32/lib/sys/rawcon_read.c
com32/lib/sys/times.c [new file with mode: 0644]
com32/libutil/ansiraw.c
com32/libutil/get_key.c
com32/modules/Makefile

diff --git a/com32/include/sys/times.h b/com32/include/sys/times.h
new file mode 100644 (file)
index 0000000..173efe2
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * sys/times.h
+ */
+
+#ifndef _SYS_TIMES_H
+#define _SYS_TIMES_H
+
+#include <stdint.h>
+
+struct tms {
+  /* Empty */
+};
+
+#define HZ      18             /* Piddly resolution... */
+#define CLK_TCK        HZ
+
+typedef uint16_t clock_t;
+
+clock_t times(struct tms *);
+
+#endif /* _SYS_TIMES_H */
index 5f7551d..972c63c 100644 (file)
@@ -17,7 +17,7 @@ LIBOBJS = abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o     \
        libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o         \
        libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o      \
        libgcc/__divdi3.o libgcc/__moddi3.o                             \
-       sys/entry.o sys/exit.o sys/argv.o                               \
+       sys/entry.o sys/exit.o sys/argv.o sys/times.o                   \
        sys/fileinfo.o sys/opendev.o sys/read.o sys/write.o             \
        sys/close.o sys/open.o sys/fileread.o sys/fileclose.o           \
        sys/isatty.o sys/openconsole.o sys/line_input.o                 \
index 8f7dba9..76fdda8 100644 (file)
@@ -15,7 +15,7 @@ size_t _fread(void *buf, size_t count, FILE *f)
   while ( count ) {
     rv = read(fileno(f), p, count);
     if ( rv == -1 ) {
-      if ( errno == EINTR )
+      if ( errno == EINTR || errno == EAGAIN )
        continue;
       else
        break;
@@ -30,6 +30,3 @@ size_t _fread(void *buf, size_t count, FILE *f)
 
   return bytes;
 }
-
-    
-      
index 0a73188..fd7dab7 100644 (file)
@@ -15,7 +15,7 @@ size_t _fwrite(const void *buf, size_t count, FILE *f)
   while ( count ) {
     rv = write(fileno(f), p, count);
     if ( rv == -1 ) {
-      if ( errno == EINTR )
+      if ( errno == EINTR || errno == EAGAIN )
        continue;
       else
        break;
@@ -30,6 +30,3 @@ size_t _fwrite(const void *buf, size_t count, FILE *f)
 
   return bytes;
 }
-
-    
-      
index f7f0f86..4071087 100644 (file)
@@ -232,8 +232,8 @@ static void ansicon_putchar(int ch)
        case 'H':
        case 'f':
          {
-           int x = st.parms[0] - 1;
-           int y = st.parms[1] - 1;
+           int y = st.parms[0] - 1;
+           int x = st.parms[1] - 1;
 
            xy.x = (x >= cols) ? cols-1 : (x < 0) ? 0 : x;
            xy.y = (y >= rows) ? rows-1 : (y < 0) ? 0 : y;
index 23a742b..e767c7a 100644 (file)
 /*
  * rawcon_read.c
  *
- * Character-oriented reading from the console without echo
+ * Character-oriented reading from the console without echo, and with
+ * a timeout (50-100 ms).
  */
 
 #include <errno.h>
 #include <string.h>
 #include <com32.h>
 #include <minmax.h>
+#include <sys/times.h>
 #include "file.h"
 
 /* Global, since it's used by stdcon_read */
@@ -44,28 +46,41 @@ ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count)
   com32sys_t ireg, oreg;
   char *bufp = buf;
   size_t n = 0;
+  clock_t start;
 
   (void)fp;
 
   memset(&ireg, 0, sizeof ireg); 
 
+  start = times(NULL);
+
   while ( count ) {
-    ireg.eax.b[1]  = 0x08;
-    __intcall(0x21, &ireg, &oreg);
-    *bufp++ = oreg.eax.b[0];
-    n++;
-    
-    if ( ! --count )
+    if ( (clock_t)(times(NULL) - start) >= 2+CLK_TCK/20 )
       break;
 
-    /* Only return more than one if there is stuff in the buffer */
+    /* Poll */
     ireg.eax.b[1] = 0x0B;
     __intcall(0x21, &ireg, &oreg);
-    if ( !oreg.eax.b[0] )
-      break;
+    if ( !oreg.eax.b[0] ) {
+      if ( n )
+       break;                  /* We have data, deliver it */
+      else
+       continue;
+    }
+
+    /* We have data, go get it */
+    ireg.eax.b[1]  = 0x08;
+    __intcall(0x21, &ireg, &oreg);
+    *bufp++ = oreg.eax.b[0];
+    n++;
   }
 
-  return n;
+  if ( n == 0 ) {
+    errno = EAGAIN;
+    return -1;
+  } else {
+    return n;
+  }
 }
 
 const struct input_dev dev_rawcon_r = {
diff --git a/com32/lib/sys/times.c b/com32/lib/sys/times.c
new file mode 100644 (file)
index 0000000..b67a2a7
--- /dev/null
@@ -0,0 +1,45 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sys/times.c
+ *
+ * Returns something like a clock.
+ */
+
+#include <sys/times.h>
+#include <inttypes.h>
+#include <com32.h>
+
+clock_t times(struct tms *buf)
+{
+  (void)buf;                   /* Ignored */
+
+  /* Should we get this via INT 1Ah? */
+  return *(uint16_t *)0x46c;
+}
index 03c5752..0e6675a 100644 (file)
@@ -84,6 +84,8 @@ void console_ansi_raw(void)
   tio.c_iflag &= ~ICRNL;
   tio.c_iflag |= IGNCR;
   tio.c_lflag &= ~(ISIG|ICANON|ECHO);
+  tio.c_cc[VMIN]  = 0;
+  tio.c_cc[VTIME] = 2;
   tcsetattr(0, TCSANOW, &tio);
   fputs("\033[0m\033[20h", stdout);
 }
index 0239d23..e243761 100644 (file)
@@ -36,6 +36,8 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
+#include <unistd.h>
 #include <getkey.h>
 
 struct keycode {
@@ -110,16 +112,24 @@ static const struct keycode keycodes[] = {
 int get_key(FILE *f)
 {
   unsigned char buffer[MAXLEN];
-  int nc, ch, i;
+  int nc, i, rv;
   const struct keycode *kc;
   int another;
+  unsigned char ch;
 
   nc = 0;
   do {
-    ch = getc(f);
-
-    if ( ch == EOF )
+    rv = read(fileno(f), &ch, 1);
+    if ( rv == 0 )
       return EOF;
+    else if ( rv == -1 && errno == EAGAIN ) {
+      if ( nc )
+       return buffer[0];       /* timeout */
+      else {
+       another = 1;
+       continue;
+      }
+    }
 
     buffer[nc++] = ch;
 
@@ -128,7 +138,6 @@ int get_key(FILE *f)
       if ( nc == kc->seqlen && !memcmp(buffer, kc->seq, nc) )
        return kc->code;
       else if ( nc < kc->seqlen && !memcmp(buffer, kc->seq, nc) ) {
-       another = 1;
        break;
       }
     }
index 0037523..4b6f335 100644 (file)
@@ -45,7 +45,7 @@ AUXDIR   = $(LIBDIR)/syslinux
 INCDIR   = /usr/include
 COM32DIR = $(AUXDIR)/com32
 
-MODULES        = chain.c32 menu.c32 menu.lnx
+MODULES        = chain.c32 menu.c32 menu.lnx
 
 all: $(MODULES)