]> git.refcnt.org Git - colorize.git/commitdiff
stdin: use nonblocking mode
authorSteven Schubiger <stsc@refcnt.org>
Sun, 3 Nov 2024 20:07:17 +0000 (21:07 +0100)
committerSteven Schubiger <stsc@refcnt.org>
Sun, 3 Nov 2024 20:07:17 +0000 (21:07 +0100)
colorize.c

index eb8f7c084c257789ec64e5453fb00d66e942cf56..da03804a57bb57b87fe15f831f394b9870ef301f 100644 (file)
@@ -26,6 +26,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <pwd.h>
 #include <stdarg.h>
@@ -403,6 +404,12 @@ main (int argc, char **argv)
     program_name = argv[0];
     atexit (cleanup);
 
+    if (fcntl (STDIN_FILENO, F_SETFL, fcntl (STDIN_FILENO, F_GETFL) | O_NONBLOCK) == -1)
+      {
+        perror ("fcntl");
+        exit (EXIT_FAILURE);
+      }
+
     setvbuf (stdout, NULL, _IOLBF, 0);
 
 #if DEBUG
@@ -1348,9 +1355,16 @@ read_print_stream (const char *attr, const struct color **colors, const char *fi
         size_t bytes_read;
         char *eol;
         const char *line;
+        bool sleep = false;
+        errno = 0;
         bytes_read = fread (buf, 1, BUF_SIZE, stream);
-        if (bytes_read != BUF_SIZE && ferror (stream))
-          vfprintf_fail (formats[FMT_ERROR], BUF_SIZE, "read");
+        if (bytes_read != BUF_SIZE)
+          {
+            if (errno == EAGAIN || errno == EWOULDBLOCK)
+              sleep = true;
+            else if (fileno (stream) != STDIN_FILENO && ferror (stream))
+              vfprintf_fail (formats[FMT_ERROR], BUF_SIZE, "read");
+          }
         buf[bytes_read] = '\0';
         line = buf;
         while ((eol = strpbrk (line, "\n\r")))
@@ -1389,6 +1403,24 @@ read_print_stream (const char *attr, const struct color **colors, const char *fi
             else
               print_line (attr, colors, line, 0, true);
           }
+        if (sleep)
+          {
+            /* This entire construct is a bit of a hack...
+               I don't see /currently/ how it could be properly converted
+               to using open() and friends with {poll,select}().
+
+               It has been tested on older hardware to assert that the
+               performance loss should only be minimal...
+
+               -stsc / 2024-11-03
+            */
+            const struct timespec ts = { 0, 50000000L }; /* pause 50ms */
+            if (nanosleep (&ts, NULL) == -1)
+              {
+                perror ("nanosleep");
+                exit (EXIT_FAILURE);
+              }
+          }
       }
 }