tree-wide: use memstream-util

This commit is contained in:
Yu Watanabe
2023-06-01 06:48:47 +09:00
parent abe72100cf
commit 2485b7e2b8
29 changed files with 302 additions and 479 deletions
+10 -9
View 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)
+5 -16
View 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) {
+5 -14
View 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;
}
+24 -47
View 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)
+14 -19
View 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) {
+7 -16
View 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) {