From 8fdcfdb4479dff7a993a25a63253f0e749fd99fe Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 3 Sep 2013 17:56:28 -0500 Subject: Introduce libbuf analogous to toybuf but for use by lib/*.c. Change readfile() semantics to be able to read into an existing buffer, or malloc its own if that's NULL. --- lib/lib.c | 31 +++++++++++++++++++------------ lib/lib.h | 2 +- lib/xwrap.c | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/lib.c b/lib/lib.c index 86e99ace..38d9cc21 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -96,11 +96,10 @@ off_t lskip(int fd, off_t offset) if (and != -1 && offset >= lseek(fd, offset, SEEK_END) && offset+and == lseek(fd, offset+and, SEEK_SET)) return 0; else { - char buf[4096]; while (offset>0) { - int try = offset>sizeof(buf) ? sizeof(buf) : offset, or; + int try = offset>sizeof(libbuf) ? sizeof(libbuf) : offset, or; - or = readall(fd, buf, try); + or = readall(fd, libbuf, try); if (or < 0) perror_msg("lskip to %lld", (long long)offset); else offset -= try; if (or < try) break; @@ -259,20 +258,28 @@ off_t fdlength(int fd) return base; } -// Read contents of file as a single freshly allocated nul-terminated string. -char *readfile(char *name) +// Read contents of file as a single nul-terminated string. +// malloc new one if buf=len=0 +char *readfile(char *name, char *buf, off_t len) { - off_t len; int fd; - char *buf; fd = open(name, O_RDONLY); if (fd == -1) return 0; - len = fdlength(fd); - // proc files don't report a length, so try 1 page minimum. - if (len<4096) len = 4095; - buf = xmalloc(len+1); - buf[readall(fd, buf, len)] = 0; + + if (len<1) { + len = fdlength(fd); + // proc files don't report a length, so try 1 page minimum. + if (len<4096) len = 4096; + } + if (!buf) buf = xmalloc(len+1); + + len = readall(fd, buf, len-1); + close(fd); + if (len<0) { + free(buf); + buf = 0; + } else buf[len] = 0; return buf; } diff --git a/lib/lib.h b/lib/lib.h index 14e14e91..26465ad4 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -135,7 +135,7 @@ ssize_t readall(int fd, void *buf, size_t len); ssize_t writeall(int fd, void *buf, size_t len); off_t lskip(int fd, off_t offset); struct string_list **splitpath(char *path, struct string_list **list); -char *readfile(char *name); +char *readfile(char *name, char *buf, off_t len); void msleep(long miliseconds); int64_t peek(void *ptr, int size); void poke(void *ptr, uint64_t val, int size); diff --git a/lib/xwrap.c b/lib/xwrap.c index 2b0690f3..90c4d86a 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -425,7 +425,7 @@ char *xreadlink(char *name) char *xreadfile(char *name) { - char *buf = readfile(name); + char *buf = readfile(name, 0, 0); if (!buf) perror_exit("xreadfile %s", name); return buf; } -- cgit v1.2.3