X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=src%2Ftrackfds.h;h=67b956238d0a2cec08583b760ca792475ff56128;hb=7337375e052aa1eeebc681c7c5b78aa242329339;hp=07cfaa11a5f444ef4f09ef7f11fad79a65ad799c;hpb=df4c9eab977217103184d91105f4b38ba956a06b;p=coloredstderr%2Fcoloredstderr.git diff --git a/src/trackfds.h b/src/trackfds.h index 07cfaa1..67b9562 100644 --- a/src/trackfds.h +++ b/src/trackfds.h @@ -21,23 +21,38 @@ #define TRACKFDS_H 1 /* List of tracked file descriptors. */ -static int *tracked_fds; +static int *tracked_fds_list; /* Current number of items in the list. */ -static size_t tracked_fds_count; +static size_t tracked_fds_list_count; /* Allocated items, used to reduce realloc()s. */ -static size_t tracked_fds_space; +static size_t tracked_fds_list_space; +#ifdef DEBUG +static void tracked_fds_debug(void) { + debug(" tracked_fds_list: %d/%d\t\t[%d]\n", tracked_fds_list_count, + tracked_fds_list_space, + getpid()); + size_t i; + for (i = 0; i < tracked_fds_list_count; i++) { + debug(" tracked_fds_list[%d]: %d\n", i, tracked_fds_list[i]); + } +} +#endif + /* Load tracked file descriptors from the environment. The environment is used * to pass the information to child processes. * * ENV_NAME_FDS has the following format: Each descriptor as string followed * by a comma; there's a trailing comma. Example: "2,4,". */ static void init_from_environment(void) { +#ifdef DEBUG + debug("init_from_environment()\t\t[%d]\n", getpid()); +#endif const char *env; initialized = 1; - tracked_fds_count = 0; + tracked_fds_list_count = 0; /* 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. */ @@ -51,10 +66,8 @@ static void init_from_environment(void) { return; } /* Environment is read-only. */ - char *env_copy = strdup(env); - if (!env_copy) { - return; - } + char env_copy[strlen(env) + 1]; + strcpy(env_copy, env); char *x; @@ -64,18 +77,21 @@ static void init_from_environment(void) { count++; } } - tracked_fds_space = count + TRACKFDS_REALLOC_STEP; + tracked_fds_list_space = count + TRACKFDS_REALLOC_STEP; - tracked_fds = malloc(tracked_fds_space * sizeof(*tracked_fds)); - if (!tracked_fds) { - free(env_copy); + tracked_fds_list = malloc(tracked_fds_list_space * sizeof(*tracked_fds_list)); + if (!tracked_fds_list) { +#ifdef DEBUG + warning("malloc(%zu): failed [%d]\n", + tracked_fds_list_space * sizeof(*tracked_fds_list), getpid()); +#endif return; } size_t i = 0; /* Parse file descriptor numbers from environment string and store them as - * integers in tracked_fds. */ + * integers in tracked_fds_list. */ char *last; for (x = env_copy, last = env_copy; *x; x++) { if (*x != ',') { @@ -92,30 +108,28 @@ static void init_from_environment(void) { } *x = 0; - tracked_fds[i++] = atoi(last); + tracked_fds_list[i++] = atoi(last); last = x + 1; } - tracked_fds_count = count; + tracked_fds_list_count = count; - free(env_copy); +#ifdef DEBUG + tracked_fds_debug(); +#endif } -static void update_environment(void) { - /* An integer (32-bit) has at most 10 digits, + 1 for the comma after each - * number. Bigger file descriptors (which shouldn't occur in reality) are - * skipped. */ - char env[tracked_fds_count * (10 + 1) + 1 /* to fit '\0' */ ]; - env[0] = 0; - - char *x = env; - +static void update_environment_buffer(char *x) { size_t i; - for (i = 0; i < tracked_fds_count; i++) { - int length = snprintf(x, 10 + 1, "%d", tracked_fds[i]); + for (i = 0; i < tracked_fds_list_count; i++) { + int length = snprintf(x, 10 + 1, "%d", tracked_fds_list[i]); if (length >= 10 + 1) { - /* Integer too bit to fit the buffer, skip it. */ + /* Integer too big to fit the buffer, skip it. */ +#ifdef DEBUG + warning("update_environment_buffer_entry(): truncated fd: %d [%d]\n", + tracked_fds_list[i], getpid()); +#endif continue; } @@ -125,52 +139,77 @@ static void update_environment(void) { /* Make sure the string is always zero terminated. */ *x = 0; } +} +inline static size_t update_environment_buffer_size(void) { + /* An integer (32-bit) has at most 10 digits, + 1 for the comma after each + * number. Bigger file descriptors (which shouldn't occur in reality) are + * skipped. */ + return tracked_fds_list_count * (10 + 1) + 1 /* to fit '\0' */; +} +static void update_environment(void) { +#ifdef DEBUG + debug("update_environment()\t\t[%d]\n", getpid()); +#endif + + /* If we haven't parsed the environment we also haven't modified it - so + * nothing to do. */ + if (!initialized) { + return; + } + + char env[update_environment_buffer_size()]; + env[0] = 0; + + update_environment_buffer(env); + +#if 0 + debug(" setenv('%s', '%s', 1)\n", ENV_NAME_FDS, env); +#endif setenv(ENV_NAME_FDS, env, 1 /* overwrite */); } -#ifdef DEBUG -static void tracked_fds_debug(void) { - debug("tracked_fds: %d/%d\t[%d]\n", tracked_fds_count, tracked_fds_space, - getpid()); - size_t i; - for (i = 0; i < tracked_fds_count; i++) { - debug("tracked_fds[%d]: %d\n", i, tracked_fds[i]); - } -} -#endif static void tracked_fds_add(int fd) { - if (tracked_fds_count >= tracked_fds_space) { - size_t new_space = tracked_fds_space + TRACKFDS_REALLOC_STEP; - if (!realloc(tracked_fds, sizeof(*tracked_fds) * new_space)) { + if (tracked_fds_list_count >= tracked_fds_list_space) { + size_t new_space = tracked_fds_list_space + TRACKFDS_REALLOC_STEP; + int *tmp = realloc(tracked_fds_list, + sizeof(*tracked_fds_list) * new_space); + if (!tmp) { /* We can do nothing, just ignore the error. We made sure not to * destroy our state, so the new descriptor is ignored without any * other consequences. */ +#ifdef DEBUG + warning("realloc(tracked_fds_list, %zu) failed! [%d]\n", + sizeof(*tracked_fds_list) * new_space, getpid()); +#endif return; } - tracked_fds_space = new_space; + tracked_fds_list = tmp; + tracked_fds_list_space = new_space; } - tracked_fds[tracked_fds_count++] = fd; + tracked_fds_list[tracked_fds_list_count++] = fd; #ifdef DEBUG + debug("tracked_fds_add(): %-3d\t\t[%d]\n", fd, getpid()); tracked_fds_debug(); #endif } static int tracked_fds_remove(int fd) { size_t i; - for (i = 0; i < tracked_fds_count; i++) { - if (fd != tracked_fds[i]) { + for (i = 0; i < tracked_fds_list_count; i++) { + if (fd != tracked_fds_list[i]) { continue; } - memmove(tracked_fds + i, tracked_fds + i + 1, - sizeof(*tracked_fds) * (tracked_fds_count - i - 1)); - tracked_fds_count--; + memmove(tracked_fds_list + i, tracked_fds_list + i + 1, + sizeof(*tracked_fds_list) * (tracked_fds_list_count - i - 1)); + tracked_fds_list_count--; #ifdef DEBUG + debug("tracked_fds_remove(): %-3d\t[%d]\n", fd, getpid()); tracked_fds_debug(); #endif @@ -183,8 +222,8 @@ static int tracked_fds_remove(int fd) { } static int tracked_fds_find(int fd) { size_t i; - for (i = 0; i < tracked_fds_count; i++) { - if (fd == tracked_fds[i]) { + for (i = 0; i < tracked_fds_list_count; i++) { + if (fd == tracked_fds_list[i]) { return 1; } }