summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Hommel <wolf@code-wizards.com>2022-02-25 21:25:58 +0100
committerWolfgang Hommel <wolf@code-wizards.com>2022-02-25 21:25:58 +0100
commit36090e8ceba3dd0cc9478403eacf5949530ab6d9 (patch)
treeee14c610b1020c9367045e1289602241334b43ad
parent0e61d3d1917f530b5e3f66db2ed5dd6acd20e798 (diff)
downloadlibfaketime-36090e8ceba3dd0cc9478403eacf5949530ab6d9.tar.gz
dynamic forced monotonic fix autosense (addresses #366)
-rw-r--r--src/libfaketime.c19
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;
}