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",

Reply via email to