mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-07 17:17:44 +03:00
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);
|
||||
}
|
||||
|
||||
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) ||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user