aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-09-09 15:28:03 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-09-09 15:28:03 -0400
commit02eefdd52c7d1a8f5ac896c22d5ff6aff065bf72 (patch)
tree4b6557006eba443415dc8fee816c1c0a967311af
parentcc94afcc567798cb983b7923f572ea7f389783e6 (diff)
Fix issues with path reading from pipes (don't UTF8 validate chunks,
because they can be fragments) and some misc buffering issues.
-rw-r--r--builtins/path.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/builtins/path.c b/builtins/path.c
index e63e4e42..1dde5aa2 100644
--- a/builtins/path.c
+++ b/builtins/path.c
@@ -8,6 +8,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <unistr.h>
#include "array.h"
@@ -257,24 +258,35 @@ public Text_t Path$read(Path_t path)
close(fd);
return Text$from_strn(gc_mem, (size_t)sb.st_size);
} else {
- const size_t chunk_size = 256;
- char *buf = GC_MALLOC_ATOMIC(chunk_size);
- Text_t contents = Text("");
- ssize_t just_read;
- do {
- just_read = read(fd, buf, chunk_size);
+ size_t capacity = 256, len = 0;
+ char *content = GC_MALLOC_ATOMIC(capacity);
+ for (;;) {
+ char chunk[256];
+ ssize_t just_read = read(fd, chunk, sizeof(chunk));
if (just_read < 0)
fail("Failed while reading file: %k (%s)", &path, strerror(errno));
- else if (just_read == 0)
+ else if (just_read == 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
break;
+ }
+
+ if (len + (size_t)just_read >= capacity) {
+ content = GC_REALLOC(content, (capacity *= 2));
+ }
+
+ memcpy(&content[len], chunk, (size_t)just_read);
+ len += (size_t)just_read;
- if (u8_check((uint8_t*)buf, (size_t)just_read) != NULL)
- fail("File does not contain valid UTF8 data!");
- contents = Texts(contents, Text$from_strn(buf, (size_t)just_read));
- buf = GC_MALLOC_ATOMIC(chunk_size);
- } while (just_read > 0);
+ if ((size_t)just_read < sizeof(chunk))
+ break;
+ }
close(fd);
- return contents;
+
+ if (u8_check((uint8_t*)content, len) != NULL)
+ fail("File does not contain valid UTF8 data!");
+
+ return Text$from_strn(content, len);
}
}