diff options
Diffstat (limited to 'src/basic/fileio.c')
-rw-r--r-- | src/basic/fileio.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c index f183de4999..1cfb7a98f5 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -37,6 +37,7 @@ #include "hexdecoct.h" #include "log.h" #include "macro.h" +#include "missing.h" #include "parse-util.h" #include "path-util.h" #include "random-util.h" @@ -47,6 +48,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 +233,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 +248,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; @@ -1035,7 +1043,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { if (r < 0) return r; - fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(t); if (fd < 0) { free(t); return -errno; @@ -1068,7 +1076,7 @@ int fflush_and_check(FILE *f) { } /* This is much like mkostemp() but is subject to umask(). */ -int mkostemp_safe(char *pattern, int flags) { +int mkostemp_safe(char *pattern) { _cleanup_umask_ mode_t u = 0; int fd; @@ -1076,7 +1084,7 @@ int mkostemp_safe(char *pattern, int flags) { u = umask(077); - fd = mkostemp(pattern, flags); + fd = mkostemp(pattern, O_CLOEXEC); if (fd < 0) return -errno; @@ -1161,8 +1169,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 +1179,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,24 +1271,25 @@ 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 */ -#ifdef O_TMPFILE /* Try O_TMPFILE first, if it is supported */ fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR); if (fd >= 0) return fd; -#endif /* Fall back to unguessable name + unlinking */ p = strjoina(directory, "/systemd-tmp-XXXXXX"); - fd = mkostemp_safe(p, flags); + fd = mkostemp_safe(p); if (fd < 0) return fd; @@ -1297,7 +1312,6 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */ -#ifdef O_TMPFILE { _cleanup_free_ char *dn = NULL; @@ -1313,7 +1327,6 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn); } -#endif r = tempfn_random(target, NULL, &tmp); if (r < 0) |