diff options
author | Wolfgang Hommel <wolf@code-wizards.com> | 2022-02-25 21:25:58 +0100 |
---|---|---|
committer | Wolfgang Hommel <wolf@code-wizards.com> | 2022-02-25 21:25:58 +0100 |
commit | 36090e8ceba3dd0cc9478403eacf5949530ab6d9 (patch) | |
tree | ee14c610b1020c9367045e1289602241334b43ad | |
parent | 0e61d3d1917f530b5e3f66db2ed5dd6acd20e798 (diff) | |
download | libfaketime-36090e8ceba3dd0cc9478403eacf5949530ab6d9.tar.gz |
dynamic forced monotonic fix autosense (addresses #366)
-rw-r--r-- | src/libfaketime.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/libfaketime.c b/src/libfaketime.c index 9813b16..5ac0300 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -32,6 +32,7 @@ #include <poll.h> #ifdef __linux__ #include <sys/epoll.h> +#include <gnu/libc-version.h> #endif #include <time.h> #ifdef MACOS_DYLD_INTERPOSE @@ -3569,6 +3570,7 @@ bool needs_forced_monotonic_fix(char *function_name) { bool result = false; char *env_var; + const char *glibc_version_string = gnu_get_libc_version(); if (function_name == NULL) return false; @@ -3586,11 +3588,24 @@ bool needs_forced_monotonic_fix(char *function_name) /* Here we try to derive the necessity for a forced monotonic fix * * based on glibc version. What could possibly go wrong? */ - result = false; // chosen by unfair coin flip + int glibc_major, glibc_minor; + sscanf(glibc_version_string, "%d.%d", &glibc_major, &glibc_minor); + + /* The following decision logic is yet purely based on experiences + * with pthread_cond_timedwait(). The used boundaries may still be + * imprecise. */ + if ( (glibc_major == 2) && + ((glibc_minor <= 17) || (glibc_minor >= 30)) ) + { + result = true; + } + else + result = false; // avoid forced monotonic fixes unless really necessary } if (getenv("FAKETIME_DEBUG") != NULL) - fprintf(stderr, "libfaketime: forced monotonic fix for %s = %s\n", function_name, result?"yes":"no"); + fprintf(stderr, "libfaketime: forced monotonic fix for %s = %s (glibc version %s)\n", + function_name, result ? "yes":"no", glibc_version_string); return result; } |