# HG changeset patch # User Rob Landley # Date 1378248988 18000 # Node ID acf7bb2b99e21d4d5cb5da15f3bec63c35bcdfa8 # Parent cbc467592b2ec972a4ffe344b7e433737b52f414 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. diff -r cbc467592b2e -r acf7bb2b99e2 lib/lib.c --- a/lib/lib.c Tue Sep 03 08:30:47 2013 -0500 +++ b/lib/lib.c Tue Sep 03 17:56:28 2013 -0500 @@ -96,11 +96,10 @@ 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 @@ 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 -r cbc467592b2e -r acf7bb2b99e2 lib/lib.h --- a/lib/lib.h Tue Sep 03 08:30:47 2013 -0500 +++ b/lib/lib.h Tue Sep 03 17:56:28 2013 -0500 @@ -135,7 +135,7 @@ 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 -r cbc467592b2e -r acf7bb2b99e2 lib/xwrap.c --- a/lib/xwrap.c Tue Sep 03 08:30:47 2013 -0500 +++ b/lib/xwrap.c Tue Sep 03 17:56:28 2013 -0500 @@ -425,7 +425,7 @@ char *xreadfile(char *name) { - char *buf = readfile(name); + char *buf = readfile(name, 0, 0); if (!buf) perror_exit("xreadfile %s", name); return buf; } diff -r cbc467592b2e -r acf7bb2b99e2 main.c --- a/main.c Tue Sep 03 08:30:47 2013 -0500 +++ b/main.c Tue Sep 03 17:56:28 2013 -0500 @@ -20,7 +20,7 @@ struct toy_context toys; union global_union this; -char toybuf[4096]; +char toybuf[4096], libbuf[4096]; struct toy_list *toy_find(char *name) { diff -r cbc467592b2e -r acf7bb2b99e2 toys.h --- a/toys.h Tue Sep 03 08:30:47 2013 -0500 +++ b/toys.h Tue Sep 03 17:56:28 2013 -0500 @@ -113,9 +113,9 @@ 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 -r cbc467592b2e -r acf7bb2b99e2 toys/other/pmap.c --- a/toys/other/pmap.c Tue Sep 03 08:30:47 2013 -0500 +++ b/toys/other/pmap.c Tue Sep 03 17:56:28 2013 -0500 @@ -35,7 +35,7 @@ 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);