]> ruderich.org/simon Gitweb - coloredstderr/coloredstderr.git/commitdiff
tests: Add example_stdio.c and test_stdio.sh.
authorSimon Ruderich <simon@ruderich.org>
Sat, 22 Jun 2013 16:21:10 +0000 (18:21 +0200)
committerSimon Ruderich <simon@ruderich.org>
Sat, 22 Jun 2013 16:21:10 +0000 (18:21 +0200)
.gitignore
README
tests/Makefile.am
tests/example_stdio.c [new file with mode: 0644]
tests/example_stdio.expected [new file with mode: 0644]
tests/test_stdio.sh [new file with mode: 0755]

index a279991267fb9ded380eb2ff8f8f74d93b672f5d..9c247c8dadd6d5d8d2989df0ada644d9e681de18 100644 (file)
@@ -29,6 +29,8 @@
 /tests/example_error.o
 /tests/example_exec
 /tests/example_exec.o
+/tests/example_stdio
+/tests/example_stdio.o
 /tests/example_vfork
 /tests/example_vfork.o
 /tests/test_environment.sh.log
@@ -47,6 +49,8 @@
 /tests/test_redirects.sh.trs
 /tests/test_simple.sh.log
 /tests/test_simple.sh.trs
+/tests/test_stdio.sh.log
+/tests/test_stdio.sh.trs
 /tests/test_symbols.sh.log
 /tests/test_symbols.sh.trs
 /tests/test_vfork.sh.log
diff --git a/README b/README
index 79a40843429a4c66f346cf893be42c29f4834cb3..e298a04e6caee7eff1b0fd070aa4bbda0d460dd7 100644 (file)
--- a/README
+++ b/README
@@ -137,6 +137,14 @@ doesn't exist it's created. An existing file isn't overwritten, but the
 warnings are appended at the end.
 
 
+KNOWN ISSUES
+------------
+
+- `{fputc,putc,putchar}_unlocked()` are not hooked when writing to stdout
+  (which might be redirected to stderr). Can't be fixed as the compiler
+  inlines the code into the program without calling any function.
+
+
 BUGS
 ----
 
index 24f94e06294516878ec9bb4db9e1722c1aca5cdd..2863950306485812108060c9c9aaa65e1d3ca0ca 100644 (file)
@@ -6,8 +6,9 @@ TESTS = test_environment.sh \
         test_exec.sh \
         test_noforce.sh \
         test_redirects.sh \
-        test_simple.sh
-check_PROGRAMS = example example_exec
+        test_simple.sh \
+        test_stdio.sh
+check_PROGRAMS = example example_exec example_stdio
 
 if HAVE_ERR_H
     TESTS += test_err.sh
@@ -36,6 +37,7 @@ dist_check_DATA = example.h \
                   example_redirects.sh.expected \
                   example_simple.sh \
                   example_simple.sh.expected \
+                  example_stdio.expected \
                   example_vfork.expected
 
 # Used by lib.sh. Can't use "export EGREP" because it doesn't work with BSD's
