commit c0ac5a44102417bc091976e713435e92550034c3
parent 71d8b53e71761d15fe2cc6f06797872bcd4c9b35
Author: Robert Russell <robertrussell.72001@gmail.com>
Date: Sat, 14 Jan 2023 12:53:49 -0800
Improve unix.h docs; handle EOF for read_all
Diffstat:
2 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/inc/rcx/unix.h b/inc/rcx/unix.h
@@ -4,28 +4,31 @@
#include "rcx/def.h"
-/* Read exactly len bytes from fd into buf and return 0 on success. On failure
- * (any error except EINTR), return -1 and set errno in the same manner as
- * read(2). In either case, if n is not NULL, set *n to the number of bytes
- * actually read (which is less than len iff an error occurred). */
+/* On success, read exactly len bytes from fd into buf and return 0. On failure
+ * (i.e., any error except EINTR, or EOF before len bytes are read into buf),
+ * return -1 and set errno in the same manner as read(2), or set errno to 0 in
+ * the case of premature EOF. In either case, if n is not NULL, set *n to the
+ * number of bytes actually read (which is less than len iff an error or
+ * premature EOF occurred). */
int r_read_all(usize *n, int fd, void *buf, usize len);
-/* Write exactly len bytes from buf to fd and return 0 on success. On failure
- * (any error except EINTR), return -1 and set errno in the same manner as
+/* On success, write exactly len bytes from buf to fd and return 0. On failure
+ * (i.e, any error except EINTR), return -1 and set errno in the same manner as
* write(2). In either case, if n is not NULL, set *n to the number of bytes
* actually written (which is less than len iff an error occurred). */
int r_write_all(usize *n, int fd, void *buf, usize len);
-/* Copy n bytes from (*src, *niov) to dst. Increment the base pointer and
+/* Copy n bytes from (*iov, *niov) to dst. Increment the base pointer and
* decrement the length in each iovec according to the number of bytes copied.
- * If there are fewer than n bytes in (*src, *niov), behaviour is undefined. */
-void r_iovec_gather(void *dst, struct iovec **src, usize *niov, usize n);
+ * There must be at least n bytes in (*iov, *niov). */
+void r_iovec_gather(void *dst, struct iovec **iov, usize *niov, usize n);
/* TODO */
/* int r_readv_all(int fd, struct iovec **iov, usize *niov); */
-/* Write all bytes from (*iov, *niov) to fd and return 0 on succes. On failure
- * (any error except EINTR), return -1 and set errno in the same manner as
- * writev(2). Increment the base pointer and decrement the length in each iovec
- * according to the number of bytes actually written. */
+/* On success, write all bytes from (*iov, *niov) to fd and return 0. On
+ * failure (i.e., any error except EINTR), return -1 and set errno in the same
+ * manner as writev(2). In either case, increment the base pointer and
+ * decrement the length in each iovec according to the number of bytes actually
+ * written. */
int r_writev_all(int fd, struct iovec **iov, usize *niov);
diff --git a/src/unix.c b/src/unix.c
@@ -8,19 +8,21 @@
typedef isize (*IoOp)(int, void *, usize);
-// TODO: handle ret == 0 and do-while -> while
static int
perform_io(usize *n, IoOp op, int fd, void *buf, usize len) {
usize i = 0;
- do {
+ while (i < len) {
isize ret = op(fd, (char *)buf + i, len - i);
if (ret < 0) {
if (errno == EINTR) continue;
break;
+ } else if (ret == 0) {
+ errno = 0;
+ break;
}
i += ret;
- } while (i < len);
+ }
if (n) *n = i;
return i == len ? 0 : -1;
@@ -38,22 +40,19 @@ r_write_all(usize *n, int fd, void *buf, usize len) {
}
void
-r_iovec_gather(void *dst, struct iovec **src, usize *niov, usize n) {
- if (n == 0) return;
-
- for (usize i = 0;;) {
- assert(*niov > 0);
-
- usize l = MIN((*src)->iov_len, n);
- memcpy((char *)dst + i, (*src)->iov_base, l);
- (*src)->iov_base = (char *)(*src)->iov_base + l;
- (*src)->iov_len -= l;
+r_iovec_gather(void *dst, struct iovec **iov, usize *niov, usize n) {
+ for (usize i = 0; *niov > 0; ++*iov, --*niov) {
+ usize l = MIN((*iov)->iov_len, n);
+ memcpy((char *)dst + i, (*iov)->iov_base, l);
+ (*iov)->iov_base = (char *)(*iov)->iov_base + l;
+ (*iov)->iov_len -= l;
i += l;
n -= l;
- if (n == 0) break;
- ++*src, --*niov;
+ if ((*iov)->iov_len > 0) break;
}
+
+ assert(n == 0);
}
/* Note for future implementation of r_readv_all: Suppose readv completely