From fb08b88f65d57baa742f33e8e6ec36a772fe801a Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 22 Jan 2008 23:36:06 +0200 Subject: [PATCH] s-s-d: Fix timeout computations for --retry option This has not worked properly for a long time (maybe never), but came to light due to #460903's fix. Closes: #462104 --- ChangeLog | 12 +++++++ debian/changelog | 3 ++ utils/start-stop-daemon.c | 75 +++++++++++++++------------------------ 3 files changed, 44 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9ca1a80..0e75f1a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-01-22 Guillem Jover + + * utils/start-stop-daemon.c (tvselector): Remove typedef. + (tvselector_sec): Remove function. + (tvselector_usec): Likewise. + (TVCALC_ELEM): Remove macro. + (TVCALC): Likewise. + (tsub): New function. + (tmul): Likewise. + (run_stop_schedule): Use tsub and tmul instead of TVCALC. Make sure + the time is not negative. + 2008-01-22 Guillem Jover * utils/start-stop-daemon.c (main): Only call initgroups if changeuser diff --git a/debian/changelog b/debian/changelog index 6e689a44..c165a3ba 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,9 @@ dpkg (1.14.16.3) UNRELEASED; urgency=low * Fix segfault in start-stop-daemon when using --group w/o --chuid (as a side effect, using --group alone works for the first time in years). Closes: #462072 + * Fix timeout computations for start-stop-daemon --retry option. This has + not worked properly for a long time (maybe never), but came to light + due to #460903's fix. Closes: #462104 -- Raphael Hertzog Tue, 22 Jan 2008 18:15:42 +0100 diff --git a/utils/start-stop-daemon.c b/utils/start-stop-daemon.c index ef9b4170..79d07c34 100644 --- a/utils/start-stop-daemon.c +++ b/utils/start-stop-daemon.c @@ -185,48 +185,6 @@ static void fatal(const char *format, ...) static void badusage(const char *msg) NONRETURNING; -/* This next part serves only to construct the TVCALC macro, which - * is used for doing arithmetic on struct timeval's. It works like this: - * TVCALC(result, expression); - * where result is a struct timeval (and must be an lvalue) and - * expression is the single expression for both components. In this - * expression you can use the special values TVELEM, which when fed a - * const struct timeval* gives you the relevant component, and - * TVADJUST. TVADJUST is necessary when subtracting timevals, to make - * it easier to renormalise. Whenver you subtract timeval elements, - * you must make sure that TVADJUST is added to the result of the - * subtraction (before any resulting multiplication or what have you). - * TVELEM must be linear in TVADJUST. - */ -typedef long tvselector(const struct timeval*); - -static long -tvselector_sec(const struct timeval *tv) -{ - return tv->tv_sec; -} - -static long -tvselector_usec(const struct timeval *tv) -{ - return tv->tv_usec; -} - -#define TVCALC_ELEM(result, expr, sec, adj) \ -{ \ - const long TVADJUST = adj; \ - long (*const TVELEM)(const struct timeval *) = tvselector_##sec; \ - (result).tv_##sec = (expr); \ -} -#define TVCALC(result, expr) \ -do { \ - TVCALC_ELEM(result, expr, sec, (-1)); \ - TVCALC_ELEM(result, expr, usec, (+1000000)); \ - (result).tv_sec += (result).tv_usec / 1000000; \ - (result).tv_usec %= 1000000; \ -} while (0) - - static void fatal(const char *format, ...) { @@ -257,6 +215,29 @@ xgettimeofday(struct timeval *tv) if (gettimeofday(tv, NULL) != 0) fatal("gettimeofday failed: %s", strerror(errno)); } + +static void +tsub(struct timeval *r, struct timeval *a, struct timeval *b) +{ + r->tv_sec = (time_t)(a->tv_sec - b->tv_sec); + r->tv_usec = (suseconds_t)(a->tv_usec - b->tv_usec); + if (r->tv_usec < 0) { + --r->tv_sec; + r->tv_usec += 1000000; + } +} + +static void +tmul(struct timeval *a, int b) +{ + a->tv_sec *= b; + a->tv_usec *= b; + if (a->tv_usec >= 1000000) { + ++a->tv_sec; + a->tv_usec -= 1000000; + } +} + static long get_open_fd_max(void) { @@ -1219,10 +1200,12 @@ run_stop_schedule(void) if (ratio < 10) ratio++; - TVCALC(interval, TVELEM(&after) * ratio - - TVELEM(&before) + TVADJUST); - TVCALC(maxinterval, TVELEM(&stopat) - - TVELEM(&after) + TVADJUST); + tsub(&maxinterval, &stopat, &after); + tsub(&interval, &after, &before); + tmul(&interval, ratio); + + if (interval.tv_sec < 0 || interval.tv_usec < 0) + interval.tv_sec = interval.tv_usec = 0; if (timercmp(&interval, &maxinterval, >)) interval = maxinterval; -- 2.39.5