diff options
Diffstat (limited to 'src/systemd/src/basic/fileio.c')
-rw-r--r-- | src/systemd/src/basic/fileio.c | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index b07cb9cb2d..b2fe15ca28 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -49,6 +49,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); @@ -232,7 +234,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 @@ -247,26 +249,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; @@ -1071,7 +1078,7 @@ int fflush_and_check(FILE *f) { return 0; } -/* This is much like like mkostemp() but is subject to umask(). */ +/* This is much like mkostemp() but is subject to umask(). */ int mkostemp_safe(char *pattern, int flags) { _cleanup_umask_ mode_t u = 0; int fd; @@ -1161,12 +1168,13 @@ int tempfn_random(const char *p, const char *extra, char **ret) { return 0; } +#if 0 /* NM_IGNORED */ 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: @@ -1175,6 +1183,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 = ""; @@ -1196,7 +1210,6 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { return 0; } -#if 0 /* NM_IGNORED */ int write_timestamp_file_atomic(const char *fn, usec_t n) { char ln[DECIMAL_STR_MAX(n)+2]; @@ -1264,9 +1277,13 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) #if 0 /* NM_IGNORED */ int open_tmpfile_unlinkable(const char *directory, int flags) { char *p; - int fd; + int fd, r; - assert(directory); + 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 */ @@ -1361,4 +1378,45 @@ int link_tmpfile(int fd, const char *path, const char *target) { return 0; } + +int read_nul_string(FILE *f, char **ret) { + _cleanup_free_ char *x = NULL; + size_t allocated = 0, n = 0; + + assert(f); + assert(ret); + + /* Reads a NUL-terminated string from the specified file. */ + + for (;;) { + int c; + + if (!GREEDY_REALLOC(x, allocated, n+2)) + return -ENOMEM; + + c = fgetc(f); + if (c == 0) /* Terminate at NUL byte */ + break; + if (c == EOF) { + if (ferror(f)) + return -errno; + break; /* Terminate at EOF */ + } + + x[n++] = (char) c; + } + + if (x) + x[n] = 0; + else { + x = new0(char, 1); + if (!x) + return -ENOMEM; + } + + *ret = x; + x = NULL; + + return 0; +} #endif /* NM_IGNORED */ |