I've reworked the patch to apply to 1.14.16.4. There are some subtle
changes.
* tsub is removed in favour of timersub (sys/time.h).
* tmul is reimplemented as it was broken.
* interval is checked right before select. There was a corner case if
maxinterval was negative.
regards,
Andreas Påhlsson
Xcerion AB
Please note that this message may contain confidential information. Unless
explicitly so designated this e-mail does not constitute a contract offer, a
contract amendment, or an acceptance of a contract offer. The views expressed
in this email may not be the policy or view of Xcerion AB.
--- dpkg-1.14.16.4/utils/start-stop-daemon.c 2008-01-22 22:57:07.000000000 +0100
+++ dpkg-1.14.16.4-ap/utils/start-stop-daemon.c 2008-01-24 10:13:33.000000000 +0100
@@ -217,25 +217,14 @@
}
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;
- }
+ a->tv_sec *= b;
+
+ // Normalize
+ a->tv_sec = a->tv_sec + a->tv_usec / 1000000;
+ a->tv_usec = a->tv_usec % 1000000;
}
static long
@@ -1200,12 +1189,10 @@
if (ratio < 10)
ratio++;
- tsub(&maxinterval, &stopat, &after);
- tsub(&interval, &after, &before);
+ timersub(&stopat, &after, &maxinterval);
+ timersub(&after, &before, &interval);
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;
@@ -1214,6 +1201,11 @@
interval.tv_usec <= MIN_POLL_INTERVAL)
interval.tv_usec = MIN_POLL_INTERVAL;
+ if (interval.tv_sec < 0 || interval.tv_usec < 0) {
+ interval.tv_sec = 0;
+ interval.tv_usec = 0;
+ }
+
r = select(0, NULL, NULL, NULL, &interval);
if (r < 0 && errno != EINTR)
fatal("select() failed for pause: %s",