about summary refs log tree commit diff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorCedric Ware <cedric.ware__bml@normalesup.org>2020-04-20 12:10:01 -0500
committerdana <dana@dana.is>2020-04-20 12:10:01 -0500
commit25c9b61a6663f90bfb22fa73c1a7aa4fb9dee4ae (patch)
tree120e8f1e11ab3791b6fbe1d6302dda275d09c2ac /Src/utils.c
parentf179dbf72a4f482c1ad513b7c58cd7f96c7cf7f3 (diff)
downloadzsh-25c9b61a6663f90bfb22fa73c1a7aa4fb9dee4ae.tar.gz
zsh-25c9b61a6663f90bfb22fa73c1a7aa4fb9dee4ae.tar.xz
zsh-25c9b61a6663f90bfb22fa73c1a7aa4fb9dee4ae.zip
45708: zsh/system: Enable sub-second timeout in zsystem flock
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/Src/utils.c b/Src/utils.c
index 69885fed3..e258ef836 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2749,6 +2749,42 @@ read_poll(int fd, int *readchar, int polltty, zlong microseconds)
 }
 
 /*
+ * Return the difference between 2 times, given as struct timespec*,
+ * expressed in microseconds, as a long.  If the difference doesn't fit
+ * into a long, return LONG_MIN or LONG_MAX so that the times can still
+ * be compared.
+ *
+ * Note: returns a long rather than a zlong because zsleep() below
+ * takes a long.
+ */
+
+/**/
+long
+timespec_diff_us(const struct timespec *t1, const struct timespec *t2)
+{
+    int reverse = (t1->tv_sec > t2->tv_sec);
+    time_t diff_sec;
+    long diff_usec, max_margin, res;
+
+    /* Don't just subtract t2-t1 because time_t might be unsigned. */
+    diff_sec = (reverse ? t1->tv_sec - t2->tv_sec : t2->tv_sec - t1->tv_sec);
+    if (diff_sec > LONG_MAX / 1000000L) {
+	goto overflow;
+    }
+    res = diff_sec * 1000000L;
+    max_margin = LONG_MAX - res;
+    diff_usec = (reverse ?
+		 t1->tv_nsec - t2->tv_nsec : t2->tv_nsec - t1->tv_nsec
+		 ) / 1000;
+    if (diff_usec <= max_margin) {
+	res += diff_usec;
+	return (reverse ? -res : res);
+    }
+ overflow:
+    return (reverse ? LONG_MIN : LONG_MAX);
+}
+
+/*
  * Sleep for the given number of microseconds --- must be within
  * range of a long at the moment, but this is only used for
  * limited internal purposes.