-
+ 48454218170DAD22CB7BD9088EC90F7F808FCDE914962D0FCA20B3331BEF95AFE749D1A218D21AE02F00588C8DC05607B35C1B7C7CD3B852D58AC0D504DD3C30
vtools/lib/cmpbuf.c
(0 . 0)(1 . 57)
46 #include <errno.h>
47 #include <limits.h>
48 #include <signal.h>
49 #include <unistd.h>
50 #include <stdint.h>
51 #include "system.h"
52 #include "cmpbuf.h"
53
54 /* Read |nbytes| bytes from descriptor |fd| into |buf|. |nbytes| must
55 not be |SIZE_MAX|. Return the number of characters successfully
56 read. On error, return |SIZE_MAX|, setting |errno|. The number
57 returned is always |nbytes| unless end-of-file or error. */
58
59 size_t
60 block_read(int fd, char *buf, size_t nbytes) {
61 char *bp = buf;
62 char const *buflim = buf + nbytes;
63 size_t readlim = MIN (SSIZE_MAX, SIZE_MAX);
64
65 do {
66 size_t bytes_remaining = buflim - bp;
67 size_t bytes_to_read = MIN (bytes_remaining, readlim);
68 ssize_t nread = read(fd, bp, bytes_to_read);
69 if (nread <= 0) {
70 if (nread == 0)
71 break;
72 return SIZE_MAX;
73 }
74 bp += nread;
75 } while (bp < buflim);
76
77 return bp - buf;
78 }
79
80 /* Least common multiple of two buffer sizes |a| and |b|. However, if
81 either |a| or |b| is zero, or if the multiple is greater than
82 |lcm_max|, return a reasonable buffer size. */
83
84 size_t
85 buffer_lcm(size_t a, size_t b, size_t lcm_max) {
86 size_t lcm, m, n, q, r;
87
88 /* Yield reasonable values if buffer sizes are zero. */
89 if (!a)
90 return b ? b : 8 * 1024;
91 if (!b)
92 return a;
93
94 /* |n = gcd (a, b)| */
95 for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
96 continue;
97
98 /* Yield a if there is an overflow. */
99 q = a / n;
100 lcm = q * b;
101 return lcm <= lcm_max && lcm / b == q ? lcm : a;
102 }