summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-12-17 11:50:33 +0100
committerLennart Poettering <lennart@poettering.net>2018-12-18 15:03:05 +0100
commit41f11239c0c83c378643fc4942c726a49025b3b8 (patch)
tree81d9dcdf214898e4f1108a534808fec3f0f5e230
parent2a7797e964e5b6a0f305b00073e2b06a195d0b15 (diff)
downloadsystemd-41f11239c0c83c378643fc4942c726a49025b3b8.tar.gz
systemd-41f11239c0c83c378643fc4942c726a49025b3b8.tar.bz2
systemd-41f11239c0c83c378643fc4942c726a49025b3b8.zip
fileio: replace read_nul_string() by read_line() with a special flag
read_line() is a lot more careful and optimized than read_nul_string() but does mostly the same thing. let's replace the latter by the former, just with a special flag that toggles between the slightly different EOL rules if both.
-rw-r--r--src/basic/fileio.c58
-rw-r--r--src/basic/fileio.h14
-rw-r--r--src/machine/machined-dbus.c8
3 files changed, 27 insertions, 53 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index a119e831b4..febda0abfd 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -667,46 +667,6 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
return fputs(s, f);
}
-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 = TAKE_PTR(x);
-
- return 0;
-}
-
/* A bitmask of the EOL markers we know */
typedef enum EndOfLineMarker {
EOL_NONE = 0,
@@ -715,11 +675,15 @@ typedef enum EndOfLineMarker {
EOL_THIRTEEN = 1 << 2, /* \r (aka CR) */
} EndOfLineMarker;
-static EndOfLineMarker categorize_eol(char c) {
- if (c == '\n')
- return EOL_TEN;
- if (c == '\r')
- return EOL_THIRTEEN;
+static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) {
+
+ if (!IN_SET(flags, READ_LINE_ONLY_NUL)) {
+ if (c == '\n')
+ return EOL_TEN;
+ if (c == '\r')
+ return EOL_THIRTEEN;
+ }
+
if (c == '\0')
return EOL_ZERO;
@@ -728,7 +692,7 @@ static EndOfLineMarker categorize_eol(char c) {
DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
-int read_line(FILE *f, size_t limit, char **ret) {
+int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
size_t n = 0, allocated = 0, count = 0;
_cleanup_free_ char *buffer = NULL;
int r;
@@ -787,7 +751,7 @@ int read_line(FILE *f, size_t limit, char **ret) {
count++;
- eol = categorize_eol(c);
+ eol = categorize_eol(c, flags);
if (FLAGS_SET(previous_eol, EOL_ZERO) ||
(eol == EOL_NONE && previous_eol != EOL_NONE) ||
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index 300d060cea..53e3f4ef5f 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -61,8 +61,18 @@ int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);
-int read_nul_string(FILE *f, char **ret);
+typedef enum ReadLineFlags {
+ READ_LINE_ONLY_NUL = 1 << 0,
+} ReadLineFlags;
-int read_line(FILE *f, size_t limit, char **ret);
+int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret);
+
+static inline int read_line(FILE *f, size_t limit, char **ret) {
+ return read_line_full(f, limit, 0, ret);
+}
+
+static inline int read_nul_string(FILE *f, size_t limit, char **ret) {
+ return read_line_full(f, limit, READ_LINE_ONLY_NUL, ret);
+}
int safe_fgetc(FILE *f, char *ret);
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 9afae72ae5..fea9cc2633 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -637,8 +637,8 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
if (success) /* The resulting temporary file could not be updated, ignore it. */
return ret;
- r = read_nul_string(f, &name);
- if (r < 0 || isempty(name)) /* Same here... */
+ r = read_nul_string(f, LONG_LINE_MAX, &name);
+ if (r <= 0) /* Same here... */
return ret;
return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name);
@@ -660,10 +660,10 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
_cleanup_free_ char *name = NULL;
uint64_t size;
- r = read_nul_string(f, &name);
+ r = read_nul_string(f, LONG_LINE_MAX, &name);
if (r < 0)
return r;
- if (isempty(name)) /* reached the end */
+ if (r == 0) /* reached the end */
break;
errno = 0;