X-Git-Url: https://ruderich.org/simon/gitweb/?p=coloredstderr%2Fcoloredstderr.git;a=blobdiff_plain;f=src%2Fcoloredstderr.c;h=4664f0d1a8d0efb033fb11bf28814fc4a730d12c;hp=15581a622c30f15d437cd982244d88498ac45803;hb=2241f5278e786c429b8d657c807ead792b4b5b36;hpb=2fc66e15eb194ca1e54cd4df7f54bfdc3c87a3cd diff --git a/src/coloredstderr.c b/src/coloredstderr.c index 15581a6..4664f0d 100644 --- a/src/coloredstderr.c +++ b/src/coloredstderr.c @@ -81,6 +81,12 @@ static int force_write_to_non_tty; /* Was ENV_NAME_FDS found and used when init_from_environment() was called? * This is not true if the process set it manually after initialization. */ static int used_fds_set_by_user; +/* Was any of our handle_*_pre()/handle_*_post() functions called recursively? + * If so don't print the pre/post string for the recursive calls. This is + * necessary on some systems (e.g. FreeBSD 9.1) which call multiple hooked + * functions while printing a string (e.g. a FILE * and a fd hook function is + * called). */ +static int handle_recursive; #include "constants.h" @@ -181,6 +187,10 @@ static void handle_file_pre(FILE *stream) noinline; static void handle_file_post(FILE *stream) noinline; static void handle_fd_pre(int fd) { + if (handle_recursive++ > 0) { + return; + } + int saved_errno = errno; if (unlikely(!pre_string || !post_string)) { @@ -193,6 +203,10 @@ static void handle_fd_pre(int fd) { errno = saved_errno; } static void handle_fd_post(int fd) { + if (--handle_recursive > 0) { + return; + } + int saved_errno = errno; /* write() already loaded above in handle_fd_pre(). */ @@ -202,6 +216,10 @@ static void handle_fd_post(int fd) { } static void handle_file_pre(FILE *stream) { + if (handle_recursive++ > 0) { + return; + } + int saved_errno = errno; if (unlikely(!pre_string || !post_string)) { @@ -214,6 +232,10 @@ static void handle_file_pre(FILE *stream) { errno = saved_errno; } static void handle_file_post(FILE *stream) { + if (--handle_recursive > 0) { + return; + } + int saved_errno = errno; /* fwrite() already loaded above in handle_file_pre(). */ @@ -238,6 +260,14 @@ HOOK_FILE2(int, fputc, stream, int, c, FILE *, stream) HOOK_FILE2(int, putc, stream, int, c, FILE *, stream) +/* The glibc uses a macro for putc() which expands to _IO_putc(). However + * sometimes the raw putc() is used as well, not sure why. Make sure to hook + * it too. */ +#ifdef putc +# undef putc +HOOK_FILE2(int, putc, stream, + int, c, FILE *, stream) +#endif HOOK_FILE1(int, putchar, stdout, int, c) HOOK_FILE1(int, puts, stdout, @@ -646,10 +676,16 @@ HOOK_FUNC_DEF2(int, execvp, char const *, file, char * const *, argv) { #ifdef HAVE_EXECVPE extern char **environ; int execvpe(char const *file, char * const argv[], char * const envp[]) { + int result; + char **old_environ = environ; + /* Fake the environment so we can reuse execvp(). */ environ = (char **)envp; /* execvp() updates the environment. */ - return execvp(file, argv); + result = execvp(file, argv); + + environ = old_environ; + return result; } #endif