]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: use memstream-util 27796/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 26 May 2023 06:40:12 +0000 (15:40 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 31 May 2023 21:48:47 +0000 (06:48 +0900)
29 files changed:
src/basic/string-util.c
src/boot/measure.c
src/busctl/busctl.c
src/core/dbus-cgroup.c
src/core/dbus-execute.c
src/core/fuzz-unit-file.c
src/core/manager-dump.c
src/coredump/coredump.c
src/fuzz/fuzz-json.c
src/home/user-record-sign.c
src/journal/journalctl.c
src/libsystemd/sd-bus/bus-introspect.c
src/libsystemd/sd-bus/bus-introspect.h
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/fuzz-bus-match.c
src/libsystemd/sd-bus/fuzz-bus-message.c
src/libsystemd/sd-bus/test-bus-marshal.c
src/network/generator/network-generator.c
src/oom/oomd-manager.c
src/oom/oomd-util.c
src/resolve/fuzz-resource-record.c
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-manager.c
src/shared/bus-util.c
src/shared/calendarspec.c
src/shared/common-signal.c
src/shared/elf-util.c
src/shared/format-table.c
src/shared/json.c

index 61737ffb41b367221bef78ae804cba16abd0e728..5d259cbf81856fd732813ff09783a0ad8f0a4b34 100644 (file)
@@ -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];
index a3b6e4f9df63881bcb34a6f06fd732c22371b4e0..bd7cc783996d6aaa7c41d94f31e7f3fc12fe5aee 100644 (file)
@@ -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();
 
index 4d69aee5eb727421de3f92c1a7a10e9d4efe50bd..b1ea0dea560376fe92d7d9d4dd0da330632efc57 100644 (file)
@@ -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",
index c373f0bbe8bafb4bb0b61a8d1936337841516a1b..726035b00a3aebf25eb554a88961cda785aa9066 100644 (file)
@@ -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;
 
index 4c413f4d29b141395afe610b00ace87de0829954..a8553c962c316c6c1a331e207d87254ac9f56a95 100644 (file)
@@ -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;
 
index 8e0ace25402b1f6a89f2e55d27a29396dd458d89..a11d6b53b5e4181e37f5d75792e9243d713b28da 100644 (file)
@@ -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, ">>>");
 
index 35143ebddf479a2e6b35c570ccd7ccc760002f3e..e39aff5d899de0aeba38c2c40c157fdd5b6e6475 100644 (file)
@@ -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) {
index a6b0d96488a77536aae71cc788baa91174b35c2d..b355970f0ffa61b27eed8f12dd23280b2d990f27 100644 (file)
@@ -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) {
index c393fcf3944d00f164e3f2730e4c8e38d71f5240..b2cca785015ad03a5d5e984e52649a4101a06efd 100644 (file)
@@ -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);
index ab73fba93fa4c087066c9c32bc093c6c08a93a0b..2cef9969b7a4c178fdeb68b1d806970343fc1dbb 100644 (file)
@@ -3,6 +3,7 @@
 #include <openssl/pem.h>
 
 #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;
 
index 4f9c1f4780c95430fa5c6f6dee52580d66858d22..ab7760290aba631168127e118d5c5234c25bb768 100644 (file)
@@ -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
 
index 27149dfcc334e57325cef4c7ff5d273a3d6f785d..84c8774c6cb1676237a381d5cae7a8d9c4f8fccb 100644 (file)
@@ -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                                       \
         " </interface>\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
-              "<node>\n", i->f);
+              "<node>\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(" </interface>\n", intro->f);
+        if (i->interface_name)
+                fputs(" </interface>\n", i->m.f);
 
         if (interface_name)
-                fprintf(intro->f, " <interface name=\"%s\">\n", interface_name);
+                fprintf(i->m.f, " <interface name=\"%s\">\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, " <node name=\"%s\"/>\n", e);
+                        fprintf(i->m.f, " <node name=\"%s\"/>\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("   <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->m.f);
 
         if (type == _SD_BUS_VTABLE_METHOD && (flags & SD_BUS_VTABLE_METHOD_NO_REPLY))
-                fputs("   <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\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("   <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->m.f);
 
                 if (flags & SD_BUS_VTABLE_PROPERTY_CONST)
-                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->m.f);
                 else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)
-                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->m.f);
                 else if (!(flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))