diff --git a/tests/example_stdio.c b/tests/example_stdio.c
new file mode 100644 (file)
index 0000000..028b3f7
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Test all hooked stdio.h functions.
+ *
+ * Copyright (C) 2013  Simon Ruderich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+/* For {fwrite,fputs,fputc}_unlocked(), if available. */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "example.h"
+#include "../src/compiler.h"
+
+
+/* These are not in POSIX. */
+#ifndef HAVE_FWRITE_UNLOCKED
+static size_t fwrite_unlocked(void const *ptr, size_t size, size_t n, FILE *stream) {
+    return fwrite(ptr, size, n, stream);
+}
+#endif
+#ifndef HAVE_FPUTS_UNLOCKED
+static int fputs_unlocked(char const *s, FILE *stream) {
+    return fputs(s, stream);
+}
+#endif
+#ifndef HAVE_FPUTC_UNLOCKED
+static int fputc_unlocked(int c, FILE *stream) {
+    return fputc(c, stream);
+}
+#endif
+
+
+static int out;
+
+static void test_vprintf(char const *format, ...) noinline;
+static void test_vfprintf(FILE *stream, char const *format, ...) noinline;
+static void NEWLINE(void) noinline;
+
+static void test_vprintf(char const *format, ...) {
+    va_list ap;
+
+    va_start(ap, format);
+    vprintf(format, ap);
+    va_end(ap);
+}
+static void test_vfprintf(FILE *stream, char const *format, ...) {
+    va_list ap;
+
+    va_start(ap, format);
+    vfprintf(stream, format, ap);
+    va_end(ap);
+}
+
+static void NEWLINE(void) {
+    fflush(stdout);
+    fflush(stderr);
+    xwrite(out, "\n", 1);
+}
+
+
+int main(int argc, char **argv unused) {
+    /* stdout */
+
+    out = dup(STDOUT_FILENO);
+    if (out == -1) {
+        perror("dup");
+        return EXIT_FAILURE;
+    }
+
+    /* Redirect stdout to stderr so we can test all functions, including those
+     * not writing to stderr. */
+    xdup2(STDERR_FILENO, STDOUT_FILENO);
+
+    /* stdout redirected to stderr. */
+
+    xwrite(STDOUT_FILENO, "write()", 7); NEWLINE();
+    fwrite("fwrite()", 8, 1, stdout);   NEWLINE();
+
+    /* puts(3) */
+    fputs("fputs()", stdout); NEWLINE();
+    fputc('a', stdout);       NEWLINE();
+    putc('b', stdout);        NEWLINE();
+    putchar('c');             NEWLINE();
+    puts("puts()");           NEWLINE();
+
+    /* printf(3) */
+    printf("%s [%d]", "printf()", argc);                  NEWLINE();
+    fprintf(stdout, "%s [%d]", "fprintf()", argc);        NEWLINE();
+    test_vprintf("%s [%d]", "vprintf()", argc);           NEWLINE();
+    test_vfprintf(stdout, "%s [%d]", "vfprintf()", argc); NEWLINE();
+
+    /* unlocked_stdio(3) */
+    fwrite_unlocked("fwrite_unlocked()", 17, 1, stdout); NEWLINE();
+    fputs_unlocked("fputs_unlocked()", stdout);          NEWLINE();
+    /* FIXME: 'x', 'y' and 'z' are not colored */
+    fputc_unlocked('x', stdout);                         NEWLINE();
+    putc_unlocked('y', stdout);                          NEWLINE();
+    putchar_unlocked('z');                               NEWLINE();
+
+
+    /* stderr */
+
+    xwrite(STDERR_FILENO, "write()", 7); NEWLINE();
+    fwrite("fwrite()", 8, 1, stderr);   NEWLINE();
+
+    /* puts(3) */
+    fputs("fputs()", stderr); NEWLINE();
+    fputc('a', stderr);       NEWLINE();
+    putc('b', stderr);        NEWLINE();
+
+    /* printf(3) */
+    fprintf(stderr, "%s [%d]", "fprintf()", argc);        NEWLINE();
+    test_vfprintf(stderr, "%s [%d]", "vfprintf()", argc); NEWLINE();
+
+    /* unlocked_stdio(3) */
+    fwrite_unlocked("fwrite_unlocked()", 17, 1, stderr); NEWLINE();
+    fputs_unlocked("fputs_unlocked()", stderr);          NEWLINE();
+    fputc_unlocked('x', stderr);                         NEWLINE();
+    putc_unlocked('y', stderr);                          NEWLINE();
+
+    return EXIT_SUCCESS;
+}
diff --git a/tests/example_stdio.expected b/tests/example_stdio.expected
new file mode 100644 (file)
index 0000000..0ab9883
--- /dev/null
@@ -0,0 +1,28 @@
+>STDERR>write()<STDERR<
+>STDERR>fwrite()<STDERR<
+>STDERR>fputs()<STDERR<
+>STDERR>a<STDERR<
+>STDERR>b<STDERR<
+>STDERR>c<STDERR<
+>STDERR>puts()
+<STDERR<
+>STDERR>printf() [1]<STDERR<
+>STDERR>fprintf() [1]<STDERR<
+>STDERR>vprintf() [1]<STDERR<
+>STDERR>vfprintf() [1]<STDERR<
+>STDERR>fwrite_unlocked()<STDERR<
+>STDERR>fputs_unlocked()<STDERR<
+x
+y
+z
+>STDERR>write()<STDERR<
+>STDERR>fwrite()<STDERR<
+>STDERR>fputs()<STDERR<
+>STDERR>a<STDERR<
+>STDERR>b<STDERR<
+>STDERR>fprintf() [1]<STDERR<
+>STDERR>vfprintf() [1]<STDERR<
+>STDERR>fwrite_unlocked()<STDERR<
+>STDERR>fputs_unlocked()<STDERR<
+>STDERR>x<STDERR<
+>STDERR>y<STDERR<
diff --git a/tests/test_stdio.sh b/tests/test_stdio.sh
new file mode 100755 (executable)
index 0000000..5052698
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Copyright (C) 2013  Simon Ruderich
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+test "x$srcdir" = x && srcdir=.
+. "$srcdir/lib.sh"
+
+test_program          example_stdio
+test_program_subshell example_stdio