/*
* Utility functions to track file descriptors.
*
- * Copyright (C) 2013 Simon Ruderich
+ * Copyright (C) 2013-2014 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
}
#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);
int saved_errno = errno;
+ assert(!initialized);
+
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);
goto next;
}
- if (i == count) {
- break;
- }
-
/* Replace ',' to null-terminate number for atoi(). */
*x = 0;
return 0;
}
- if (fd < TRACKFDS_STATIC_COUNT) {
+ if (likely(fd < TRACKFDS_STATIC_COUNT)) {
return tracked_fds[fd];
}