summaryrefslogtreecommitdiffstats
path: root/src/basic/fileio.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 03:50:40 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 03:50:40 +0000
commitfc53809803cd2bc2434e312b19a18fa36776da12 (patch)
treeb4b43bd6538f51965ce32856e9c053d0f90919c8 /src/basic/fileio.c
parentAdding upstream version 255.5. (diff)
downloadsystemd-fc53809803cd2bc2434e312b19a18fa36776da12.tar.xz
systemd-fc53809803cd2bc2434e312b19a18fa36776da12.zip
Adding upstream version 256.upstream/256
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/basic/fileio.c')
-rw-r--r--src/basic/fileio.c76
1 files changed, 41 insertions, 35 deletions
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) {