diff --git a/src/libfaketime.c b/src/libfaketime.c index 1a498d8..c259240 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -2636,8 +2636,9 @@ struct LockedState { static void pthread_cleanup_mutex_lock(void *data) { struct LockedState *state = data; + sigset_t original_mask = state->original_mask; // inside the lock! pthread_mutex_unlock(&state->mutex); - sigprocmask(SIG_SETMASK, &state->original_mask, NULL); + pthread_sigmask(SIG_SETMASK, &original_mask, NULL); } #endif @@ -2666,15 +2667,18 @@ 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 }; // block all signals while locked. prevents deadlocks if signal interrupts in in mid-operation. - sigset_t all_signals; + sigset_t all_signals, original_mask; sigfillset(&all_signals); - sigprocmask(SIG_SETMASK, &all_signals, &state.original_mask); - + pthread_sigmask(SIG_SETMASK, &all_signals, &original_mask); pthread_mutex_lock(&state.mutex); + state.original_mask = original_mask; // inside the lock! pthread_cleanup_push(pthread_cleanup_mutex_lock, &state); #endif @@ -2720,10 +2724,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); */ } @@ -2828,7 +2836,8 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) { if (load_time(tp)) { - return 0; + ret = 0; + goto abort; } } @@ -2891,12 +2900,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 */