From 2485b7e2b8a66504e0b6f3bfd03dd48ea5629497 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 May 2023 15:40:12 +0900 Subject: [PATCH] tree-wide: use memstream-util --- src/basic/string-util.c | 20 ++--- src/boot/measure.c | 8 +- src/busctl/busctl.c | 14 ++-- src/core/dbus-cgroup.c | 87 ++++++++++---------- src/core/dbus-execute.c | 18 ++--- src/core/fuzz-unit-file.c | 10 +-- src/core/manager-dump.c | 22 ++---- src/coredump/coredump.c | 25 ++---- src/fuzz/fuzz-json.c | 9 ++- src/home/user-record-sign.c | 14 ++-- src/journal/journalctl.c | 22 ++---- src/libsystemd/sd-bus/bus-introspect.c | 96 ++++++++++++----------- src/libsystemd/sd-bus/bus-introspect.h | 5 +- src/libsystemd/sd-bus/bus-match.c | 15 ++-- src/libsystemd/sd-bus/fuzz-bus-match.c | 8 +- src/libsystemd/sd-bus/fuzz-bus-message.c | 8 +- src/libsystemd/sd-bus/test-bus-marshal.c | 45 +++++------ src/network/generator/network-generator.c | 73 +++-------------- src/oom/oomd-manager.c | 23 ++---- src/oom/oomd-util.c | 23 ++---- src/resolve/fuzz-resource-record.c | 8 +- src/resolve/resolved-dns-dnssec.c | 21 ++--- src/resolve/resolved-manager.c | 19 ++--- src/shared/bus-util.c | 19 ++--- src/shared/calendarspec.c | 21 ++--- src/shared/common-signal.c | 19 ++--- src/shared/elf-util.c | 71 ++++++----------- src/shared/format-table.c | 33 ++++---- src/shared/json.c | 23 ++---- 29 files changed, 301 insertions(+), 478 deletions(-) diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 61737ffb41b..5d259cbf818 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -15,6 +15,7 @@ #include "locale-util.h" #include "macro.h" #include "memory-util.h" +#include "memstream-util.h" #include "string-util.h" #include "strv.h" #include "terminal-util.h" @@ -604,9 +605,9 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { STATE_CSI, STATE_CSO, } state = STATE_OTHER; - _cleanup_free_ char *obuf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0; + _cleanup_(memstream_done) MemStream m = {}; + size_t isz, shift[2] = {}, n_carriage_returns = 0; + FILE *f; assert(ibuf); assert(*ibuf); @@ -629,7 +630,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { /* Note we turn off internal locking on f for performance reasons. It's safe to do so since we * created f here and it doesn't leave our scope. */ - f = open_memstream_unlocked(&obuf, &osz); + f = memstream_init(&m); if (!f) return NULL; @@ -714,19 +715,12 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { } } - if (fflush_and_check(f) < 0) - return NULL; - - f = safe_fclose(f); - - if (!obuf) + char *obuf; + if (memstream_finalize(&m, &obuf, _isz) < 0) return NULL; free_and_replace(*ibuf, obuf); - if (_isz) - *_isz = osz; - if (highlight) { highlight[0] += shift[0]; highlight[1] += shift[1]; diff --git a/src/boot/measure.c b/src/boot/measure.c index a3b6e4f9df6..bd7cc783996 100644 --- a/src/boot/measure.c +++ b/src/boot/measure.c @@ -11,6 +11,7 @@ #include "hexdecoct.h" #include "json.h" #include "main-func.h" +#include "memstream-util.h" #include "openssl-util.h" #include "parse-argument.h" #include "parse-util.h" @@ -779,13 +780,12 @@ static int verb_sign(int argc, char *argv[], void *userdata) { if (!pubkey) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key); } else { - _cleanup_free_ char *data = NULL; - _cleanup_fclose_ FILE *tf = NULL; - size_t sz; + _cleanup_(memstream_done) MemStream m = {}; + FILE *tf; /* No public key was specified, let's derive it automatically, if we can */ - tf = open_memstream_unlocked(&data, &sz); + tf = memstream_init(&m); if (!tf) return log_oom(); diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 4d69aee5eb7..b1ea0dea560 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -21,6 +21,7 @@ #include "json.h" #include "log.h" #include "main-func.h" +#include "memstream-util.h" #include "os-util.h" #include "pager.h" #include "parse-argument.h" @@ -1035,12 +1036,12 @@ static int introspect(int argc, char **argv, void *userdata) { return bus_log_parse_error(r); for (;;) { - _cleanup_fclose_ FILE *mf = NULL; + _cleanup_(memstream_done) MemStream ms = {}; _cleanup_free_ char *buf = NULL; const char *name, *contents; - size_t sz = 0; Member *z; char type; + FILE *mf; r = sd_bus_message_enter_container(reply, 'e', "sv"); if (r < 0) @@ -1062,7 +1063,7 @@ static int introspect(int argc, char **argv, void *userdata) { if (r < 0) return bus_log_parse_error(r); - mf = open_memstream_unlocked(&buf, &sz); + mf = memstream_init(&ms); if (!mf) return log_oom(); @@ -1070,10 +1071,9 @@ static int introspect(int argc, char **argv, void *userdata) { if (r < 0) return bus_log_parse_error(r); - mf = safe_fclose(mf); - - if (!buf) - return bus_log_parse_error(ENOMEM); + r = memstream_finalize(&ms, &buf, NULL); + if (r < 0) + return log_error_errno(r, "Failed to flush and close memstream: %m"); z = set_get(members, &((Member) { .type = "property", diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index c373f0bbe8b..726035b00a3 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -18,6 +18,7 @@ #include "in-addr-prefix-util.h" #include "ip-protocol-list.h" #include "limits-util.h" +#include "memstream-util.h" #include "parse-util.h" #include "path-util.h" #include "percent-util.h" @@ -657,15 +658,16 @@ static int bus_cgroup_set_transient_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) *filters = strv_free(*filters); unit_invalidate_cgroup_bpf(u); - f = open_memstream_unlocked(&buf, &size); + + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -675,7 +677,7 @@ static int bus_cgroup_set_transient_property( STRV_FOREACH(entry, *filters) fprintf(f, "%s=%s\n", name, *entry); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -736,15 +738,15 @@ static int bus_cgroup_set_transient_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) while (c->bpf_foreign_programs) cgroup_context_remove_bpf_foreign_program(c, c->bpf_foreign_programs); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -756,7 +758,7 @@ static int bus_cgroup_set_transient_property( bpf_cgroup_attach_type_to_string(fp->attach_type), fp->bpffs_path); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -1403,9 +1405,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) LIST_FOREACH(device_limits, a, c->io_device_limits) @@ -1413,7 +1415,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_IO); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1422,9 +1424,10 @@ int bus_cgroup_set_property( if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type]) fprintf(f, "%s=%s %" PRIu64 "\n", name, a->path, a->limits[iol_type]); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; + unit_write_setting(u, flags, name, buf); } @@ -1480,9 +1483,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) while (c->io_device_weights) @@ -1490,7 +1493,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_IO); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1498,9 +1501,10 @@ int bus_cgroup_set_property( LIST_FOREACH(device_weights, a, c->io_device_weights) fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; + unit_write_setting(u, flags, name, buf); } @@ -1553,9 +1557,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) while (c->io_device_latencies) @@ -1563,7 +1567,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_IO); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1572,9 +1576,10 @@ int bus_cgroup_set_property( fprintf(f, "IODeviceLatencyTargetSec=%s %s\n", a->path, FORMAT_TIMESPAN(a->target_usec, 1)); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; + unit_write_setting(u, flags, name, buf); } @@ -1638,9 +1643,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) { @@ -1652,7 +1657,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1668,7 +1673,7 @@ int bus_cgroup_set_property( fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps); } - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -1727,9 +1732,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) while (c->blockio_device_weights) @@ -1737,7 +1742,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1745,7 +1750,7 @@ int bus_cgroup_set_property( LIST_FOREACH(device_weights, a, c->blockio_device_weights) fprintf(f, "BlockIODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -1830,9 +1835,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) while (c->device_allow) @@ -1840,7 +1845,7 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1848,9 +1853,10 @@ int bus_cgroup_set_property( LIST_FOREACH(device_allow, a, c->device_allow) fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; + unit_write_setting(u, flags, name, buf); } @@ -1939,14 +1945,15 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; Set **prefixes; bool *reduced; + FILE *f; unit_invalidate_cgroup_bpf(u); - f = open_memstream_unlocked(&buf, &size); + + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1971,7 +1978,7 @@ int bus_cgroup_set_property( IN_ADDR_PREFIX_TO_STRING(p->family, &p->address, p->prefixlen)); } - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -2100,9 +2107,9 @@ int bus_cgroup_set_property( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) cgroup_context_remove_socket_bind(list); @@ -2114,7 +2121,7 @@ int bus_cgroup_set_property( "Starting this unit will fail!", u->id); } - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -2127,7 +2134,7 @@ int bus_cgroup_set_property( fputc('\n', f); } - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 4c413f4d29b..a8553c962c3 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -26,6 +26,7 @@ #include "io-util.h" #include "ioprio-util.h" #include "journal-file.h" +#include "memstream-util.h" #include "missing_ioprio.h" #include "mountpoint-util.h" #include "namespace.h" @@ -1616,14 +1617,14 @@ int bus_set_transient_exec_command( return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + FILE *f; if (n == 0) *exec_command = exec_command_free_list(*exec_command); - f = open_memstream_unlocked(&buf, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1656,7 +1657,7 @@ int bus_set_transient_exec_command( } } - r = fflush_and_check(f); + r = memstream_finalize(&m, &buf, NULL); if (r < 0) return r; @@ -3220,17 +3221,16 @@ int bus_exec_context_set_transient_property( return 1; } else if (streq(name, "EnvironmentFiles")) { - + _cleanup_(memstream_done) MemStream m = {}; _cleanup_free_ char *joined = NULL; - _cleanup_fclose_ FILE *f = NULL; _cleanup_strv_free_ char **l = NULL; - size_t size = 0; + FILE *f; r = sd_bus_message_enter_container(message, 'a', "(sb)"); if (r < 0) return r; - f = open_memstream_unlocked(&joined, &size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -3286,7 +3286,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - r = fflush_and_check(f); + r = memstream_finalize(&m, &joined, NULL); if (r < 0) return r; diff --git a/src/core/fuzz-unit-file.c b/src/core/fuzz-unit-file.c index 8e0ace25402..a11d6b53b5e 100644 --- a/src/core/fuzz-unit-file.c +++ b/src/core/fuzz-unit-file.c @@ -6,14 +6,13 @@ #include "install.h" #include "load-fragment.h" #include "manager-dump.h" +#include "memstream-util.h" #include "string-util.h" #include "unit-serialize.h" #include "utf8.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - _cleanup_free_ char *out = NULL; /* out should be freed after g */ - size_t out_size; - _cleanup_fclose_ FILE *f = NULL, *g = NULL; + _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; UnitType t; _cleanup_(manager_freep) Manager *m = NULL; @@ -79,9 +78,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { u, NULL); - g = open_memstream_unlocked(&out, &out_size); - assert_se(g); + _cleanup_(memstream_done) MemStream ms = {}; + FILE *g; + assert_se(g = memstream_init(&ms)); unit_dump(u, g, ""); manager_dump(m, g, /* patterns= */ NULL, ">>>"); diff --git a/src/core/manager-dump.c b/src/core/manager-dump.c index 35143ebddf4..e39aff5d899 100644 --- a/src/core/manager-dump.c +++ b/src/core/manager-dump.c @@ -5,6 +5,7 @@ #include "fileio.h" #include "hashmap.h" #include "manager-dump.h" +#include "memstream-util.h" #include "unit-serialize.h" void manager_dump_jobs(Manager *s, FILE *f, char **patterns, const char *prefix) { @@ -75,32 +76,19 @@ void manager_dump(Manager *m, FILE *f, char **patterns, const char *prefix) { } int manager_get_dump_string(Manager *m, char **patterns, char **ret) { - _cleanup_free_ char *dump = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size; - int r; + _cleanup_(memstream_done) MemStream ms = {}; + FILE *f; assert(m); assert(ret); - f = open_memstream_unlocked(&dump, &size); + f = memstream_init(&ms); if (!f) return -errno; manager_dump(m, f, patterns, NULL); - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!dump) - return -ENOMEM; - - *ret = TAKE_PTR(dump); - - return 0; + return memstream_finalize(&ms, ret, NULL); } void manager_test_summary(Manager *m) { diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index a6b0d96488a..b355970f0ff 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -36,6 +36,7 @@ #include "macro.h" #include "main-func.h" #include "memory-util.h" +#include "memstream-util.h" #include "mkdir-label.h" #include "parse-util.h" #include "process-util.h" @@ -641,17 +642,16 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s * flags: 0100002 * EOF */ -static int compose_open_fds(pid_t pid, char **open_fds) { +static int compose_open_fds(pid_t pid, char **ret) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_closedir_ DIR *proc_fd_dir = NULL; _cleanup_close_ int proc_fdinfo_fd = -EBADF; - _cleanup_free_ char *buffer = NULL; - _cleanup_fclose_ FILE *stream = NULL; const char *fddelim = "", *path; - size_t size = 0; + FILE *stream; int r; assert(pid >= 0); - assert(open_fds != NULL); + assert(ret); path = procfs_file_alloca(pid, "fd"); proc_fd_dir = opendir(path); @@ -662,7 +662,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) { if (proc_fdinfo_fd < 0) return -errno; - stream = open_memstream_unlocked(&buffer, &size); + stream = memstream_init(&m); if (!stream) return -ENOMEM; @@ -701,18 +701,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) { } } - errno = 0; - stream = safe_fclose(stream); - - if (errno > 0) - return -errno; - - if (!buffer) - return -ENOMEM; - - *open_fds = TAKE_PTR(buffer); - - return 0; + return memstream_finalize(&m, ret, NULL); } static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) { diff --git a/src/fuzz/fuzz-json.c b/src/fuzz/fuzz-json.c index c393fcf3944..b2cca785015 100644 --- a/src/fuzz/fuzz-json.c +++ b/src/fuzz/fuzz-json.c @@ -5,12 +5,13 @@ #include "fd-util.h" #include "fuzz.h" #include "json.h" +#include "memstream-util.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - _cleanup_free_ char *out = NULL; /* out should be freed after g */ - size_t out_size; - _cleanup_fclose_ FILE *f = NULL, *g = NULL; + _cleanup_(memstream_done) MemStream m = {}; _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + _cleanup_fclose_ FILE *f = NULL; + FILE *g = NULL; int r; /* Disable most logging if not running standalone */ @@ -27,7 +28,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { } if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) - assert_se(g = open_memstream_unlocked(&out, &out_size)); + assert_se(g = memstream_init(&m)); json_variant_dump(v, 0, g ?: stdout, NULL); json_variant_dump(v, JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR|JSON_FORMAT_SOURCE, g ?: stdout, NULL); diff --git a/src/home/user-record-sign.c b/src/home/user-record-sign.c index ab73fba93fa..2cef9969b7a 100644 --- a/src/home/user-record-sign.c +++ b/src/home/user-record-sign.c @@ -3,6 +3,7 @@ #include #include "fd-util.h" +#include "memstream-util.h" #include "user-record-sign.h" #include "fileio.h" @@ -30,13 +31,14 @@ static int user_record_signable_json(UserRecord *ur, char **ret) { DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD_CTX*, EVP_MD_CTX_free, NULL); int user_record_sign(UserRecord *ur, EVP_PKEY *private_key, UserRecord **ret) { + _cleanup_(memstream_done) MemStream m = {}; _cleanup_(json_variant_unrefp) JsonVariant *encoded = NULL, *v = NULL; _cleanup_(user_record_unrefp) UserRecord *signed_ur = NULL; _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *md_ctx = NULL; _cleanup_free_ char *text = NULL, *key = NULL; - size_t signature_size = 0, key_size = 0; _cleanup_free_ void *signature = NULL; - _cleanup_fclose_ FILE *mf = NULL; + size_t signature_size = 0; + FILE *f; int r; assert(ur); @@ -65,14 +67,14 @@ int user_record_sign(UserRecord *ur, EVP_PKEY *private_key, UserRecord **ret) { if (EVP_DigestSign(md_ctx, signature, &signature_size, (uint8_t*) text, strlen(text)) <= 0) return -EIO; - mf = open_memstream_unlocked(&key, &key_size); - if (!mf) + f = memstream_init(&m); + if (!f) return -ENOMEM; - if (PEM_write_PUBKEY(mf, private_key) <= 0) + if (PEM_write_PUBKEY(f, private_key) <= 0) return -EIO; - r = fflush_and_check(mf); + r = memstream_finalize(&m, &key, NULL); if (r < 0) return r; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 4f9c1f4780c..ab7760290ab 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -49,6 +49,7 @@ #include "logs-show.h" #include "main-func.h" #include "memory-util.h" +#include "memstream-util.h" #include "missing_sched.h" #include "mkdir.h" #include "mount-util.h" @@ -1758,15 +1759,14 @@ static int format_journal_url( sd_id128_t machine, bool full, char **ret_url) { - _cleanup_free_ char *url = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t url_size = 0; - int r; + + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; assert(seed); assert(seed_size > 0); - f = open_memstream_unlocked(&url, &url_size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1787,17 +1787,7 @@ static int format_journal_url( fprintf(f, ";hostname=%s", hn); } - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!url) - return -ENOMEM; - - *ret_url = TAKE_PTR(url); - return 0; + return memstream_finalize(&m, ret_url, NULL); } #endif diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 27149dfcc33..84c8774c6cb 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -8,6 +8,7 @@ #include "fd-util.h" #include "fileio.h" #include "memory-util.h" +#include "memstream-util.h" #include "string-util.h" #define BUS_INTROSPECT_DOCTYPE \ @@ -68,52 +69,59 @@ " \n" int introspect_begin(struct introspect *i, bool trusted) { + FILE *f; + assert(i); *i = (struct introspect) { .trusted = trusted, }; - i->f = open_memstream_unlocked(&i->introspection, &i->size); - if (!i->f) + f = memstream_init(&i->m); + if (!f) return -ENOMEM; fputs(BUS_INTROSPECT_DOCTYPE - "\n", i->f); + "\n", f); return 0; } int introspect_write_default_interfaces(struct introspect *i, bool object_manager) { assert(i); + assert(i->m.f); fputs(BUS_INTROSPECT_INTERFACE_PEER BUS_INTROSPECT_INTERFACE_INTROSPECTABLE - BUS_INTROSPECT_INTERFACE_PROPERTIES, i->f); + BUS_INTROSPECT_INTERFACE_PROPERTIES, i->m.f); if (object_manager) - fputs(BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->f); + fputs(BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->m.f); return 0; } -static int set_interface_name(struct introspect *intro, const char *interface_name) { - if (streq_ptr(intro->interface_name, interface_name)) +static int set_interface_name(struct introspect *i, const char *interface_name) { + assert(i); + assert(i->m.f); + + if (streq_ptr(i->interface_name, interface_name)) return 0; - if (intro->interface_name) - fputs(" \n", intro->f); + if (i->interface_name) + fputs(" \n", i->m.f); if (interface_name) - fprintf(intro->f, " \n", interface_name); + fprintf(i->m.f, " \n", interface_name); - return free_and_strdup(&intro->interface_name, interface_name); + return free_and_strdup(&i->interface_name, interface_name); } int introspect_write_child_nodes(struct introspect *i, OrderedSet *s, const char *prefix) { char *node; assert(i); + assert(i->m.f); assert(prefix); assert_se(set_interface_name(i, NULL) >= 0); @@ -123,7 +131,7 @@ int introspect_write_child_nodes(struct introspect *i, OrderedSet *s, const char e = object_path_startswith(node, prefix); if (e && e[0]) - fprintf(i->f, " \n", e); + fprintf(i->m.f, " \n", e); free(node); } @@ -132,28 +140,31 @@ int introspect_write_child_nodes(struct introspect *i, OrderedSet *s, const char } static void introspect_write_flags(struct introspect *i, int type, uint64_t flags) { + assert(i); + assert(i->m.f); + if (flags & SD_BUS_VTABLE_DEPRECATED) - fputs(" \n", i->f); + fputs(" \n", i->m.f); if (type == _SD_BUS_VTABLE_METHOD && (flags & SD_BUS_VTABLE_METHOD_NO_REPLY)) - fputs(" \n", i->f); + fputs(" \n", i->m.f); if (IN_SET(type, _SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY)) { if (flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT) - fputs(" \n", i->f); + fputs(" \n", i->m.f); if (flags & SD_BUS_VTABLE_PROPERTY_CONST) - fputs(" \n", i->f); + fputs(" \n", i->m.f); else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) - fputs(" \n", i->f); + fputs(" \n", i->m.f); else if (!(flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) - fputs(" \n", i->f); + fputs(" \n", i->m.f); } if (!i->trusted && IN_SET(type, _SD_BUS_VTABLE_METHOD, _SD_BUS_VTABLE_WRITABLE_PROPERTY) && !(flags & SD_BUS_VTABLE_UNPRIVILEGED)) - fputs(" \n", i->f); + fputs(" \n", i->m.f); } /* Note that "names" is both an input and an output parameter. It initially points to the first argument name in a @@ -161,6 +172,9 @@ static void introspect_write_flags(struct introspect *i, int type, uint64_t flag static int introspect_write_arguments(struct introspect *i, const char *signature, const char **names, const char *direction) { int r; + assert(i); + assert(i->m.f); + for (;;) { size_t l; @@ -171,17 +185,17 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur if (r < 0) return r; - fprintf(i->f, " m.f, " f, " name=\"%s\"", *names); + fprintf(i->m.f, " name=\"%s\"", *names); *names += strlen(*names) + 1; } if (direction) - fprintf(i->f, " direction=\"%s\"/>\n", direction); + fprintf(i->m.f, " direction=\"%s\"/>\n", direction); else - fputs("/>\n", i->f); + fputs("/>\n", i->m.f); signature += l; } @@ -197,6 +211,7 @@ int introspect_write_interface( int r; assert(i); + assert(i->m.f); assert(interface_name); r = set_interface_name(i, interface_name); @@ -216,36 +231,36 @@ int introspect_write_interface( case _SD_BUS_VTABLE_START: if (v->flags & SD_BUS_VTABLE_DEPRECATED) - fputs(" \n", i->f); + fputs(" \n", i->m.f); break; case _SD_BUS_VTABLE_METHOD: - fprintf(i->f, " \n", v->x.method.member); + fprintf(i->m.f, " \n", v->x.method.member); if (bus_vtable_has_names(vtable)) names = strempty(v->x.method.names); introspect_write_arguments(i, strempty(v->x.method.signature), &names, "in"); introspect_write_arguments(i, strempty(v->x.method.result), &names, "out"); introspect_write_flags(i, v->type, v->flags); - fputs(" \n", i->f); + fputs(" \n", i->m.f); break; case _SD_BUS_VTABLE_PROPERTY: case _SD_BUS_VTABLE_WRITABLE_PROPERTY: - fprintf(i->f, " \n", + fprintf(i->m.f, " \n", v->x.property.member, v->x.property.signature, v->type == _SD_BUS_VTABLE_WRITABLE_PROPERTY ? "readwrite" : "read"); introspect_write_flags(i, v->type, v->flags); - fputs(" \n", i->f); + fputs(" \n", i->m.f); break; case _SD_BUS_VTABLE_SIGNAL: - fprintf(i->f, " \n", v->x.signal.member); + fprintf(i->m.f, " \n", v->x.signal.member); if (bus_vtable_has_names(vtable)) names = strempty(v->x.signal.names); introspect_write_arguments(i, strempty(v->x.signal.signature), &names, NULL); introspect_write_flags(i, v->type, v->flags); - fputs(" \n", i->f); + fputs(" \n", i->m.f); break; } @@ -255,26 +270,14 @@ int introspect_write_interface( } int introspect_finish(struct introspect *i, char **ret) { - int r; - assert(i); + assert(i->m.f); assert_se(set_interface_name(i, NULL) >= 0); - fputs("\n", i->f); + fputs("\n", i->m.f); - r = fflush_and_check(i->f); - if (r < 0) - return r; - - i->f = safe_fclose(i->f); - - if (!i->introspection) - return -ENOMEM; - - *ret = TAKE_PTR(i->introspection); - - return 0; + return memstream_finalize(&i->m, ret, NULL); } void introspect_done(struct introspect *i) { @@ -282,7 +285,6 @@ void introspect_done(struct introspect *i) { /* Normally introspect_finish() does all the work, this is just a backup for error paths */ - safe_fclose(i->f); + memstream_done(&i->m); free(i->interface_name); - free(i->introspection); } diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h index 8bd23a50fd7..83bcfb2dadb 100644 --- a/src/libsystemd/sd-bus/bus-introspect.h +++ b/src/libsystemd/sd-bus/bus-introspect.h @@ -5,13 +5,12 @@ #include "sd-bus.h" +#include "memstream-util.h" #include "ordered-set.h" struct introspect { - FILE *f; + MemStream m; char *interface_name; - char *introspection; - size_t size; bool trusted; }; diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index cc043abfe34..606304d833c 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -7,6 +7,7 @@ #include "fd-util.h" #include "fileio.h" #include "hexdecoct.h" +#include "memstream-util.h" #include "sort-util.h" #include "string-util.h" #include "strv.h" @@ -823,9 +824,8 @@ int bus_match_parse( } char *bus_match_to_string(struct bus_match_component *components, size_t n_components) { - _cleanup_free_ char *buffer = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t size = 0; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; int r; if (n_components <= 0) @@ -833,7 +833,7 @@ char *bus_match_to_string(struct bus_match_component *components, size_t n_compo assert(components); - f = open_memstream_unlocked(&buffer, &size); + f = memstream_init(&m); if (!f) return NULL; @@ -855,13 +855,12 @@ char *bus_match_to_string(struct bus_match_component *components, size_t n_compo fputc('\'', f); } - r = fflush_and_check(f); + char *buffer; + r = memstream_finalize(&m, &buffer, NULL); if (r < 0) return NULL; - f = safe_fclose(f); - - return TAKE_PTR(buffer); + return buffer; } int bus_match_add( diff --git a/src/libsystemd/sd-bus/fuzz-bus-match.c b/src/libsystemd/sd-bus/fuzz-bus-match.c index d183460ea7b..b79494d8889 100644 --- a/src/libsystemd/sd-bus/fuzz-bus-match.c +++ b/src/libsystemd/sd-bus/fuzz-bus-match.c @@ -7,14 +7,14 @@ #include "fd-util.h" #include "fileio.h" #include "fuzz.h" +#include "memstream-util.h" DEFINE_TRIVIAL_DESTRUCTOR(bus_match_donep, struct bus_match_node, bus_match_free); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - _cleanup_free_ char *out = NULL; /* out should be freed after g */ - size_t out_size; - _cleanup_fclose_ FILE *g = NULL; + _cleanup_(memstream_done) MemStream m = {}; _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + FILE *g = NULL; int r; if (outside_size_range(size, 0, 65536)) @@ -40,7 +40,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { }; if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) - assert_se(g = open_memstream_unlocked(&out, &out_size)); + assert_se(g = memstream_init(&m)); for (size_t offset = 0; offset < size; ) { _cleanup_free_ char *line = NULL; diff --git a/src/libsystemd/sd-bus/fuzz-bus-message.c b/src/libsystemd/sd-bus/fuzz-bus-message.c index af3dbf4d57b..9b04b4422b1 100644 --- a/src/libsystemd/sd-bus/fuzz-bus-message.c +++ b/src/libsystemd/sd-bus/fuzz-bus-message.c @@ -7,14 +7,14 @@ #include "fd-util.h" #include "fileio.h" #include "fuzz.h" +#include "memstream-util.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - _cleanup_free_ char *out = NULL; /* out should be freed after g */ - size_t out_size; - _cleanup_fclose_ FILE *g = NULL; + _cleanup_(memstream_done) MemStream ms = {}; _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ void *buffer = NULL; + FILE *g = NULL; int r; /* We don't want to fill the logs with messages about parse errors. @@ -34,7 +34,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TAKE_PTR(buffer); if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) - assert_se(g = open_memstream_unlocked(&out, &out_size)); + assert_se(g = memstream_init(&ms)); sd_bus_message_dump(m, g ?: stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER); diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c index 3361b0675e0..0044d33a599 100644 --- a/src/libsystemd/sd-bus/test-bus-marshal.c +++ b/src/libsystemd/sd-bus/test-bus-marshal.c @@ -22,6 +22,7 @@ #include "fd-util.h" #include "fileio.h" #include "log.h" +#include "memstream-util.h" #include "tests.h" static void test_bus_path_encode_unique(void) { @@ -108,20 +109,19 @@ static void test_bus_label_escape(void) { int main(int argc, char *argv[]) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *copy = NULL; - int r, boolean; - const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature; - uint8_t u, v; - void *buffer = NULL; - size_t sz; - _cleanup_free_ char *h = NULL; + _cleanup_free_ char *h = NULL, *first = NULL, *second = NULL, *third = NULL; const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; - char *s; - _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL; - _cleanup_fclose_ FILE *ms = NULL; - size_t first_size = 0, second_size = 0, third_size = 0; + const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature; + size_t sz, first_size, second_size = 0, third_size = 0; _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; - double dbl; + _cleanup_(memstream_done) MemStream ms = {}; + void *buffer = NULL; + int r, boolean; uint64_t u64; + uint8_t u, v; + double dbl; + FILE *mf; + char *s; test_setup_logging(LOG_INFO); @@ -191,10 +191,9 @@ int main(int argc, char *argv[]) { sd_bus_message_dump(m, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER); - ms = open_memstream_unlocked(&first, &first_size); - sd_bus_message_dump(m, ms, 0); - fflush(ms); - assert_se(!ferror(ms)); + assert_se(mf = memstream_init(&ms)); + sd_bus_message_dump(m, mf, 0); + assert_se(memstream_finalize(&ms, &first, &first_size) >= 0); r = bus_message_get_blob(m, &buffer, &sz); assert_se(r >= 0); @@ -247,11 +246,9 @@ int main(int argc, char *argv[]) { sd_bus_message_dump(m, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER); - fclose(ms); - ms = open_memstream_unlocked(&second, &second_size); - sd_bus_message_dump(m, ms, 0); - fflush(ms); - assert_se(!ferror(ms)); + assert_se(mf = memstream_init(&ms)); + sd_bus_message_dump(m, mf, 0); + assert_se(memstream_finalize(&ms, &second, &second_size) >= 0); assert_se(first_size == second_size); assert_se(memcmp(first, second, first_size) == 0); @@ -353,11 +350,9 @@ int main(int argc, char *argv[]) { r = sd_bus_message_seal(copy, 4712, 0); assert_se(r >= 0); - fclose(ms); - ms = open_memstream_unlocked(&third, &third_size); - sd_bus_message_dump(copy, ms, 0); - fflush(ms); - assert_se(!ferror(ms)); + assert_se(mf = memstream_init(&ms)); + sd_bus_message_dump(copy, mf, 0); + assert_se(memstream_finalize(&ms, &third, &third_size) >= 0); printf("<%.*s>\n", (int) first_size, first); printf("<%.*s>\n", (int) third_size, third); diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 569dcdf5114..823cd41f7ee 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -5,6 +5,7 @@ #include "hostname-util.h" #include "log.h" #include "macro.h" +#include "memstream-util.h" #include "netif-naming-scheme.h" #include "network-generator.h" #include "parse-util.h" @@ -1198,97 +1199,49 @@ void link_dump(Link *link, FILE *f) { } int network_format(Network *network, char **ret) { - _cleanup_free_ char *s = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; - int r; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; assert(network); assert(ret); - f = open_memstream_unlocked(&s, &sz); + f = memstream_init(&m); if (!f) return -ENOMEM; network_dump(network, f); - /* Add terminating 0, so that the output buffer is a valid string. */ - fputc('\0', f); - - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!s) - return -ENOMEM; - - *ret = TAKE_PTR(s); - assert(sz > 0); - return (int) sz - 1; + return memstream_finalize(&m, ret, NULL); } int netdev_format(NetDev *netdev, char **ret) { - _cleanup_free_ char *s = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; - int r; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; assert(netdev); assert(ret); - f = open_memstream_unlocked(&s, &sz); + f = memstream_init(&m); if (!f) return -ENOMEM; netdev_dump(netdev, f); - /* Add terminating 0, so that the output buffer is a valid string. */ - fputc('\0', f); - - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!s) - return -ENOMEM; - - *ret = TAKE_PTR(s); - assert(sz > 0); - return (int) sz - 1; + return memstream_finalize(&m, ret, NULL); } int link_format(Link *link, char **ret) { - _cleanup_free_ char *s = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; - int r; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; assert(link); assert(ret); - f = open_memstream_unlocked(&s, &sz); + f = memstream_init(&m); if (!f) return -ENOMEM; link_dump(link, f); - /* Add terminating 0, so that the output buffer is a valid string. */ - fputc('\0', f); - - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!s) - return -ENOMEM; - - *ret = TAKE_PTR(s); - assert(sz > 0); - return (int) sz - 1; + return memstream_finalize(&m, ret, NULL); } diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c index c39e75562d4..514a4750d27 100644 --- a/src/oom/oomd-manager.c +++ b/src/oom/oomd-manager.c @@ -10,6 +10,7 @@ #include "fileio.h" #include "format-util.h" #include "memory-util.h" +#include "memstream-util.h" #include "oomd-manager-bus.h" #include "oomd-manager.h" #include "path-util.h" @@ -807,18 +808,16 @@ int manager_start( } int manager_get_dump_string(Manager *m, char **ret) { - _cleanup_free_ char *dump = NULL; - _cleanup_fclose_ FILE *f = NULL; + _cleanup_(memstream_done) MemStream ms = {}; OomdCGroupContext *c; - size_t size; - int r; + FILE *f; assert(m); assert(ret); - f = open_memstream_unlocked(&dump, &size); + f = memstream_init(&ms); if (!f) - return -errno; + return -ENOMEM; fprintf(f, "Dry Run: %s\n" @@ -840,15 +839,5 @@ int manager_get_dump_string(Manager *m, char **ret) { HASHMAP_FOREACH(c, m->monitored_mem_pressure_cgroup_contexts) oomd_dump_memory_pressure_cgroup_context(c, f, "\t"); - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!dump) - return -ENOMEM; - - *ret = TAKE_PTR(dump); - return 0; + return memstream_finalize(&ms, ret, NULL); } diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 6309d2c4739..810ea7f98d5 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -7,6 +7,7 @@ #include "fd-util.h" #include "fileio.h" #include "format-util.h" +#include "memstream-util.h" #include "oomd-util.h" #include "parse-util.h" #include "path-util.h" @@ -281,30 +282,20 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) { typedef void (*dump_candidate_func)(const OomdCGroupContext *ctx, FILE *f, const char *prefix); static int dump_kill_candidates(OomdCGroupContext **sorted, int n, int dump_until, dump_candidate_func dump_func) { + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; + /* Try dumping top offendors, ignoring any errors that might happen. */ - _cleanup_free_ char *dump = NULL; - _cleanup_fclose_ FILE *f = NULL; - int r; - size_t size; - f = open_memstream_unlocked(&dump, &size); + f = memstream_init(&m); if (!f) - return -errno; + return -ENOMEM; fprintf(f, "Considered %d cgroups for killing, top candidates were:\n", n); for (int i = 0; i < dump_until; i++) dump_func(sorted[i], f, "\t"); - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!dump) - return -ENOMEM; - - return log_dump(LOG_INFO, dump); + return memstream_dump(LOG_INFO, &m); } int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char **ret_selected) { diff --git a/src/resolve/fuzz-resource-record.c b/src/resolve/fuzz-resource-record.c index 15c465933da..34727213564 100644 --- a/src/resolve/fuzz-resource-record.c +++ b/src/resolve/fuzz-resource-record.c @@ -3,14 +3,14 @@ #include "fd-util.h" #include "fuzz.h" #include "memory-util.h" +#include "memstream-util.h" #include "resolved-dns-packet.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - _cleanup_free_ char *out = NULL; /* out should be freed after f */ - size_t out_size; - _cleanup_fclose_ FILE *f = NULL; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL, *copy = NULL; _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; if (outside_size_range(size, 0, DNS_PACKET_SIZE_MAX)) return 0; @@ -21,7 +21,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(copy = dns_resource_record_copy(rr)); assert_se(dns_resource_record_equal(copy, rr) > 0); - assert_se(f = open_memstream_unlocked(&out, &out_size)); + assert_se(f = memstream_init(&m)); (void) fprintf(f, "%s", strna(dns_resource_record_to_string(rr))); if (dns_resource_record_to_json(rr, &v) < 0) diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index e7c18c29a0b..01f79331b95 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -7,6 +7,7 @@ #include "gcrypt-util.h" #include "hexdecoct.h" #include "memory-util.h" +#include "memstream-util.h" #include "openssl-util.h" #include "resolved-dns-dnssec.h" #include "resolved-dns-packet.h" @@ -810,11 +811,10 @@ static int dnssec_rrset_serialize_sig( char **ret_sig_data, size_t *ret_sig_size) { - _cleanup_free_ char *sig_data = NULL; - size_t sig_size = 0; - _cleanup_fclose_ FILE *f = NULL; + _cleanup_(memstream_done) MemStream m = {}; uint8_t wire_format_name[DNS_WIRE_FORMAT_HOSTNAME_MAX]; DnsResourceRecord *rr; + FILE *f; int r; assert(rrsig); @@ -823,7 +823,7 @@ static int dnssec_rrset_serialize_sig( assert(ret_sig_data); assert(ret_sig_size); - f = open_memstream_unlocked(&sig_data, &sig_size); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -866,18 +866,7 @@ static int dnssec_rrset_serialize_sig( fwrite(DNS_RESOURCE_RECORD_RDATA(rr), 1, l, f); } - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); /* sig_data may be reallocated when f is closed. */ - - if (!sig_data) - return -ENOMEM; - - *ret_sig_data = TAKE_PTR(sig_data); - *ret_sig_size = sig_size; - return 0; + return memstream_finalize(&m, ret_sig_data, ret_sig_size); } static int dnssec_rrset_verify_sig( diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 67786d39fdb..96899ed0ad6 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -19,6 +19,7 @@ #include "hostname-util.h" #include "idn-util.h" #include "io-util.h" +#include "memstream-util.h" #include "missing_network.h" #include "missing_socket.h" #include "netlink-util.h" @@ -492,16 +493,15 @@ static int manager_watch_hostname(Manager *m) { } static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { - _cleanup_free_ char *buffer = NULL; - _cleanup_fclose_ FILE *f = NULL; + _cleanup_(memstream_done) MemStream ms = {}; Manager *m = ASSERT_PTR(userdata); - size_t size = 0; Link *l; + FILE *f; assert(s); assert(si); - f = open_memstream_unlocked(&buffer, &size); + f = memstream_init(&ms); if (!f) return log_oom(); @@ -516,16 +516,7 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si LIST_FOREACH(servers, server, l->dns_servers) dns_server_dump(server, f); - if (fflush_and_check(f) < 0) - return log_oom(); - - f = safe_fclose(f); - - if (!buffer) - return -ENOMEM; - - log_dump(LOG_INFO, buffer); - return 0; + return memstream_dump(LOG_INFO, &ms); } static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index b99883a088e..4eb1b1c3161 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -20,6 +20,7 @@ #include "bus-util.h" #include "data-fd-util.h" #include "fd-util.h" +#include "memstream-util.h" #include "path-util.h" #include "socket-util.h" #include "stdio-util.h" @@ -610,26 +611,26 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) { } static int method_dump_memory_state_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { - _cleanup_free_ char *dump = NULL; /* keep this above dump_file, so that it's freed after */ - _cleanup_fclose_ FILE *dump_file = NULL; + _cleanup_(memstream_done) MemStream m = {}; + _cleanup_free_ char *dump = NULL; _cleanup_close_ int fd = -EBADF; size_t dump_size; + FILE *f; int r; assert(message); - dump_file = open_memstream(&dump, &dump_size); - if (!dump_file) + f = memstream_init(&m); + if (!f) return -ENOMEM; - r = RET_NERRNO(malloc_info(/* options= */ 0, dump_file)); + r = RET_NERRNO(malloc_info(/* options= */ 0, f)); if (r < 0) return r; - dump_file = safe_fclose(dump_file); - - if (!dump) - return -ENOMEM; + r = memstream_finalize(&m, &dump, &dump_size); + if (r < 0) + return r; fd = acquire_data_fd(dump, dump_size, 0); if (fd < 0) diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c index 9e43a4689eb..628c6202e1e 100644 --- a/src/shared/calendarspec.c +++ b/src/shared/calendarspec.c @@ -15,6 +15,7 @@ #include "fd-util.h" #include "fileio.h" #include "macro.h" +#include "memstream-util.h" #include "parse-util.h" #include "process-util.h" #include "sort-util.h" @@ -337,15 +338,13 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us } int calendar_spec_to_string(const CalendarSpec *c, char **ret) { - _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; - int r; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; assert(c); assert(ret); - f = open_memstream_unlocked(&buf, &sz); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -383,17 +382,7 @@ int calendar_spec_to_string(const CalendarSpec *c, char **ret) { } } - r = fflush_and_check(f); - if (r < 0) - return r; - - f = safe_fclose(f); - - if (!buf) - return -ENOMEM; - - *ret = TAKE_PTR(buf); - return 0; + return memstream_finalize(&m, ret, NULL); } static int parse_weekdays(const char **p, CalendarSpec *c) { diff --git a/src/shared/common-signal.c b/src/shared/common-signal.c index 18964436325..e4edd180d8e 100644 --- a/src/shared/common-signal.c +++ b/src/shared/common-signal.c @@ -3,13 +3,13 @@ #include "common-signal.h" #include "fd-util.h" #include "fileio.h" +#include "memstream-util.h" #include "process-util.h" #include "signal-util.h" int sigrtmin18_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { struct sigrtmin18_info *info = userdata; _cleanup_free_ char *comm = NULL; - int r; assert(s); assert(si); @@ -57,11 +57,10 @@ int sigrtmin18_handler(sd_event_source *s, const struct signalfd_siginfo *si, vo break; case COMMON_SIGNAL_COMMAND_MALLOC_INFO: { - _cleanup_free_ char *data = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; - f = open_memstream_unlocked(&data, &sz); + f = memstream_init(&m); if (!f) { log_oom(); break; @@ -72,15 +71,7 @@ int sigrtmin18_handler(sd_event_source *s, const struct signalfd_siginfo *si, vo break; } - fputc(0, f); - - r = fflush_and_check(f); - if (r < 0) { - log_error_errno(r, "Failed to flush malloc_info() buffer: %m"); - break; - } - - log_dump(LOG_INFO, data); + (void) memstream_dump(LOG_INFO, &m); break; } diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 91f42de4000..5d652d7ac76 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -22,6 +22,7 @@ #include "hexdecoct.h" #include "io-util.h" #include "macro.h" +#include "memstream-util.h" #include "process-util.h" #include "rlimit-util.h" #include "string-util.h" @@ -149,7 +150,7 @@ int dlopen_elf(void) { } typedef struct StackContext { - FILE *f; + MemStream m; Dwfl *dwfl; Elf *elf; unsigned n_thread; @@ -161,7 +162,7 @@ typedef struct StackContext { static void stack_context_done(StackContext *c) { assert(c); - c->f = safe_fclose(c->f); + memstream_done(&c->m); if (c->dwfl) { sym_dwfl_end(c->dwfl); @@ -232,8 +233,8 @@ static int frame_callback(Dwfl_Frame *frame, void *userdata) { module_offset = pc - start; } - if (c->f) - fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s + 0x%" PRIx64 ")\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname), module_offset); + if (c->m.f) + fprintf(c->m.f, "#%-2u 0x%016" PRIx64 " %s (%s + 0x%" PRIx64 ")\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname), module_offset); c->n_frame++; return DWARF_CB_OK; @@ -248,14 +249,14 @@ static int thread_callback(Dwfl_Thread *thread, void *userdata) { if (c->n_thread >= THREADS_MAX) return DWARF_CB_ABORT; - if (c->n_thread != 0 && c->f) - fputc('\n', c->f); + if (c->n_thread != 0 && c->m.f) + fputc('\n', c->m.f); c->n_frame = 0; - if (c->f) { + if (c->m.f) { tid = sym_dwfl_thread_tid(thread); - fprintf(c->f, "Stack trace of thread " PID_FMT ":\n", tid); + fprintf(c->m.f, "Stack trace of thread " PID_FMT ":\n", tid); } if (sym_dwfl_thread_getframes(thread, frame_callback, c) < 0) @@ -294,10 +295,10 @@ static void report_module_metadata(StackContext *c, const char *name, JsonVarian assert(c); assert(name); - if (!c->f) + if (!c->m.f) return; - fprintf(c->f, "Module %s", name); + fprintf(c->m.f, "Module %s", name); if (metadata) { const char @@ -311,14 +312,14 @@ static void report_module_metadata(StackContext *c, const char *name, JsonVarian /* Version/architecture is only meaningful with a package name. * Skip the detailed fields if package is unknown. */ _cleanup_free_ char *id = build_package_reference(type, package, version, arch); - fprintf(c->f, " from %s", strnull(id)); + fprintf(c->m.f, " from %s", strnull(id)); } if (build_id && !(package && version)) - fprintf(c->f, ", build-id=%s", build_id); + fprintf(c->m.f, ", build-id=%s", build_id); } - fputs("\n", c->f); + fputs("\n", c->m.f); } static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *elf, bool *ret_interpreter_found, StackContext *c) { @@ -461,8 +462,8 @@ static int parse_buildid(Dwfl_Module *mod, Elf *elf, const char *name, StackCont /* If we don't find a build-id, note it in the journal message, and try * anyway to find the package metadata. It's unlikely to have the latter * without the former, but there's no hard rule. */ - if (c->f) - fprintf(c->f, "Module %s without build-id.\n", name); + if (c->m.f) + fprintf(c->m.f, "Module %s without build-id.\n", name); } else { /* We will later parse package metadata json and pass it to our caller. Prepare the * build-id in json format too, so that it can be appended and parsed cleanly. It @@ -568,12 +569,10 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant ** _cleanup_(json_variant_unrefp) JsonVariant *package_metadata = NULL; _cleanup_set_free_ Set *modules = NULL; - _cleanup_free_ char *buf = NULL; /* buf should be freed last, c.f closed first (via stack_context_done) */ _cleanup_(stack_context_done) StackContext c = { .package_metadata = &package_metadata, .modules = &modules, }; - size_t sz = 0; int r; assert(fd >= 0); @@ -581,11 +580,8 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant ** if (lseek(fd, 0, SEEK_SET) == (off_t) -1) return log_warning_errno(errno, "Failed to seek to beginning of the core file: %m"); - if (ret) { - c.f = open_memstream_unlocked(&buf, &sz); - if (!c.f) - return log_oom(); - } + if (ret && !memstream_init(&c.m)) + return log_oom(); sym_elf_version(EV_CURRENT); @@ -613,16 +609,9 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant ** return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Could not parse core file, dwfl_getthreads() failed: %s", sym_dwfl_errmsg(sym_dwfl_errno())); if (ret) { - r = fflush_and_check(c.f); + r = memstream_finalize(&c.m, ret, NULL); if (r < 0) return log_warning_errno(r, "Could not parse core file, flushing file buffer failed: %m"); - - c.f = safe_fclose(c.f); - - if (!buf) - return log_oom(); - - *ret = TAKE_PTR(buf); } if (ret_package_metadata) @@ -634,14 +623,12 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant ** static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **ret_package_metadata) { _cleanup_(json_variant_unrefp) JsonVariant *package_metadata = NULL, *elf_metadata = NULL; _cleanup_set_free_ Set *modules = NULL; - _cleanup_free_ char *buf = NULL; /* buf should be freed last, c.f closed first (via stack_context_done) */ _cleanup_(stack_context_done) StackContext c = { .package_metadata = &package_metadata, .modules = &modules, }; const char *elf_type; GElf_Ehdr elf_header; - size_t sz = 0; int r; assert(fd >= 0); @@ -649,11 +636,8 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r if (lseek(fd, 0, SEEK_SET) == (off_t) -1) return log_warning_errno(errno, "Failed to seek to beginning of the ELF file: %m"); - if (ret) { - c.f = open_memstream_unlocked(&buf, &sz); - if (!c.f) - return log_oom(); - } + if (ret && !memstream_init(&c.m)) + return log_oom(); sym_elf_version(EV_CURRENT); @@ -672,7 +656,7 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r return log_warning_errno(r, "Failed to inspect core file: %m"); if (out) - fprintf(c.f, "%s", out); + fprintf(c.m.f, "%s", out); elf_type = "coredump"; } else { @@ -722,7 +706,7 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r return log_warning_errno(r, "Failed to merge JSON objects: %m"); if (ret) - fprintf(c.f, "ELF object binary architecture: %s\n", elf_architecture); + fprintf(c.m.f, "ELF object binary architecture: %s\n", elf_architecture); } #endif @@ -732,16 +716,9 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r return log_warning_errno(r, "Failed to merge JSON objects: %m"); if (ret) { - r = fflush_and_check(c.f); + r = memstream_finalize(&c.m, ret, NULL); if (r < 0) return log_warning_errno(r, "Could not parse ELF file, flushing file buffer failed: %m"); - - c.f = safe_fclose(c.f); - - if (!buf) - return log_oom(); - - *ret = TAKE_PTR(buf); } if (ret_package_metadata) diff --git a/src/shared/format-table.c b/src/shared/format-table.c index 22efd042e2d..df79a424500 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -18,6 +18,7 @@ #include "id128-util.h" #include "in-addr-util.h" #include "memory-util.h" +#include "memstream-util.h" #include "pager.h" #include "parse-util.h" #include "path-util.h" @@ -1446,11 +1447,10 @@ static int table_data_compare(const size_t *a, const size_t *b, Table *t) { } static char* format_strv_width(char **strv, size_t column_width) { - _cleanup_free_ char *buf = NULL; /* buf must be freed after f */ - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; - f = open_memstream_unlocked(&buf, &sz); + f = memstream_init(&m); if (!f) return NULL; @@ -1471,11 +1471,11 @@ static char* format_strv_width(char **strv, size_t column_width) { } } - if (fflush_and_check(f) < 0) + char *buf; + if (memstream_finalize(&m, &buf, NULL) < 0) return NULL; - f = safe_fclose(f); - return TAKE_PTR(buf); + return buf; } static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercasing, size_t column_width, bool *have_soft) { @@ -2530,12 +2530,14 @@ int table_print(Table *t, FILE *f) { } int table_format(Table *t, char **ret) { - _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; + _cleanup_(memstream_done) MemStream m = {}; + FILE *f; int r; - f = open_memstream_unlocked(&buf, &sz); + assert(t); + assert(ret); + + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -2543,14 +2545,7 @@ int table_format(Table *t, char **ret) { if (r < 0) return r; - f = safe_fclose(f); - - if (!buf) - return -ENOMEM; - - *ret = TAKE_PTR(buf); - - return 0; + return memstream_finalize(&m, ret, NULL); } size_t table_get_rows(Table *t) { diff --git a/src/shared/json.c b/src/shared/json.c index 5bf00f009fc..26d99a5fba0 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -20,6 +20,7 @@ #include "macro.h" #include "math-util.h" #include "memory-util.h" +#include "memstream-util.h" #include "string-table.h" #include "string-util.h" #include "strv.h" @@ -1768,9 +1769,9 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha } int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) { - _cleanup_free_ char *s = NULL; - _cleanup_fclose_ FILE *f = NULL; - size_t sz = 0; + _cleanup_(memstream_done) MemStream m = {}; + size_t sz; + FILE *f; int r; /* Returns the length of the generated string (without the terminating NUL), @@ -1782,7 +1783,7 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) { if (flags & JSON_FORMAT_OFF) return -ENOEXEC; - f = open_memstream_unlocked(&s, &sz); + f = memstream_init(&m); if (!f) return -ENOMEM; @@ -1790,21 +1791,11 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) { if (r < 0) return r; - /* Add terminating 0, so that the output buffer is a valid string. */ - fputc('\0', f); - - r = fflush_and_check(f); + r = memstream_finalize(&m, ret, &sz); if (r < 0) return r; - f = safe_fclose(f); - - if (!s) - return -ENOMEM; - - *ret = TAKE_PTR(s); - assert(sz > 0); - return (int) sz - 1; + return sz; } int json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) { -- 2.47.3