aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c31
-rw-r--r--lib/lib.h2
-rw-r--r--lib/xwrap.c2
-rw-r--r--main.c2
-rw-r--r--toys.h4
-rw-r--r--toys/other/pmap.c2
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);