commit d04402b6eab409cb37955429ee8a33b45fb2e4dd
Author:     Quentin Rameau <[email protected]>
AuthorDate: Tue Mar 1 11:04:11 2016 +0100
Commit:     sin <[email protected]>
CommitDate: Tue Mar 1 11:14:42 2016 +0000

    cat: fix u flag
    
    Our libutil concat() always uses a buffer for input wich is obviously
    not compatible with unbuffered io. Here is a local uconcat() which
    naively copies input to stdout char by char.

diff --git a/cat.c b/cat.c
index c36657d..e3741aa 100644
--- a/cat.c
+++ b/cat.c
@@ -7,6 +7,16 @@
 #include "util.h"
 
 static void
+uconcat(FILE *fp1, const char *s1, FILE *fp2, const char *s2)
+{
+       int c;
+
+       setbuf(fp2, NULL);
+       while ((c = getc(fp1)) != EOF)
+               putc(c, fp2);
+}
+
+static void
 usage(void)
 {
        eprintf("usage: %s [-u] [file ...]\n", argv0);
@@ -17,17 +27,18 @@ main(int argc, char *argv[])
 {
        FILE *fp;
        int ret = 0;
+       void (*cat)(FILE *, const char *, FILE *, const char *) = &concat;
 
        ARGBEGIN {
        case 'u':
-               setbuf(stdout, NULL);
+               cat = &uconcat;
                break;
        default:
                usage();
        } ARGEND
 
        if (!argc) {
-               concat(stdin, "<stdin>", stdout, "<stdout>");
+               cat(stdin, "<stdin>", stdout, "<stdout>");
        } else {
                for (; *argv; argc--, argv++) {
                        if (!strcmp(*argv, "-")) {
@@ -38,7 +49,7 @@ main(int argc, char *argv[])
                                ret = 1;
                                continue;
                        }
-                       concat(fp, *argv, stdout, "<stdout>");
+                       cat(fp, *argv, stdout, "<stdout>");
                        if (fp != stdin && fshut(fp, *argv))
                                ret = 1;
                }

Reply via email to