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.
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
-----
(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
#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. */
}
#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);
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);
# 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
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