#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"
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);
/* 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;
}
}
- 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];
#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"
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();
#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"
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)
if (r < 0)
return bus_log_parse_error(r);
- mf = open_memstream_unlocked(&buf, &sz);
+ mf = memstream_init(&ms);
if (!mf)
return log_oom();
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",
#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"
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;
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;
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;
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;
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)
unit_invalidate_cgroup(u, CGROUP_MASK_IO);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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);
}
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)
unit_invalidate_cgroup(u, CGROUP_MASK_IO);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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);
}
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)
unit_invalidate_cgroup(u, CGROUP_MASK_IO);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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);
}
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) {
unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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;
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)
unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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;
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)
unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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);
}
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;
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;
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);
"Starting this unit will fail!", u->id);
}
- f = open_memstream_unlocked(&buf, &size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
fputc('\n', f);
}
- r = fflush_and_check(f);
+ r = memstream_finalize(&m, &buf, NULL);
if (r < 0)
return r;
#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"
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;
}
}
- r = fflush_and_check(f);
+ r = memstream_finalize(&m, &buf, NULL);
if (r < 0)
return r;
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;
if (r < 0)
return r;
- r = fflush_and_check(f);
+ r = memstream_finalize(&m, &joined, NULL);
if (r < 0)
return r;
#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;
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, ">>>");
#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) {
}
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) {
#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"
* 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);
if (proc_fdinfo_fd < 0)
return -errno;
- stream = open_memstream_unlocked(&buffer, &size);
+ stream = memstream_init(&m);
if (!stream)
return -ENOMEM;
}
}
- 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) {
#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 */
}
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);
#include <openssl/pem.h>
#include "fd-util.h"
+#include "memstream-util.h"
#include "user-record-sign.h"
#include "fileio.h"
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);
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;
#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"
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;
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
#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);
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);
}
}
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
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;
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;
}
int r;
assert(i);
+ assert(i->m.f);
assert(interface_name);
r = set_interface_name(i, interface_name);
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;
}
}
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) {
/* 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);
}
#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;
};
#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"
}
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)
assert(components);
- f = open_memstream_unlocked(&buffer, &size);
+ f = memstream_init(&m);
if (!f)
return NULL;
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(
#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))
};
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;
#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.
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);
#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) {
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);
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);
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);
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);
#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"
}
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);
}
#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"
}
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"
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);
}
#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"
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) {
#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;
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)
#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"
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);
assert(ret_sig_data);
assert(ret_sig_size);
- f = open_memstream_unlocked(&sig_data, &sig_size);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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(
#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"
}
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();
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) {
#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"
}
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)
#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"
}
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;
}
}
- 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) {
#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);
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;
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;
}
#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"
}
typedef struct StackContext {
- FILE *f;
+ MemStream m;
Dwfl *dwfl;
Elf *elf;
unsigned n_thread;
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);
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;
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)
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
/* 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) {
/* 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
_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);
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);
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)
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);
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);
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 {
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
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)
#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"
}
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;
}
}
- 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) {
}
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;
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) {
#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"
}
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),
if (flags & JSON_FORMAT_OFF)
return -ENOEXEC;
- f = open_memstream_unlocked(&s, &sz);
+ f = memstream_init(&m);
if (!f)
return -ENOMEM;
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) {