chiark / gitweb /
rand/noise.c: Make the high-res timer function be a bit more abstract.
[catacomb] / rand / noise.c
index b59fd8ad99f4e2cbfe3de26c7a26964c815219c7..f01af65187d639e6c3cf5b71b0429b100e022f68 100644 (file)
 /*----- Magical numbers ---------------------------------------------------*/
 
 #define NOISE_KIDLIFE 100000           /* @noise_filter@ child lifetime */
-#define MILLION 1000000                        /* One million */
+
+#  define TIMESTRUCT timeval
+#  define tv_SEC tv_sec
+#  define tv_FRAC tv_usec
+#  define TIMERES 1000000
+#  define GETTIME(tv) (gettimeofday((tv), 0))
+#  define TOTIMEVAL(tv, xx) (*(tv) = *(xx))
 
 /*----- Noise source definition -------------------------------------------*/
 
@@ -106,20 +112,20 @@ static int bitcount(unsigned long x)
 /* --- @timer@ --- *
  *
  * Arguments:  @rand_pool *r@ = pointer to randomness pool
- *             @struct timeval *tv@ = pointer to time block
+ *             @const struct TIMESTRUCT *tv@ = pointer to time block
  *
  * Returns:    Nonzero if some randomness was contributed.
  *
  * Use:                Low-level timer contributor.
  */
 
-static int timer(rand_pool *r, struct timeval *tv)
+static int timer(rand_pool *r, const struct TIMESTRUCT *tv)
 {
   unsigned long x, d, dd;
   int de, dde;
   int ret;
 
-  x = tv->tv_usec + MILLION * tv->tv_sec;
+  x = tv->tv_FRAC + TIMERES*tv->tv_SEC;
   d = x ^ noise_last;
   dd = d ^ noise_diff;
   noise_last = x;
@@ -146,9 +152,8 @@ static int timer(rand_pool *r, struct timeval *tv)
 
 int noise_timer(rand_pool *r)
 {
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  return (timer(r, &tv));
+  struct TIMESTRUCT tv;
+  GETTIME(&tv); return (timer(r, &tv));
 }
 
 /* --- @noise_devrandom@ --- *
@@ -172,6 +177,9 @@ int noise_devrandom(rand_pool *r)
   fd_set infd;
   struct timeval tv = { 0, 0 };
 #endif
+#ifdef HAVE_GETENTROPY
+  size_t nn;
+#endif
 
 #if defined(HAVE_LINUX_RANDOM_H) &&                                    \
     defined(GRND_NONBLOCK) &&                                          \
@@ -189,6 +197,18 @@ int noise_devrandom(rand_pool *r)
   if (n == sizeof(buf)) goto win;
 #endif
 
+#ifdef HAVE_GETENTROPY
+  /* --- OpenBSD-flavoured shinies --- */
+
+  while (n < sizeof(buf)) {
+    nn = sizeof(buf) - nn;
+    if (nn > 256) nn = 256;
+    if (getentropy(buf + n, nn)) break;
+    n += nn;
+  }
+  if (n == sizeof(buf)) goto win;
+#endif
+
 #ifdef __linux__
   /* --- Don't take from `/dev/urandom' if `/dev/random' would block --- */
 
@@ -304,6 +324,7 @@ int noise_filter(rand_pool *r, int good, const char *c)
   pid_t kid;
   int fd[2];
   struct timeval dead;
+  struct TIMESTRUCT now;
   int ret = 0;
   struct noisekid nk = { 0 };
   sel_state sel;
@@ -316,8 +337,8 @@ int noise_filter(rand_pool *r, int good, const char *c)
 
   /* --- Remember when this business started --- */
 
-  gettimeofday(&dead, 0);
-  timer(r, &dead);
+  GETTIME(&now); timer(r, &now);
+  TOTIMEVAL(&dead, &now);
 
   /* --- Create a pipe --- */