From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: berrange@redhat.com
Subject: [RFC 1/4] util: Introduce LogOutput
Date: Tue, 2 Sep 2025 12:30:07 +0200 [thread overview]
Message-ID: <20250902103010.309094-2-richard.henderson@linaro.org> (raw)
In-Reply-To: <20250902103010.309094-1-richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/monitor/monitor.h | 4 +++
include/qemu/log-output.h | 14 ++++++++++
monitor/monitor.c | 54 +++++++++++++++++++++++++++++++--------
stubs/error-printf.c | 11 ++++++++
util/log.c | 7 +++++
5 files changed, 79 insertions(+), 11 deletions(-)
create mode 100644 include/qemu/log-output.h
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index c3740ec616..8c4d73592f 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -4,6 +4,7 @@
#include "block/block.h"
#include "qapi/qapi-types-misc.h"
#include "qemu/readline.h"
+#include "qemu/log-output.h"
#include "exec/hwaddr.h"
typedef struct MonitorHMP MonitorHMP;
@@ -62,4 +63,7 @@ void monitor_register_hmp_info_hrt(const char *name,
int error_vprintf_unless_qmp(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
int error_printf_unless_qmp(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
+const LogOutput *error_log_output(void **popaque);
+const LogOutput *error_log_output_unless_qmp(void **popaque);
+
#endif /* MONITOR_H */
diff --git a/include/qemu/log-output.h b/include/qemu/log-output.h
new file mode 100644
index 0000000000..1d502aae77
--- /dev/null
+++ b/include/qemu/log-output.h
@@ -0,0 +1,14 @@
+#ifndef QEMU_LOG_OUTPUT_H
+#define QEMU_LOG_OUTPUT_H 1
+
+typedef int LogOutputVararg(void *, const char *, ...) G_GNUC_PRINTF(2, 3);
+typedef int LogOutputVaList(void *, const char *, va_list) G_GNUC_PRINTF(2, 0);
+
+typedef struct LogOutput {
+ LogOutputVararg *print;
+ LogOutputVaList *vprint;
+} LogOutput;
+
+extern const LogOutput log_output_stdio;
+
+#endif
diff --git a/monitor/monitor.c b/monitor/monitor.c
index da54e1b1ce..71a3d62e0f 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -268,28 +268,60 @@ void monitor_printc(Monitor *mon, int c)
monitor_printf(mon, "'");
}
+static const LogOutput log_output_monitor = {
+ /* Abuse the Monitor* argument of monitor_printf as void* opaque. */
+ (LogOutputVararg *)monitor_printf,
+ (LogOutputVaList *)monitor_vprintf,
+};
+
+const LogOutput *error_log_output(void **popaque)
+{
+ Monitor *cur_mon = monitor_cur();
+
+ if (cur_mon && !monitor_cur_is_qmp()) {
+ *popaque = cur_mon;
+ return &log_output_monitor;
+ }
+
+ *popaque = stderr;
+ return &log_output_stdio;
+}
+
+const LogOutput *error_log_output_unless_qmp(void **popaque)
+{
+ Monitor *cur_mon = monitor_cur();
+
+ if (!cur_mon) {
+ *popaque = stderr;
+ return &log_output_stdio;
+ }
+ if (!monitor_cur_is_qmp()) {
+ *popaque = cur_mon;
+ return &log_output_monitor;
+ }
+
+ *popaque = NULL;
+ return NULL;
+}
+
/*
* Print to current monitor if we have one, else to stderr.
*/
int error_vprintf(const char *fmt, va_list ap)
{
- Monitor *cur_mon = monitor_cur();
+ void *opaque;
+ const LogOutput *l = error_log_output(&opaque);
- if (cur_mon && !monitor_cur_is_qmp()) {
- return monitor_vprintf(cur_mon, fmt, ap);
- }
- return vfprintf(stderr, fmt, ap);
+ return l->vprint(opaque, fmt, ap);
}
int error_vprintf_unless_qmp(const char *fmt, va_list ap)
{
- Monitor *cur_mon = monitor_cur();
+ void *opaque;
+ const LogOutput *l = error_log_output_unless_qmp(&opaque);
- if (!cur_mon) {
- return vfprintf(stderr, fmt, ap);
- }
- if (!monitor_cur_is_qmp()) {
- return monitor_vprintf(cur_mon, fmt, ap);
+ if (l) {
+ return l->vprint(opaque, fmt, ap);
}
return -1;
}
diff --git a/stubs/error-printf.c b/stubs/error-printf.c
index 0e326d8010..82e4756bda 100644
--- a/stubs/error-printf.c
+++ b/stubs/error-printf.c
@@ -21,3 +21,14 @@ int error_vprintf_unless_qmp(const char *fmt, va_list ap)
{
return error_vprintf(fmt, ap);
}
+
+const LogOutput *error_log_output(void **popaque)
+{
+ *popaque = stderr;
+ return &log_output_stdio;
+}
+
+const LogOutput *error_log_output_unless_qmp(void **popaque)
+{
+ return error_log_output(popaque);
+}
diff --git a/util/log.c b/util/log.c
index fc900cde0c..4b5953dcc7 100644
--- a/util/log.c
+++ b/util/log.c
@@ -28,6 +28,7 @@
#include "qemu/thread.h"
#include "qemu/lockable.h"
#include "qemu/rcu.h"
+#include "qemu/log-output.h"
#ifdef CONFIG_LINUX
#include <sys/syscall.h>
#endif
@@ -592,3 +593,9 @@ ssize_t rust_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
return ret < 0 ? -errno : 0;
}
#endif
+
+const LogOutput log_output_stdio = {
+ /* Abuse the FILE* argument of fprintf as void* opaque. */
+ (LogOutputVararg *)fprintf,
+ (LogOutputVaList *)vfprintf,
+};
--
2.43.0
next prev parent reply other threads:[~2025-09-02 10:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-02 10:30 [RFC 0/4] util: qmessage_context followup Richard Henderson
2025-09-02 10:30 ` Richard Henderson [this message]
2025-09-02 10:30 ` [RFC 2/4] util: Drop QMESSAGE_CONTEXT_SKIP_MONITOR Richard Henderson
2025-09-02 10:30 ` [RFC 3/4] util/message: Use LogOutput Richard Henderson
2025-09-02 10:30 ` [RFC 4/4] util/error-report: Use LogOutput in vreport Richard Henderson
2025-09-02 16:47 ` [RFC 0/4] util: qmessage_context followup Daniel P. Berrangé
2025-09-10 18:05 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250902103010.309094-2-richard.henderson@linaro.org \
--to=richard.henderson@linaro.org \
--cc=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).