From b950cdb79209e092d20d629bd1b0e9211647bd1e Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sun, 7 Jul 2013 13:33:44 +0200 Subject: [PATCH] Add COLORED_STDERR_IGNORED_BINARIES to exclude binaries. --- README | 12 ++++++++++ src/constants.h | 1 + src/trackfds.h | 46 +++++++++++++++++++++++++++++++++++++++ tests/lib.sh | 1 + tests/test_environment.sh | 17 +++++++++++++++ 5 files changed, 77 insertions(+) diff --git a/README b/README index e9772b4..4827509 100644 --- a/README +++ b/README @@ -93,6 +93,10 @@ The following additional environment variables are available: If set to an non-empty value add pre/post strings even when not writing to a terminal, e.g. when writing to a file. By default, only writes to a terminal are colored. +- 'COLORED_STDERR_IGNORED_BINARIES' + Comma separated list of binary names/paths which should not be tracked + (including their children). Useful for `reset` which writes to the terminal + but fails to work if the output is colored. See below for an example. All environment variables starting with 'COLORED_STDERR_PRIVATE_*' are internal variables used by the implementation and should not be set manually. @@ -113,6 +117,12 @@ Bourne shell: COLORED_STDERR_POST="${esc}[0m" # default export COLORED_STDERR_PRE COLORED_STDERR_POST +Fix `reset`; its writes to the terminal must be unaltered. `reset` is +symbolic-link to `tset` on some systems, adapt as necessary: + + COLORED_STDERR_IGNORED_BINARIES=/usr/bin/tset + export COLORED_STDERR_IGNORED_BINARIES + DEBUG ----- @@ -143,6 +153,8 @@ KNOWN ISSUES (which might be redirected to stderr). Can't be fixed as the compiler inlines the code into the program without calling any function. - Test `test_stdio.sh` fails for this reason on FreeBSD. +- 'COLORED_STDERR_IGNORED_BINARIES' requries the `/proc` file system. + Suggestions welcome. BUGS diff --git a/src/constants.h b/src/constants.h index 3e41261..45650ff 100644 --- a/src/constants.h +++ b/src/constants.h @@ -25,6 +25,7 @@ #define ENV_NAME_PRE_STRING "COLORED_STDERR_PRE" #define ENV_NAME_POST_STRING "COLORED_STDERR_POST" #define ENV_NAME_FORCE_WRITE "COLORED_STDERR_FORCE_WRITE" +#define ENV_NAME_IGNORED_BINARIES "COLORED_STDERR_IGNORED_BINARIES" #define ENV_NAME_PRIVATE_FDS "COLORED_STDERR_PRIVATE_FDS" /* Strings written before/after each matched function. */ diff --git a/src/trackfds.h b/src/trackfds.h index 5720b0c..28b38fb 100644 --- a/src/trackfds.h +++ b/src/trackfds.h @@ -50,6 +50,36 @@ static void tracked_fds_debug(void) { } #endif +/* Check if filename occurs in the comma-separated list ignore. */ +static int is_program_ignored(char const *filename, char const *ignore) { + size_t length; + size_t filename_length = strlen(filename); + +#ifdef DEBUG + debug(" is_program_ignored(\"%s\", \"%s\")\n", filename, ignore); +#endif + + for (; *ignore; ignore += length) { + while (*ignore == ',') { + ignore++; + } + + length = strcspn(ignore, ","); + if (length == 0) { + break; + } + + if (length != filename_length) { + continue; + } + if (!strncmp(filename, ignore, length)) { + return 1; + } + } + + return 0; +} + static int init_tracked_fds_list(size_t count) { assert(count > 0); @@ -88,6 +118,22 @@ static void init_from_environment(void) { initialized = 1; tracked_fds_list_count = 0; + /* Don't color writes to stderr for this binary (and its children) if it's + * contained in the comma-separated list in ENV_NAME_IGNORED_BINARIES. */ + env = getenv(ENV_NAME_IGNORED_BINARIES); + if (env) { + char path[512]; + + /* TODO: Don't require /proc/. */ + ssize_t written = readlink("/proc/self/exe", path, sizeof(path) - 1); + if (written > 0) { + path[written] = 0; /* readlink() does not null-terminate! */ + if (is_program_ignored(path, env)) { + return; + } + } + } + /* If ENV_NAME_FORCE_WRITE is set and not empty, allow writes to a non-tty * device. Use with care! Mainly used for the test suite. */ env = getenv(ENV_NAME_FORCE_WRITE); diff --git a/tests/lib.sh b/tests/lib.sh index 33a3721..7face08 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -20,6 +20,7 @@ set -e # Allow running the script directly without running `make check`. test "x$builddir" = x && builddir=. +test "x$abs_builddir" = x && abs_builddir="`pwd`" test "x$EGREP" = x && EGREP='grep -E' # The tests fail if running under coloredstderr because the tests redirect diff --git a/tests/test_environment.sh b/tests/test_environment.sh index 47a02a2..d402472 100755 --- a/tests/test_environment.sh +++ b/tests/test_environment.sh @@ -59,3 +59,20 @@ COLORED_STDERR_FDS= export COLORED_STDERR_FDS test_program example example_environment_empty test_program_subshell example example_environment_empty + +unset COLORED_STDERR_FDS + + +# Test COLORED_STDERR_IGNORED_BINARIES. + +if test -x /proc/self/exe; then + COLORED_STDERR_IGNORED_BINARIES="$abs_builddir/example" + export COLORED_STDERR_IGNORED_BINARIES + test_program example example_environment_empty + test_program_subshell example example_environment_empty + + COLORED_STDERR_IGNORED_BINARIES=",some,other,path,," + export COLORED_STDERR_IGNORED_BINARIES + test_program example example_environment + test_program_subshell example example_environment +fi -- 2.43.2