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.
This commit is contained in:
parent
2a7797e964
commit
41f11239c0
|
@ -667,46 +667,6 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
|
||||||
return fputs(s, f);
|
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 */
|
/* A bitmask of the EOL markers we know */
|
||||||
typedef enum EndOfLineMarker {
|
typedef enum EndOfLineMarker {
|
||||||
EOL_NONE = 0,
|
EOL_NONE = 0,
|
||||||
|
@ -715,11 +675,15 @@ typedef enum EndOfLineMarker {
|
||||||
EOL_THIRTEEN = 1 << 2, /* \r (aka CR) */
|
EOL_THIRTEEN = 1 << 2, /* \r (aka CR) */
|
||||||
} EndOfLineMarker;
|
} EndOfLineMarker;
|
||||||
|
|
||||||
static EndOfLineMarker categorize_eol(char c) {
|
static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) {
|
||||||
if (c == '\n')
|
|
||||||
return EOL_TEN;
|
if (!IN_SET(flags, READ_LINE_ONLY_NUL)) {
|
||||||
if (c == '\r')
|
if (c == '\n')
|
||||||
return EOL_THIRTEEN;
|
return EOL_TEN;
|
||||||
|
if (c == '\r')
|
||||||
|
return EOL_THIRTEEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == '\0')
|
if (c == '\0')
|
||||||
return EOL_ZERO;
|
return EOL_ZERO;
|
||||||
|
|
||||||
|
@ -728,7 +692,7 @@ static EndOfLineMarker categorize_eol(char c) {
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
|
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;
|
size_t n = 0, allocated = 0, count = 0;
|
||||||
_cleanup_free_ char *buffer = NULL;
|
_cleanup_free_ char *buffer = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -787,7 +751,7 @@ int read_line(FILE *f, size_t limit, char **ret) {
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
eol = categorize_eol(c);
|
eol = categorize_eol(c, flags);
|
||||||
|
|
||||||
if (FLAGS_SET(previous_eol, EOL_ZERO) ||
|
if (FLAGS_SET(previous_eol, EOL_ZERO) ||
|
||||||
(eol == EOL_NONE && previous_eol != EOL_NONE) ||
|
(eol == EOL_NONE && previous_eol != EOL_NONE) ||
|
||||||
|
|
|
@ -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 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);
|
int safe_fgetc(FILE *f, char *ret);
|
||||||
|
|
|
@ -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. */
|
if (success) /* The resulting temporary file could not be updated, ignore it. */
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
r = read_nul_string(f, &name);
|
r = read_nul_string(f, LONG_LINE_MAX, &name);
|
||||||
if (r < 0 || isempty(name)) /* Same here... */
|
if (r <= 0) /* Same here... */
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name);
|
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;
|
_cleanup_free_ char *name = NULL;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|
||||||
r = read_nul_string(f, &name);
|
r = read_nul_string(f, LONG_LINE_MAX, &name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (isempty(name)) /* reached the end */
|
if (r == 0) /* reached the end */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
Loading…
Reference in a new issue