From ff39f61a4de1e53bf5ece8d37f286487e29a2dd4 Mon Sep 17 00:00:00 2001 From: Stuart Cunningham Date: Mon, 13 Apr 2026 23:39:37 +1000 Subject: [PATCH 1/2] Fix silent read failure in load(): use perror and exit instead of painting over error message --- io.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/io.c b/io.c index b9c2741..c6d5d69 100644 --- a/io.c +++ b/io.c @@ -290,8 +290,11 @@ load(char *fname) } else if ((filemode == REGULAR) || (filemode == DIRECTORY)) { filesize = buf.st_size; if (read_to_end(fd, mem, filesize) != filesize) { - sysemsg(fname); - filemode = ERROR; + close(fd); + move(maxy, 0); + endwin(); + perror(fname); + exit(0); } } else { filesize = 0L; From f6bdbd018ac24284c9fffa253aa8d48c84469b6a Mon Sep 17 00:00:00 2001 From: Stuart Cunningham Date: Mon, 13 Apr 2026 23:49:50 +1000 Subject: [PATCH 2/2] Limit read() to 0x7FFF0000 bytes per call to fix >2GiB files on macOS --- io.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/io.c b/io.c index c6d5d69..b919f02 100644 --- a/io.c +++ b/io.c @@ -58,13 +58,17 @@ #endif -//@ read on linux has a limit of 0x7ffff000 bytes (see `man read`) -//@ this function calls recursively read until all `count` characters are read. +//@ linux read() clamps to 0x7ffff000 bytes per call (see `man read`) +//@ macOS read() returns EINVAL if count > INT_MAX (0x7fffffff) +//@ cap each read and loop until all `count` bytes are read. +#define READ_MAX 0x7FFF0000 static ssize_t read_to_end(int fd, void *buf, size_t count) { size_t read_bytes = 0; while(read_bytes < count) { - const ssize_t ret = read(fd, ((char*)buf)+read_bytes, count-read_bytes); + size_t remaining = count - read_bytes; + if(remaining > READ_MAX) remaining = READ_MAX; + const ssize_t ret = read(fd, ((char*)buf)+read_bytes, remaining); if(ret <= 0) return ret; read_bytes += ret; }