]> ruderich.org/simon Gitweb - coloredstderr/coloredstderr.git/blobdiff - src/coloredstderr.c
Hook __overflow() correctly.
[coloredstderr/coloredstderr.git] / src / coloredstderr.c
index 247bd06ecc0d78cfd085574a7665a53b3a40b328..85b2b941b88f9d76c58a0f14eb0dd4181dc3a3c9 100644 (file)
@@ -36,6 +36,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #ifdef HAVE_ERR_H
 # include <libio.h>
 #endif
 
-/* Conflicting declaration in glibc. */
-#undef fwrite_unlocked
-/* These functions may be macros when compiling with hardening flags (fortify)
- * which cause build failures when used in our hook macros below. Observed
- * with Clang on Debian Wheezy. */
+/* The following functions may be macros. Undefine them or they cause build
+ * failures when used in our hook macros below. */
+
+/* In glibc, real fwrite_unlocked() is called in macro. */
+#ifdef HAVE_FWRITE_UNLOCKED
+# undef fwrite_unlocked
+#endif
+/* In Clang when compiling with hardening flags (fortify) on Debian Wheezy. */
 #undef printf
 #undef fprintf
 
@@ -249,19 +253,31 @@ HOOK_FILE4(int, __vfprintf_chk, stream,
            FILE *, stream, int, flag, char const *, format, va_list, ap)
 
 /* unlocked_stdio(3), only functions from above are hooked */
+#ifdef HAVE_FWRITE_UNLOCKED
 HOOK_FILE4(size_t, fwrite_unlocked, stream,
            void const *, ptr, size_t, size, size_t, nmemb, FILE *, stream)
+#endif
+#ifdef HAVE_FPUTS_UNLOCKED
 HOOK_FILE2(int, fputs_unlocked, stream,
            char const *, s, FILE *, stream)
+#endif
+#ifdef HAVE_FPUTC_UNLOCKED
 HOOK_FILE2(int, fputc_unlocked, stream,
            int, c, FILE *, stream)
+#endif
 HOOK_FILE2(int, putc_unlocked, stream,
            int, c, FILE *, stream)
 HOOK_FILE1(int, putchar_unlocked, stdout,
            int, c)
-/* glibc defines (_IO_)putc_unlocked() to __overflow() in some cases. */
+/* glibc defines (_IO_)putc_unlocked() to a macro which either updates the
+ * output buffer or calls __overflow(). As this code is inlined we can't
+ * handle the first case, but if __overflow() is called we can color that
+ * part. As writes to stderr are never buffered, __overflow() is always called
+ * and everything works fine. This is only a problem if stdout is dupped to
+ * stderr (which shouldn't be the case too often). */
 #ifdef HAVE_STRUCT__IO_FILE__FILENO
-HOOK_FD2(int, __overflow, f->_fileno, _IO_FILE *, f, int, ch)
+/* _IO_FILE is glibc's representation of FILE. */
+HOOK_FILE2(int, __overflow, f, _IO_FILE *, f, int, ch)
 #endif
 
 /* perror(3) */