-                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\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("   <annotation name=\"org.freedesktop.systemd1.Privileged\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.systemd1.Privileged\" value=\"true\"/>\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, "   <arg type=\"%.*s\"", (int) l, signature);
+                fprintf(i->m.f, "   <arg type=\"%.*s\"", (int) l, signature);
 
                 if (**names != '\0') {
-                        fprintf(i->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("  <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
+                                fputs("  <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->m.f);
                         break;
 
                 case _SD_BUS_VTABLE_METHOD:
-                        fprintf(i->f, "  <method name=\"%s\">\n", v->x.method.member);
+                        fprintf(i->m.f, "  <method name=\"%s\">\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("  </method>\n", i->f);
+                        fputs("  </method>\n", i->m.f);
                         break;
 
                 case _SD_BUS_VTABLE_PROPERTY:
                 case _SD_BUS_VTABLE_WRITABLE_PROPERTY:
-                        fprintf(i->f, "  <property name=\"%s\" type=\"%s\" access=\"%s\">\n",
+                        fprintf(i->m.f, "  <property name=\"%s\" type=\"%s\" access=\"%s\">\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("  </property>\n", i->f);
+                        fputs("  </property>\n", i->m.f);
                         break;
 
                 case _SD_BUS_VTABLE_SIGNAL:
-                        fprintf(i->f, "  <signal name=\"%s\">\n", v->x.signal.member);
+                        fprintf(i->m.f, "  <signal name=\"%s\">\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("  </signal>\n", i->f);
+                        fputs("  </signal>\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("</node>\n", i->f);
+        fputs("</node>\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);
 }
index 8bd23a50fd79a84cd6e9609e984e0ece83162591..83bcfb2dadb8f698597d22b56769751a26b7f4bc 100644 (file)
@@ -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;
 };
 
index cc043abfe348edabe0e810d3acd5bfb550a0e5b4..606304d833cd92d3146bf3152422305679fd1440 100644 (file)
@@ -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(
index d183460ea7b6a83160b9958f84874b8a827e019a..b79494d88890f78dac299d3c31f2e0981664f309 100644 (file)
@@ -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;
index af3dbf4d57b0f8b4c9828730ef21f76ffcde0fab..9b04b4422b134e5903a5d24e470d8c752fbc92de 100644 (file)
@@ -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);
 
index 3361b0675e081cf75548a5a621faa905dc1bfe86..0044d33a599fc46169efcf87952622791f6ec611 100644 (file)
@@ -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);
index 569dcdf5114d78ee2b6f0f54bf6169d9ee293fb4..823cd41f7ee0fdfd808497363ffe5bb239e0bec4 100644 (file)
@@ -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);
 }
index c39e75562d4df68527b28f422e0397354e593466..514a4750d27aef7277d0a73be3e747f822131770 100644 (file)
@@ -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);
 }
index 6309d2c4739907c3f81dac56e8eb91eaabb5f05f..810ea7f98d5018ebc7236d5b38054d0382d892df 100644 (file)
@@ -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) {
index 15c465933da3776b3f435d5e82bda4550dacd168..347272135641d420a033150831465952e79c68ba 100644 (file)
@@ -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)
index e7c18c29a0b2e81dbb8f5e40c84d2b63f5871c55..01f79331b959ede8201a5bb8745f9f14d4a980fb 100644 (file)
@@ -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(
index 67786d39fdbca3633c561eecec7bb086faeafc3c..96899ed0ad68a74b662f99437d2c7b8903111c50 100644 (file)
@@ -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) {
index b99883a088e23353c8e32e9be39ff6e222019c64..4eb1b1c316194bda1daa3e715f9687da3c304d17 100644 (file)
@@ -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)
index 9e43a4689ebd2351b6327437b6ed82feb085638d..628c6202e1e57ccf6bbdd48767face478462e70a 100644 (file)
@@ -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) {
index 18964436325216c07f50e6fbd71f40f1644c4def..e4edd180d8e3d253da21bd269f102c8d77425b23 100644 (file)
@@ -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;
         }
 
index 91f42de40004b5308f6cb8d96fa5df1893cc9ba9..5d652d7ac7612f4bb9af9e6d1daaf6a7fcc6101c 100644 (file)
@@ -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)
index 22efd042e2d9996db68ac272b8d90121a3926829..df79a424500ec37f2dc8ff370c170e6de560fecd 100644 (file)
@@ -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) {
index 5bf00f009fcba9a8a8a1a0ff61c611a0a73025d6..26d99a5fba0f59ad7e29730b94edd610eed6c54f 100644 (file)
@@ -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) {