Subject: bug#36380: service urandom-seed takes too long on boot

From: raid5atemyhomework <[email-masked]>
Date: Sun, 07 Feb 2021 15:23:13 +0000

```scheme
(define (get-bytevector-n-timed port count max-time)
  "Read COUNT octets from PORT, blocking as necessary and return a
bytevector containing the octets read, and taking no more than
MAX-TIME seconds.  If fewer bytes are available, a bytevector
smaller than COUNT is returned."

  (define (get-time)
    (let* ((pair   (gettimeofday))
           (secs   (car pair))
           (usecs  (cdr pair)))
      (+ secs (* 0.000001 usecs))))

  (let* ((start-time  (get-time))
         (end-time    (+ start-time max-time))
         (buf         (make-bytevector count)))
    (let loop ((offset  0))
      (let ((current-time (get-time)))
        (cond
          ((= offset count)
            buf)
          ((>= current-time end-time)
            (let ((newbuf (make-bytevector offset)))
              (bytevector-copy! buf 0 newbuf 0 offset)
              newbuf))
          (else
            (let* ((result     (select (list port) '() '() (- end-time current-time)))
                   (readable?  (not (null? (car result)))))
              (if readable?
                (begin
                  ;; read only one byte at a time, as we cannot be sure
                  ;; that the given port will have more than one byte
                  ;; available and that ports will not block if we ask
                  ;; for more than one byte.
                  (get-bytevector-n! port buf offset 1)
                  (loop (+ offset 1)))
                (loop offset)))))))))
```