diff options
Diffstat (limited to 'src/basic/fileio.c')
-rw-r--r-- | src/basic/fileio.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c index f183de4999..d642f3daea 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -47,6 +47,8 @@ #include "umask-util.h" #include "utf8.h" +#define READ_FULL_BYTES_MAX (4U*1024U*1024U) + int write_string_stream(FILE *f, const char *line, bool enforce_newline) { assert(f); @@ -230,7 +232,7 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { if (S_ISREG(st.st_mode)) { /* Safety check */ - if (st.st_size > 4*1024*1024) + if (st.st_size > READ_FULL_BYTES_MAX) return -E2BIG; /* Start with the right file size, but be prepared for @@ -245,26 +247,31 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { char *t; size_t k; - t = realloc(buf, n+1); + t = realloc(buf, n + 1); if (!t) return -ENOMEM; buf = t; k = fread(buf + l, 1, n - l, f); + if (k > 0) + l += k; - if (k <= 0) { - if (ferror(f)) - return -errno; + if (ferror(f)) + return -errno; + if (feof(f)) break; - } - l += k; - n *= 2; + /* We aren't expecting fread() to return a short read outside + * of (error && eof), assert buffer is full and enlarge buffer. + */ + assert(l == n); /* Safety check */ - if (n > 4*1024*1024) + if (n >= READ_FULL_BYTES_MAX) return -E2BIG; + + n = MIN(n * 2, READ_FULL_BYTES_MAX); } buf[l] = 0; @@ -1161,8 +1168,8 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { char *t, *x; uint64_t u; unsigned i; + int r; - assert(p); assert(ret); /* Turns this: @@ -1171,6 +1178,12 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0 */ + if (!p) { + r = tmp_dir(&p); + if (r < 0) + return r; + } + if (!extra) extra = ""; @@ -1257,10 +1270,13 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) int open_tmpfile_unlinkable(const char *directory, int flags) { char *p; - int fd; + int fd, r; - if (!directory) - directory = "/tmp"; + if (!directory) { + r = tmp_dir(&directory); + if (r < 0) + return r; + } /* Returns an unlinked temporary file that cannot be linked into the file system anymore */ |