diff options
author | Mathis Beer <Mathis.Beer@funkwerk-itk.com> | 2020-03-11 14:34:25 +0100 |
---|---|---|
committer | Mathis Beer <Mathis.Beer@funkwerk-itk.com> | 2020-03-12 06:45:43 +0100 |
commit | b4dea2ef9b529e2a7fb8619d68f0830ff957d3de (patch) | |
tree | 814859a9a4d6aa28b7f0eef6ce7e4fd5e3930c7a /src | |
parent | 796b30bebf5a74ac73ad506da8576e3445090131 (diff) | |
download | libfaketime-b4dea2ef9b529e2a7fb8619d68f0830ff957d3de.tar.gz |
Unlock faketime lock on all return paths from libfaketime.c.
These gymnastics are necessary because pthread_cleanup_push
and pthread_cleanup_pop must match exactly 1:1 and appear at
the same level of indentation.
This is because pthread_cleanup_push/pop are implemented in
such a way that pthread_cleanup_push opens a scope and
pthread_cleanup_pop closes it.
They're macros with unbalanced brackets.
C, ladies and gentlemen.
So instead of returning, we have to set a field indicating our
intent to return and then jump to the unlock site.
Diffstat (limited to 'src')
-rw-r--r-- | src/libfaketime.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/libfaketime.c b/src/libfaketime.c index d9f1fc0..17ebaa2 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -2666,6 +2666,9 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) /* Sanity check by Karl Chan since v0.8 */ if (tp == NULL) return -1; + // {ret = value; goto abort;} to call matching pthread_cleanup_pop and return value + int ret = INT_MAX; + #ifdef PTHREAD_SINGLETHREADED_TIME static struct LockedState state = { 0 }; @@ -2719,10 +2722,14 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) { /* Check whether we actually should be faking the returned timestamp. */ /* fprintf(stderr, "(libfaketime limits -> runtime: %lu, callcounter: %lu\n", (*time_tptr - ftpl_starttime), callcounter); */ - if ((ft_start_after_secs != -1) && (tmp_ts.tv_sec < ft_start_after_secs)) return 0; - if ((ft_stop_after_secs != -1) && (tmp_ts.tv_sec >= ft_stop_after_secs)) return 0; - if ((ft_start_after_ncalls != -1) && (callcounter < ft_start_after_ncalls)) return 0; - if ((ft_stop_after_ncalls != -1) && (callcounter >= ft_stop_after_ncalls)) return 0; + if (((ft_start_after_secs != -1) && (tmp_ts.tv_sec < ft_start_after_secs)) + || ((ft_stop_after_secs != -1) && (tmp_ts.tv_sec >= ft_stop_after_secs)) + || ((ft_start_after_ncalls != -1) && (callcounter < ft_start_after_ncalls)) + || ((ft_stop_after_ncalls != -1) && (callcounter >= ft_stop_after_ncalls))) + { + ret = 0; + goto abort; + } /* fprintf(stderr, "(libfaketime limits -> runtime: %lu, callcounter: %lu continues\n", (*time_tptr - ftpl_starttime), callcounter); */ } @@ -2827,7 +2834,8 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) { if (load_time(tp)) { - return 0; + ret = 0; + goto abort; } } @@ -2890,12 +2898,16 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) break; default: - return -1; + ret = -1; + goto abort; } // end of switch(ft_mode) +abort: #ifdef PTHREAD_SINGLETHREADED_TIME pthread_cleanup_pop(1); #endif + // came here via goto abort? + if (ret != INT_MAX) return ret; save_time(tp); /* Cache this most recent real and faked time we encountered */ |