raw
vtools_genesis          1 #include <errno.h>
vtools_genesis 2 #include <limits.h>
vtools_genesis 3 #include <signal.h>
vtools_genesis 4 #include <unistd.h>
vtools_genesis 5 #include <stdint.h>
vtools_genesis 6 #include "system.h"
vtools_genesis 7 #include "cmpbuf.h"
vtools_genesis 8
vtools_genesis 9 /* Read |nbytes| bytes from descriptor |fd| into |buf|. |nbytes| must
vtools_genesis 10 not be |SIZE_MAX|. Return the number of characters successfully
vtools_genesis 11 read. On error, return |SIZE_MAX|, setting |errno|. The number
vtools_genesis 12 returned is always |nbytes| unless end-of-file or error. */
vtools_genesis 13
vtools_genesis 14 size_t
vtools_genesis 15 block_read(int fd, char *buf, size_t nbytes) {
vtools_genesis 16 char *bp = buf;
vtools_genesis 17 char const *buflim = buf + nbytes;
vtools_genesis 18 size_t readlim = MIN (SSIZE_MAX, SIZE_MAX);
vtools_genesis 19
vtools_genesis 20 do {
vtools_genesis 21 size_t bytes_remaining = buflim - bp;
vtools_genesis 22 size_t bytes_to_read = MIN (bytes_remaining, readlim);
vtools_genesis 23 ssize_t nread = read(fd, bp, bytes_to_read);
vtools_genesis 24 if (nread <= 0) {
vtools_genesis 25 if (nread == 0)
vtools_genesis 26 break;
vtools_genesis 27 return SIZE_MAX;
vtools_genesis 28 }
vtools_genesis 29 bp += nread;
vtools_genesis 30 } while (bp < buflim);
vtools_genesis 31
vtools_genesis 32 return bp - buf;
vtools_genesis 33 }
vtools_genesis 34
vtools_genesis 35 /* Least common multiple of two buffer sizes |a| and |b|. However, if
vtools_genesis 36 either |a| or |b| is zero, or if the multiple is greater than
vtools_genesis 37 |lcm_max|, return a reasonable buffer size. */
vtools_genesis 38
vtools_genesis 39 size_t
vtools_genesis 40 buffer_lcm(size_t a, size_t b, size_t lcm_max) {
vtools_genesis 41 size_t lcm, m, n, q, r;
vtools_genesis 42
vtools_genesis 43 /* Yield reasonable values if buffer sizes are zero. */
vtools_genesis 44 if (!a)
vtools_genesis 45 return b ? b : 8 * 1024;
vtools_genesis 46 if (!b)
vtools_genesis 47 return a;
vtools_genesis 48
vtools_genesis 49 /* |n = gcd (a, b)| */
vtools_genesis 50 for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
vtools_genesis 51 continue;
vtools_genesis 52
vtools_genesis 53 /* Yield a if there is an overflow. */
vtools_genesis 54 q = a / n;
vtools_genesis 55 lcm = q * b;
vtools_genesis 56 return lcm <= lcm_max && lcm / b == q ? lcm : a;
vtools_genesis 57 }