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 +- main.c | 2 +- toys.h | 4 ++-- toys/other/pmap.c | 2 +- 6 files changed, 25 insertions(+), 18 deletions(-) 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; } diff --git a/main.c b/main.c index dd985b84..53f670d2 100644 --- a/main.c +++ b/main.c @@ -20,7 +20,7 @@ struct toy_list toy_list[] = { struct toy_context toys; union global_union this; -char toybuf[4096]; +char toybuf[4096], libbuf[4096]; struct toy_list *toy_find(char *name) { diff --git a/toys.h b/toys.h index c810123a..b7acc270 100644 --- a/toys.h +++ b/toys.h @@ -113,9 +113,9 @@ extern struct toy_context { jmp_buf *rebound; // longjmp here instead of exit when do_rebound set } toys; -// One big temporary buffer, for use by commands (not library functions). +// Two big temporary buffers: one for use by commands, one for library functions -extern char toybuf[4096]; +extern char toybuf[4096], libbuf[4096]; extern char **environ; diff --git a/toys/other/pmap.c b/toys/other/pmap.c index 012280dd..1cc04220 100644 --- a/toys/other/pmap.c +++ b/toys/other/pmap.c @@ -35,7 +35,7 @@ void pmap_main(void) int count, xx = 0; snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid); - line = readfile(toybuf); + line = readfile(toybuf, 0, 0); if (!line) error_msg("No %lu", (long)pid); xprintf("%u: %s\n", (int)pid, line); free(line); -- cgit v1.2.3