From 78e9bb837c258ac0ec7712b3d612cc2f407e731e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 05:50:42 +0200 Subject: Merging upstream version 256. Signed-off-by: Daniel Baumann --- src/basic/fileio.c | 76 +++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'src/basic/fileio.c') diff --git a/src/basic/fileio.c b/src/basic/fileio.c index a050b61..5233781 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -28,10 +28,11 @@ #include "stdio-util.h" #include "string-util.h" #include "sync-util.h" +#include "terminal-util.h" #include "tmpfile-util.h" /* The maximum size of the file we'll read in one go in read_full_file() (64M). */ -#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U) +#define READ_FULL_BYTES_MAX (64U * U64_MB - UINT64_C(1)) /* Used when a size is specified for read_full_file() with READ_FULL_FILE_UNBASE64 or _UNHEX */ #define READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY 3 @@ -44,7 +45,7 @@ * exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/ * allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we * can detect EOFs. */ -#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 2U) +#define READ_VIRTUAL_BYTES_MAX (4U * U64_MB - UINT64_C(2)) int fdopen_unlocked(int fd, const char *options, FILE **ret) { assert(ret); @@ -199,6 +200,19 @@ int write_string_stream_ts( return 0; } +static mode_t write_string_file_flags_to_mode(WriteStringFileFlags flags) { + + /* We support three different modes, that are the ones that really make sense for text files like this: + * + * → 0600 (i.e. root-only) + * → 0444 (i.e. read-only) + * → 0644 (i.e. writable for root, readable for everyone else) + */ + + return FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : + FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0444) ? 0444 : 0644; +} + static int write_string_file_atomic_at( int dir_fd, const char *fn, @@ -224,7 +238,7 @@ static int write_string_file_atomic_at( if (r < 0) goto fail; - r = fchmod_umask(fileno(f), FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0644); + r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags)); if (r < 0) goto fail; @@ -287,7 +301,7 @@ int write_string_file_ts_at( (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) | (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) | (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY), - (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666)); + write_string_file_flags_to_mode(flags)); if (fd < 0) { r = -errno; goto fail; @@ -1313,33 +1327,31 @@ int read_timestamp_file(const char *fn, usec_t *ret) { return 0; } -int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) { - int r; - +int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *space) { assert(s); + assert(space); - /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter - * when specified shall initially point to a boolean variable initialized to false. It is set to true after the - * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each - * element, but not before the first one. */ + /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. + * The *space parameter when specified shall initially point to a boolean variable initialized + * to false. It is set to true after the first invocation. This call is supposed to be use in loops, + * where a separator shall be inserted between each element, but not before the first one. */ if (!f) f = stdout; - if (space) { - if (!separator) - separator = " "; + if (!separator) + separator = " "; - if (*space) { - r = fputs(separator, f); - if (r < 0) - return r; - } + if (*space) + if (fputs(separator, f) < 0) + return -EIO; - *space = true; - } + *space = true; + + if (fputs(s, f) < 0) + return -EIO; - return fputs(s, f); + return 0; } /* A bitmask of the EOL markers we know */ @@ -1459,7 +1471,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { * and don't call isatty() on an invalid fd */ flags |= READ_LINE_NOT_A_TTY; else - flags |= isatty(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY; + flags |= isatty_safe(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY; } if (FLAGS_SET(flags, READ_LINE_IS_A_TTY)) break; @@ -1492,7 +1504,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { int read_stripped_line(FILE *f, size_t limit, char **ret) { _cleanup_free_ char *s = NULL; - int r; + int r, k; assert(f); @@ -1501,23 +1513,17 @@ int read_stripped_line(FILE *f, size_t limit, char **ret) { return r; if (ret) { - const char *p; - - p = strstrip(s); + const char *p = strstrip(s); if (p == s) *ret = TAKE_PTR(s); else { - char *copy; - - copy = strdup(p); - if (!copy) - return -ENOMEM; - - *ret = copy; + k = strdup_to(ret, p); + if (k < 0) + return k; } } - return r; + return r > 0; /* Return 1 if something was read. */ } int safe_fgetc(FILE *f, char *ret) { -- cgit v1.2.3