diff --git a/io.c b/io.c index b9c2741..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; } @@ -290,8 +294,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;