qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH for-11.0 0/8] chardev: cleanup
@ 2025-11-29 13:43 Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 1/8] chardev: ChardevClass: consistent naming for handlers Vladimir Sementsov-Ogievskiy
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: pbonzini, qemu-devel, vsementsov, d-tatianin

Hi all.

Here is a cleanup for chardev code:

 - improve naming
 - add boolean return for some errp-functions
 - simplify open() API

Vladimir Sementsov-Ogievskiy (8):
  chardev: ChardevClass: consistent naming for handlers
  chardev: consistent naming for ChardevClass handlers implementations
  chardev: .chr_open(): drop be_opened parameter
  chardev: .chr_open(): add boolean return value
  chardev/char-pty: store pty_name into PtyChardev state
  chardev: introduce .chr_get_pty_name() handler
  chardev: rework filename handling
  chardev/char: qemu_char_open(): add return value

 chardev/baum.c                                | 12 ++--
 chardev/char-console.c                        | 10 ++--
 chardev/char-fe.c                             |  8 +--
 chardev/char-file.c                           | 26 ++++----
 chardev/char-hub.c                            | 27 ++++-----
 chardev/char-mux.c                            | 30 ++++++----
 chardev/char-null.c                           |  9 +--
 chardev/char-parallel.c                       | 41 ++++++-------
 chardev/char-pipe.c                           | 30 +++++-----
 chardev/char-pty.c                            | 52 ++++++++--------
 chardev/char-ringbuf.c                        | 20 ++++---
 chardev/char-serial.c                         | 39 ++++++------
 chardev/char-socket.c                         | 59 +++++++++----------
 chardev/char-stdio.c                          | 30 +++++-----
 chardev/char-udp.c                            | 16 ++---
 chardev/char-win-stdio.c                      | 25 ++++----
 chardev/char.c                                | 51 ++++++++--------
 chardev/msmouse.c                             | 13 ++--
 chardev/spice.c                               | 50 ++++++++--------
 chardev/wctablet.c                            | 10 ++--
 gdbstub/system.c                              | 12 ++--
 hw/char/xen_console.c                         |  7 ++-
 hw/misc/ivshmem-pci.c                         |  4 +-
 include/chardev/char.h                        | 37 +++++++++---
 .../codeconverter/test_regexps.py             |  2 +-
 ui/console-vc.c                               | 12 ++--
 ui/dbus-chardev.c                             | 16 +++--
 ui/dbus.c                                     |  4 +-
 ui/gtk.c                                      | 14 ++---
 ui/spice-app.c                                | 18 +++---
 ui/vdagent.c                                  | 17 +++---
 31 files changed, 354 insertions(+), 347 deletions(-)

-- 
2.48.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/8] chardev: ChardevClass: consistent naming for handlers
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations Vladimir Sementsov-Ogievskiy
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: pbonzini, qemu-devel, vsementsov, d-tatianin, Samuel Thibault,
	Alex Bennée, Philippe Mathieu-Daudé, Eduardo Habkost

Most handlers have name prefixed with "chr_". That's a good practice
which helps to grep them. Convert the rest: .parse, .open,
get/set_msgfds.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/baum.c                                      | 2 +-
 chardev/char-console.c                              | 2 +-
 chardev/char-fe.c                                   | 8 ++++----
 chardev/char-file.c                                 | 4 ++--
 chardev/char-hub.c                                  | 4 ++--
 chardev/char-mux.c                                  | 4 ++--
 chardev/char-null.c                                 | 2 +-
 chardev/char-parallel.c                             | 4 ++--
 chardev/char-pipe.c                                 | 4 ++--
 chardev/char-pty.c                                  | 4 ++--
 chardev/char-ringbuf.c                              | 4 ++--
 chardev/char-serial.c                               | 4 ++--
 chardev/char-socket.c                               | 8 ++++----
 chardev/char-stdio.c                                | 4 ++--
 chardev/char-udp.c                                  | 4 ++--
 chardev/char-win-stdio.c                            | 2 +-
 chardev/char.c                                      | 8 ++++----
 chardev/msmouse.c                                   | 2 +-
 chardev/spice.c                                     | 8 ++++----
 chardev/wctablet.c                                  | 2 +-
 gdbstub/system.c                                    | 2 +-
 include/chardev/char.h                              | 8 ++++----
 scripts/codeconverter/codeconverter/test_regexps.py | 2 +-
 ui/console-vc.c                                     | 4 ++--
 ui/dbus-chardev.c                                   | 8 ++++----
 ui/dbus.c                                           | 4 ++--
 ui/gtk.c                                            | 2 +-
 ui/spice-app.c                                      | 6 +++---
 ui/vdagent.c                                        | 4 ++--
 29 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/chardev/baum.c b/chardev/baum.c
index ad68321504..6b81c97d10 100644
--- a/chardev/baum.c
+++ b/chardev/baum.c
@@ -676,7 +676,7 @@ static void char_braille_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = baum_chr_open;
+    cc->chr_open = baum_chr_open;
     cc->chr_write = baum_chr_write;
     cc->chr_accept_input = baum_chr_accept_input;
 }
diff --git a/chardev/char-console.c b/chardev/char-console.c
index 7e1bf642eb..9a2e012d53 100644
--- a/chardev/char-console.c
+++ b/chardev/char-console.c
@@ -38,7 +38,7 @@ static void char_console_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = qemu_chr_open_win_con;
+    cc->chr_open = qemu_chr_open_win_con;
 }
 
 static const TypeInfo char_console_type_info = {
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index 34b83fc1c4..a44f267373 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -130,8 +130,8 @@ int qemu_chr_fe_get_msgfds(CharFrontend *c, int *fds, int len)
         return -1;
     }
 
-    return CHARDEV_GET_CLASS(s)->get_msgfds ?
-        CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1;
+    return CHARDEV_GET_CLASS(s)->chr_get_msgfds ?
+        CHARDEV_GET_CLASS(s)->chr_get_msgfds(s, fds, len) : -1;
 }
 
 int qemu_chr_fe_set_msgfds(CharFrontend *c, int *fds, int num)
@@ -142,8 +142,8 @@ int qemu_chr_fe_set_msgfds(CharFrontend *c, int *fds, int num)
         return -1;
     }
 
-    return CHARDEV_GET_CLASS(s)->set_msgfds ?
-        CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1;
+    return CHARDEV_GET_CLASS(s)->chr_set_msgfds ?
+        CHARDEV_GET_CLASS(s)->chr_set_msgfds(s, fds, num) : -1;
 }
 
 void qemu_chr_fe_accept_input(CharFrontend *c)
diff --git a/chardev/char-file.c b/chardev/char-file.c
index 1f7adf592f..1e293e7054 100644
--- a/chardev/char-file.c
+++ b/chardev/char-file.c
@@ -133,8 +133,8 @@ static void char_file_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_file_out;
-    cc->open = qmp_chardev_open_file;
+    cc->chr_parse = qemu_chr_parse_file_out;
+    cc->chr_open = qmp_chardev_open_file;
 }
 
 static const TypeInfo char_file_type_info = {
diff --git a/chardev/char-hub.c b/chardev/char-hub.c
index d0967c2233..082baa84ab 100644
--- a/chardev/char-hub.c
+++ b/chardev/char-hub.c
@@ -276,8 +276,8 @@ static void char_hub_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_hub;
-    cc->open = qemu_chr_open_hub;
+    cc->chr_parse = qemu_chr_parse_hub;
+    cc->chr_open = qemu_chr_open_hub;
     cc->chr_write = hub_chr_write;
     cc->chr_add_watch = hub_chr_add_watch;
     /* We handle events from backends only */
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index db9e89f441..c82c2da56d 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -451,8 +451,8 @@ static void char_mux_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_mux;
-    cc->open = qemu_chr_open_mux;
+    cc->chr_parse = qemu_chr_parse_mux;
+    cc->chr_open = qemu_chr_open_mux;
     cc->chr_write = mux_chr_write;
     cc->chr_accept_input = mux_chr_accept_input;
     cc->chr_add_watch = mux_chr_add_watch;
diff --git a/chardev/char-null.c b/chardev/char-null.c
index 89cb85da79..674603b380 100644
--- a/chardev/char-null.c
+++ b/chardev/char-null.c
@@ -38,7 +38,7 @@ static void char_null_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = null_chr_open;
+    cc->chr_open = null_chr_open;
 }
 
 static const TypeInfo char_null_type_info = {
diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index 62a44b2f96..a0839b784b 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -274,8 +274,8 @@ static void char_parallel_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_parallel;
-    cc->open = qmp_chardev_open_parallel;
+    cc->chr_parse = qemu_chr_parse_parallel;
+    cc->chr_open = qmp_chardev_open_parallel;
     cc->chr_ioctl = pp_ioctl;
 }
 
diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c
index e9f3bb8290..a2cd322efe 100644
--- a/chardev/char-pipe.c
+++ b/chardev/char-pipe.c
@@ -182,8 +182,8 @@ static void char_pipe_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_pipe;
-    cc->open = qemu_chr_open_pipe;
+    cc->chr_parse = qemu_chr_parse_pipe;
+    cc->chr_open = qemu_chr_open_pipe;
 }
 
 static const TypeInfo char_pipe_type_info = {
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 652b0bd9e7..1a15082b02 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -394,8 +394,8 @@ static void char_pty_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = char_pty_parse;
-    cc->open = char_pty_open;
+    cc->chr_parse = char_pty_parse;
+    cc->chr_open = char_pty_open;
     cc->chr_write = char_pty_chr_write;
     cc->chr_update_read_handler = pty_chr_update_read_handler;
     cc->chr_add_watch = pty_chr_add_watch;
diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 98aadb6acf..6d5ba667bb 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -227,8 +227,8 @@ static void char_ringbuf_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_ringbuf;
-    cc->open = qemu_chr_open_ringbuf;
+    cc->chr_parse = qemu_chr_parse_ringbuf;
+    cc->chr_open = qemu_chr_open_ringbuf;
     cc->chr_write = ringbuf_chr_write;
 }
 
diff --git a/chardev/char-serial.c b/chardev/char-serial.c
index 4c6ca713eb..97ed7adf73 100644
--- a/chardev/char-serial.c
+++ b/chardev/char-serial.c
@@ -305,8 +305,8 @@ static void char_serial_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_serial;
-    cc->open = qmp_chardev_open_serial;
+    cc->chr_parse = qemu_chr_parse_serial;
+    cc->chr_open = qmp_chardev_open_serial;
 #ifndef _WIN32
     cc->chr_ioctl = tty_serial_ioctl;
 #endif
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 26d2f11202..12916af7ff 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1576,14 +1576,14 @@ static void char_socket_class_init(ObjectClass *oc, const void *data)
 
     cc->supports_yank = true;
 
-    cc->parse = qemu_chr_parse_socket;
-    cc->open = qmp_chardev_open_socket;
+    cc->chr_parse = qemu_chr_parse_socket;
+    cc->chr_open = qmp_chardev_open_socket;
     cc->chr_wait_connected = tcp_chr_wait_connected;
     cc->chr_write = tcp_chr_write;
     cc->chr_sync_read = tcp_chr_sync_read;
     cc->chr_disconnect = tcp_chr_disconnect;
-    cc->get_msgfds = tcp_get_msgfds;
-    cc->set_msgfds = tcp_set_msgfds;
+    cc->chr_get_msgfds = tcp_get_msgfds;
+    cc->chr_set_msgfds = tcp_set_msgfds;
     cc->chr_add_client = tcp_chr_add_client;
     cc->chr_add_watch = tcp_chr_add_watch;
     cc->chr_update_read_handler = tcp_chr_update_read_handler;
diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
index 2568164a10..b7e9af1388 100644
--- a/chardev/char-stdio.c
+++ b/chardev/char-stdio.c
@@ -142,9 +142,9 @@ static void char_stdio_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_stdio;
+    cc->chr_parse = qemu_chr_parse_stdio;
 #ifndef _WIN32
-    cc->open = qemu_chr_open_stdio;
+    cc->chr_open = qemu_chr_open_stdio;
     cc->chr_set_echo = qemu_chr_set_echo_stdio;
 #endif
 }
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 572fab0ad1..a6f496ac7b 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -223,8 +223,8 @@ static void char_udp_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_udp;
-    cc->open = qmp_chardev_open_udp;
+    cc->chr_parse = qemu_chr_parse_udp;
+    cc->chr_open = qmp_chardev_open_udp;
     cc->chr_write = udp_chr_write;
     cc->chr_update_read_handler = udp_chr_update_read_handler;
 }
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index fb802a00b1..26e67aef1c 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -260,7 +260,7 @@ static void char_win_stdio_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = qemu_chr_open_stdio;
+    cc->chr_open = qemu_chr_open_stdio;
     cc->chr_write = win_stdio_write;
     cc->chr_set_echo = qemu_chr_set_echo_win_stdio;
 }
diff --git a/chardev/char.c b/chardev/char.c
index 3e432195a5..df37d1df16 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -267,8 +267,8 @@ static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
         }
     }
 
-    if (cc->open) {
-        cc->open(chr, backend, be_opened, errp);
+    if (cc->chr_open) {
+        cc->chr_open(chr, backend, be_opened, errp);
     }
 }
 
@@ -604,8 +604,8 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)
     backend = g_new0(ChardevBackend, 1);
     backend->type = CHARDEV_BACKEND_KIND_NULL;
 
-    if (cc->parse) {
-        cc->parse(opts, backend, &local_err);
+    if (cc->chr_parse) {
+        cc->chr_parse(opts, backend, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
             qapi_free_ChardevBackend(backend);
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index 1a55755d39..8405016489 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -271,7 +271,7 @@ static void char_msmouse_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = msmouse_chr_open;
+    cc->chr_open = msmouse_chr_open;
     cc->chr_write = msmouse_chr_write;
     cc->chr_accept_input = msmouse_chr_accept_input;
     cc->chr_ioctl = msmouse_ioctl;
diff --git a/chardev/spice.c b/chardev/spice.c
index db53b49da2..d55b3693b6 100644
--- a/chardev/spice.c
+++ b/chardev/spice.c
@@ -370,8 +370,8 @@ static void char_spicevmc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_spice_vmc;
-    cc->open = qemu_chr_open_spice_vmc;
+    cc->chr_parse = qemu_chr_parse_spice_vmc;
+    cc->chr_open = qemu_chr_open_spice_vmc;
     cc->chr_set_fe_open = spice_vmc_set_fe_open;
 }
 
@@ -386,8 +386,8 @@ static void char_spiceport_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = qemu_chr_parse_spice_port;
-    cc->open = qemu_chr_open_spice_port;
+    cc->chr_parse = qemu_chr_parse_spice_port;
+    cc->chr_open = qemu_chr_open_spice_port;
     cc->chr_set_fe_open = spice_port_set_fe_open;
 }
 
diff --git a/chardev/wctablet.c b/chardev/wctablet.c
index 0dc6ef08f5..8285a56e7b 100644
--- a/chardev/wctablet.c
+++ b/chardev/wctablet.c
@@ -346,7 +346,7 @@ static void wctablet_chr_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = wctablet_chr_open;
+    cc->chr_open = wctablet_chr_open;
     cc->chr_write = wctablet_chr_write;
     cc->chr_ioctl = wctablet_chr_ioctl;
     cc->chr_accept_input = wctablet_chr_accept_input;
diff --git a/gdbstub/system.c b/gdbstub/system.c
index e2220c1ae4..fe2afeb107 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -244,7 +244,7 @@ static void char_gdb_class_init(ObjectClass *oc, const void *data)
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
     cc->internal = true;
-    cc->open = gdb_monitor_open;
+    cc->chr_open = gdb_monitor_open;
     cc->chr_write = gdb_monitor_write;
 }
 
diff --git a/include/chardev/char.h b/include/chardev/char.h
index b65e9981c1..2baf2a8a1a 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -257,10 +257,10 @@ struct ChardevClass {
     bool supports_yank;
 
     /* parse command line options and populate QAPI @backend */
-    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
+    void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 
     /* called after construction, open/starts the backend */
-    void (*open)(Chardev *chr, ChardevBackend *backend,
+    void (*chr_open)(Chardev *chr, ChardevBackend *backend,
                  bool *be_opened, Error **errp);
 
     /* write buf to the backend */
@@ -282,10 +282,10 @@ struct ChardevClass {
     int (*chr_ioctl)(Chardev *s, int cmd, void *arg);
 
     /* get ancillary-received fds during last read */
-    int (*get_msgfds)(Chardev *s, int* fds, int num);
+    int (*chr_get_msgfds)(Chardev *s, int* fds, int num);
 
     /* set ancillary fds to be sent with next write */
-    int (*set_msgfds)(Chardev *s, int *fds, int num);
+    int (*chr_set_msgfds)(Chardev *s, int *fds, int num);
 
     /* accept the given fd */
     int (*chr_add_client)(Chardev *chr, int fd);
diff --git a/scripts/codeconverter/codeconverter/test_regexps.py b/scripts/codeconverter/codeconverter/test_regexps.py
index b00e9ef15b..d3a5cc3ad3 100644
--- a/scripts/codeconverter/codeconverter/test_regexps.py
+++ b/scripts/codeconverter/codeconverter/test_regexps.py
@@ -57,7 +57,7 @@ def fullmatch(regexp, s):
 
     print(RE_TYPEINFO_START)
     assert re.search(RE_TYPEINFO_START, r'''
-    cc->open = qmp_chardev_open_file;
+    cc->chr_open = qmp_chardev_open_file;
 }
 
 static const TypeInfo char_file_type_info = {
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 830842064d..931068d43a 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -1185,8 +1185,8 @@ static void char_vc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = vc_chr_parse;
-    cc->open = vc_chr_open;
+    cc->chr_parse = vc_chr_parse;
+    cc->chr_open = vc_chr_open;
     cc->chr_write = vc_chr_write;
     cc->chr_accept_input = vc_chr_accept_input;
     cc->chr_set_echo = vc_chr_set_echo;
diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c
index d05dddaf81..f6c426e220 100644
--- a/ui/dbus-chardev.c
+++ b/ui/dbus-chardev.c
@@ -205,12 +205,12 @@ dbus_chr_open(Chardev *chr, ChardevBackend *backend,
     opts = qemu_opts_create(qemu_find_opts("chardev"), NULL, 0, &error_abort);
     qemu_opt_set(opts, "server", "on", &error_abort);
     qemu_opt_set(opts, "wait", "off", &error_abort);
-    CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->parse(
+    CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_parse(
         opts, be, errp);
     if (*errp) {
         return;
     }
-    CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->open(
+    CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_open(
         chr, be, be_opened, errp);
 }
 
@@ -274,8 +274,8 @@ char_dbus_class_init(ObjectClass *oc, const void *data)
     DBusChardevClass *klass = DBUS_CHARDEV_CLASS(oc);
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse = dbus_chr_parse;
-    cc->open = dbus_chr_open;
+    cc->chr_parse = dbus_chr_parse;
+    cc->chr_open = dbus_chr_open;
     cc->chr_set_fe_open = dbus_chr_set_fe_open;
     cc->chr_set_echo = dbus_chr_set_echo;
     klass->parent_chr_be_event = cc->chr_be_event;
diff --git a/ui/dbus.c b/ui/dbus.c
index d2dff33258..31f6eb1189 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -451,8 +451,8 @@ dbus_vc_class_init(ObjectClass *oc, const void *data)
     DBusVCClass *klass = DBUS_VC_CLASS(oc);
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    klass->parent_parse = cc->parse;
-    cc->parse = dbus_vc_parse;
+    klass->parent_parse = cc->chr_parse;
+    cc->chr_parse = dbus_vc_parse;
 }
 
 static const TypeInfo dbus_vc_type_info = {
diff --git a/ui/gtk.c b/ui/gtk.c
index 48571bedbf..7aa97907ed 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1985,7 +1985,7 @@ static void char_gd_vc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->open = gd_vc_open;
+    cc->chr_open = gd_vc_open;
     cc->chr_write = gd_vc_chr_write;
     cc->chr_accept_input = gd_vc_chr_accept_input;
     cc->chr_set_echo = gd_vc_chr_set_echo;
diff --git a/ui/spice-app.c b/ui/spice-app.c
index 24f78f305c..ea0b62a22b 100644
--- a/ui/spice-app.c
+++ b/ui/spice-app.c
@@ -106,10 +106,10 @@ static void char_vc_class_init(ObjectClass *oc, const void *data)
     VCChardevClass *vc = CHARDEV_VC_CLASS(oc);
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    vc->parent_open = cc->open;
+    vc->parent_open = cc->chr_open;
 
-    cc->parse = vc_chr_parse;
-    cc->open = vc_chr_open;
+    cc->chr_parse = vc_chr_parse;
+    cc->chr_open = vc_chr_open;
     cc->chr_set_echo = vc_chr_set_echo;
 }
 
diff --git a/ui/vdagent.c b/ui/vdagent.c
index 660686c9c0..9972a9c476 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -924,8 +924,8 @@ static void vdagent_chr_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->parse            = vdagent_chr_parse;
-    cc->open             = vdagent_chr_open;
+    cc->chr_parse        = vdagent_chr_parse;
+    cc->chr_open         = vdagent_chr_open;
     cc->chr_write        = vdagent_chr_write;
     cc->chr_set_fe_open  = vdagent_chr_set_fe_open;
     cc->chr_accept_input = vdagent_chr_accept_input;
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 1/8] chardev: ChardevClass: consistent naming for handlers Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 14:07   ` Philippe Mathieu-Daudé
  2025-11-29 13:43 ` [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter Vladimir Sementsov-Ogievskiy
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: pbonzini, qemu-devel, vsementsov, d-tatianin, Alex Bennée,
	Philippe Mathieu-Daudé, Eduardo Habkost

Most handlers implementations has name like {unit_name}_{handler_name},
which is usual and well-recognized pattern. Convert the rest (especially
with useless qemu_ prefixes and misleading qmp_ prefixes) to the common
pattern.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/char-console.c                        | 10 ++---
 chardev/char-file.c                           | 16 ++++----
 chardev/char-hub.c                            | 15 ++++---
 chardev/char-mux.c                            | 15 ++++---
 chardev/char-parallel.c                       | 28 ++++++-------
 chardev/char-pipe.c                           | 24 +++++------
 chardev/char-pty.c                            | 19 +++++----
 chardev/char-ringbuf.c                        | 16 ++++----
 chardev/char-serial.c                         | 28 ++++++-------
 chardev/char-socket.c                         | 25 ++++++------
 chardev/char-stdio.c                          | 22 +++++-----
 chardev/char-udp.c                            | 15 ++++---
 chardev/char-win-stdio.c                      | 20 +++++-----
 chardev/msmouse.c                             |  4 +-
 chardev/spice.c                               | 40 +++++++++----------
 gdbstub/system.c                              |  8 ++--
 .../codeconverter/test_regexps.py             |  2 +-
 ui/gtk.c                                      |  4 +-
 18 files changed, 153 insertions(+), 158 deletions(-)

diff --git a/chardev/char-console.c b/chardev/char-console.c
index 9a2e012d53..f3ef1a7748 100644
--- a/chardev/char-console.c
+++ b/chardev/char-console.c
@@ -26,10 +26,10 @@
 #include "chardev/char-win.h"
 #include "qemu/module.h"
 
-static void qemu_chr_open_win_con(Chardev *chr,
-                                  ChardevBackend *backend,
-                                  bool *be_opened,
-                                  Error **errp)
+static void console_chr_open(Chardev *chr,
+                             ChardevBackend *backend,
+                             bool *be_opened,
+                             Error **errp)
 {
     win_chr_set_file(chr, GetStdHandle(STD_OUTPUT_HANDLE), true);
 }
@@ -38,7 +38,7 @@ static void char_console_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_open = qemu_chr_open_win_con;
+    cc->chr_open = console_chr_open;
 }
 
 static const TypeInfo char_console_type_info = {
diff --git a/chardev/char-file.c b/chardev/char-file.c
index 1e293e7054..568600bb7c 100644
--- a/chardev/char-file.c
+++ b/chardev/char-file.c
@@ -34,10 +34,10 @@
 #include "chardev/char-fd.h"
 #endif
 
-static void qmp_chardev_open_file(Chardev *chr,
-                                  ChardevBackend *backend,
-                                  bool *be_opened,
-                                  Error **errp)
+static void file_chr_open(Chardev *chr,
+                          ChardevBackend *backend,
+                          bool *be_opened,
+                          Error **errp)
 {
     ChardevFile *file = backend->u.file.data;
 #ifdef _WIN32
@@ -102,8 +102,8 @@ static void qmp_chardev_open_file(Chardev *chr,
 #endif
 }
 
-static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
-                                    Error **errp)
+static void file_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                           Error **errp)
 {
     const char *path = qemu_opt_get(opts, "path");
     const char *inpath = qemu_opt_get(opts, "input-path");
@@ -133,8 +133,8 @@ static void char_file_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_file_out;
-    cc->chr_open = qmp_chardev_open_file;
+    cc->chr_parse = file_chr_parse;
+    cc->chr_open = file_chr_open;
 }
 
 static const TypeInfo char_file_type_info = {
diff --git a/chardev/char-hub.c b/chardev/char-hub.c
index 082baa84ab..11556dfa72 100644
--- a/chardev/char-hub.c
+++ b/chardev/char-hub.c
@@ -203,10 +203,10 @@ static void hub_chr_update_read_handlers(Chardev *chr)
     }
 }
 
-static void qemu_chr_open_hub(Chardev *chr,
-                                 ChardevBackend *backend,
-                                 bool *be_opened,
-                                 Error **errp)
+static void hub_chr_open(Chardev *chr,
+                         ChardevBackend *backend,
+                         bool *be_opened,
+                         Error **errp)
 {
     ChardevHub *hub = backend->u.hub.data;
     HubChardev *d = HUB_CHARDEV(chr);
@@ -245,8 +245,7 @@ static void qemu_chr_open_hub(Chardev *chr,
     *be_opened = false;
 }
 
-static void qemu_chr_parse_hub(QemuOpts *opts, ChardevBackend *backend,
-                                  Error **errp)
+static void hub_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     ChardevHub *hub;
     strList **tail;
@@ -276,8 +275,8 @@ static void char_hub_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_hub;
-    cc->chr_open = qemu_chr_open_hub;
+    cc->chr_parse = hub_chr_parse;
+    cc->chr_open = hub_chr_open;
     cc->chr_write = hub_chr_write;
     cc->chr_add_watch = hub_chr_add_watch;
     /* We handle events from backends only */
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index c82c2da56d..f38d66b21f 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -361,10 +361,10 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
     mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 }
 
-static void qemu_chr_open_mux(Chardev *chr,
-                              ChardevBackend *backend,
-                              bool *be_opened,
-                              Error **errp)
+static void mux_chr_open(Chardev *chr,
+                         ChardevBackend *backend,
+                         bool *be_opened,
+                         Error **errp)
 {
     ChardevMux *mux = backend->u.mux.data;
     Chardev *drv;
@@ -384,8 +384,7 @@ static void qemu_chr_open_mux(Chardev *chr,
     qemu_chr_fe_init(&d->chr, drv, errp);
 }
 
-static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
-                               Error **errp)
+static void mux_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     const char *chardev = qemu_opt_get(opts, "chardev");
     ChardevMux *mux;
@@ -451,8 +450,8 @@ static void char_mux_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_mux;
-    cc->chr_open = qemu_chr_open_mux;
+    cc->chr_parse = mux_chr_parse;
+    cc->chr_open = mux_chr_open;
     cc->chr_write = mux_chr_write;
     cc->chr_accept_input = mux_chr_accept_input;
     cc->chr_add_watch = mux_chr_add_watch;
diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index a0839b784b..1be1ef4629 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -70,7 +70,7 @@ static int pp_hw_mode(ParallelChardev *s, uint16_t mode)
     return 1;
 }
 
-static int pp_ioctl(Chardev *chr, int cmd, void *arg)
+static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
     int fd = drv->fd;
@@ -157,7 +157,7 @@ static int pp_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void qemu_chr_open_pp_fd(Chardev *chr,
+static void parallel_chr_open_fd(Chardev *chr,
                                 int fd,
                                 bool *be_opened,
                                 Error **errp)
@@ -185,7 +185,7 @@ typedef struct {
 #define PARALLEL_CHARDEV(obj)                                   \
     OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL)
 
-static int pp_ioctl(Chardev *chr, int cmd, void *arg)
+static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
     uint8_t b;
@@ -227,7 +227,7 @@ static int pp_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void qemu_chr_open_pp_fd(Chardev *chr,
+static void parallel_chr_open_fd(Chardev *chr,
                                 int fd,
                                 bool *be_opened,
                                 Error **errp)
@@ -239,10 +239,10 @@ static void qemu_chr_open_pp_fd(Chardev *chr,
 #endif
 
 #ifdef HAVE_CHARDEV_PARALLEL
-static void qmp_chardev_open_parallel(Chardev *chr,
-                                      ChardevBackend *backend,
-                                      bool *be_opened,
-                                      Error **errp)
+static void parallel_chr_open(Chardev *chr,
+                              ChardevBackend *backend,
+                              bool *be_opened,
+                              Error **errp)
 {
     ChardevHostdev *parallel = backend->u.parallel.data;
     int fd;
@@ -251,11 +251,11 @@ static void qmp_chardev_open_parallel(Chardev *chr,
     if (fd < 0) {
         return;
     }
-    qemu_chr_open_pp_fd(chr, fd, be_opened, errp);
+    parallel_chr_open_fd(chr, fd, be_opened, errp);
 }
 
-static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
-                                    Error **errp)
+static void parallel_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                               Error **errp)
 {
     const char *device = qemu_opt_get(opts, "path");
     ChardevHostdev *parallel;
@@ -274,9 +274,9 @@ static void char_parallel_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_parallel;
-    cc->chr_open = qmp_chardev_open_parallel;
-    cc->chr_ioctl = pp_ioctl;
+    cc->chr_parse = parallel_chr_parse;
+    cc->chr_open = parallel_chr_open;
+    cc->chr_ioctl = parallel_chr_ioctl;
 }
 
 static void char_parallel_finalize(Object *obj)
diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c
index a2cd322efe..e84492d42b 100644
--- a/chardev/char-pipe.c
+++ b/chardev/char-pipe.c
@@ -103,10 +103,10 @@ static int win_chr_pipe_init(Chardev *chr, const char *filename,
     return -1;
 }
 
-static void qemu_chr_open_pipe(Chardev *chr,
-                               ChardevBackend *backend,
-                               bool *be_opened,
-                               Error **errp)
+static void pipe_chr_open(Chardev *chr,
+                          ChardevBackend *backend,
+                          bool *be_opened,
+                          Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     const char *filename = opts->device;
@@ -118,10 +118,10 @@ static void qemu_chr_open_pipe(Chardev *chr,
 
 #else
 
-static void qemu_chr_open_pipe(Chardev *chr,
-                               ChardevBackend *backend,
-                               bool *be_opened,
-                               Error **errp)
+static void pipe_chr_open(Chardev *chr,
+                          ChardevBackend *backend,
+                          bool *be_opened,
+                          Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     int fd_in, fd_out;
@@ -162,8 +162,8 @@ static void qemu_chr_open_pipe(Chardev *chr,
 
 #endif /* !_WIN32 */
 
-static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
-                                Error **errp)
+static void pipe_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                           Error **errp)
 {
     const char *device = qemu_opt_get(opts, "path");
     ChardevHostdev *dev;
@@ -182,8 +182,8 @@ static void char_pipe_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_pipe;
-    cc->chr_open = qemu_chr_open_pipe;
+    cc->chr_parse = pipe_chr_parse;
+    cc->chr_open = pipe_chr_open;
 }
 
 static const TypeInfo char_pipe_type_info = {
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 1a15082b02..909ab01f5f 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -105,7 +105,7 @@ static void pty_chr_update_read_handler(Chardev *chr)
     }
 }
 
-static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static int pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
 {
     PtyChardev *s = PTY_CHARDEV(chr);
     GPollFD pfd;
@@ -331,10 +331,10 @@ static int qemu_openpty_raw(int *aslave, char *pty_name)
     return amaster;
 }
 
-static void char_pty_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void pty_chr_open(Chardev *chr,
+                         ChardevBackend *backend,
+                         bool *be_opened,
+                         Error **errp)
 {
     PtyChardev *s;
     int master_fd, slave_fd;
@@ -378,8 +378,7 @@ static void char_pty_open(Chardev *chr,
     }
 }
 
-static void char_pty_parse(QemuOpts *opts, ChardevBackend *backend,
-                           Error **errp)
+static void pty_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     const char *path = qemu_opt_get(opts, "path");
     ChardevPty *pty;
@@ -394,9 +393,9 @@ static void char_pty_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = char_pty_parse;
-    cc->chr_open = char_pty_open;
-    cc->chr_write = char_pty_chr_write;
+    cc->chr_parse = pty_chr_parse;
+    cc->chr_open = pty_chr_open;
+    cc->chr_write = pty_chr_write;
     cc->chr_update_read_handler = pty_chr_update_read_handler;
     cc->chr_add_watch = pty_chr_add_watch;
 }
diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 6d5ba667bb..19652fe2b3 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -92,10 +92,10 @@ static void char_ringbuf_finalize(Object *obj)
     g_free(d->cbuf);
 }
 
-static void qemu_chr_open_ringbuf(Chardev *chr,
-                                  ChardevBackend *backend,
-                                  bool *be_opened,
-                                  Error **errp)
+static void ringbuf_chr_open(Chardev *chr,
+                             ChardevBackend *backend,
+                             bool *be_opened,
+                             Error **errp)
 {
     ChardevRingbuf *opts = backend->u.ringbuf.data;
     RingBufChardev *d = RINGBUF_CHARDEV(chr);
@@ -206,8 +206,8 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
     return data;
 }
 
-static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
-                                   Error **errp)
+static void ringbuf_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                              Error **errp)
 {
     int val;
     ChardevRingbuf *ringbuf;
@@ -227,8 +227,8 @@ static void char_ringbuf_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_ringbuf;
-    cc->chr_open = qemu_chr_open_ringbuf;
+    cc->chr_parse = ringbuf_chr_parse;
+    cc->chr_open = ringbuf_chr_open;
     cc->chr_write = ringbuf_chr_write;
 }
 
diff --git a/chardev/char-serial.c b/chardev/char-serial.c
index 97ed7adf73..54c2b3935c 100644
--- a/chardev/char-serial.c
+++ b/chardev/char-serial.c
@@ -41,10 +41,10 @@
 
 #ifdef _WIN32
 
-static void qmp_chardev_open_serial(Chardev *chr,
-                                    ChardevBackend *backend,
-                                    bool *be_opened,
-                                    Error **errp)
+static void serial_chr_open(Chardev *chr,
+                            ChardevBackend *backend,
+                            bool *be_opened,
+                            Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
 
@@ -176,7 +176,7 @@ static void tty_serial_init(int fd, int speed,
     tcsetattr(fd, TCSANOW, &tty);
 }
 
-static int tty_serial_ioctl(Chardev *chr, int cmd, void *arg)
+static int serial_chr_ioctl(Chardev *chr, int cmd, void *arg)
 {
     FDChardev *s = FD_CHARDEV(chr);
     QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in);
@@ -258,10 +258,10 @@ static int tty_serial_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void qmp_chardev_open_serial(Chardev *chr,
-                                    ChardevBackend *backend,
-                                    bool *be_opened,
-                                    Error **errp)
+static void serial_chr_open(Chardev *chr,
+                            ChardevBackend *backend,
+                            bool *be_opened,
+                            Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
     int fd;
@@ -285,8 +285,8 @@ static void qmp_chardev_open_serial(Chardev *chr,
 #endif /* __linux__ || __sun__ */
 
 #ifdef HAVE_CHARDEV_SERIAL
-static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
-                                  Error **errp)
+static void serial_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                             Error **errp)
 {
     const char *device = qemu_opt_get(opts, "path");
     ChardevHostdev *serial;
@@ -305,10 +305,10 @@ static void char_serial_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_serial;
-    cc->chr_open = qmp_chardev_open_serial;
+    cc->chr_parse = serial_chr_parse;
+    cc->chr_open = serial_chr_open;
 #ifndef _WIN32
-    cc->chr_ioctl = tty_serial_ioctl;
+    cc->chr_ioctl = serial_chr_ioctl;
 #endif
 }
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 12916af7ff..329cd9f0a8 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -222,7 +222,7 @@ static void tcp_chr_process_IAC_bytes(Chardev *chr,
     *size = j;
 }
 
-static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
+static int tcp_chr_get_msgfds(Chardev *chr, int *fds, int num)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
 
@@ -248,7 +248,7 @@ static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
     return to_copy;
 }
 
-static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
+static int tcp_chr_set_msgfds(Chardev *chr, int *fds, int num)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
 
@@ -367,7 +367,7 @@ static void tcp_chr_free_connection(Chardev *chr)
 
     remove_hup_source(s);
 
-    tcp_set_msgfds(chr, NULL, 0);
+    tcp_chr_set_msgfds(chr, NULL, 0);
     remove_fd_in_watch(chr);
     if (s->registered_yank &&
         (s->state == TCP_CHARDEV_STATE_CONNECTING
@@ -1365,10 +1365,10 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
 }
 
 
-static void qmp_chardev_open_socket(Chardev *chr,
-                                    ChardevBackend *backend,
-                                    bool *be_opened,
-                                    Error **errp)
+static void tcp_chr_open(Chardev *chr,
+                         ChardevBackend *backend,
+                         bool *be_opened,
+                         Error **errp)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
     ChardevSocket *sock = backend->u.socket.data;
@@ -1456,8 +1456,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
     }
 }
 
-static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
-                                  Error **errp)
+static void tcp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     const char *path = qemu_opt_get(opts, "path");
     const char *host = qemu_opt_get(opts, "host");
@@ -1576,14 +1575,14 @@ static void char_socket_class_init(ObjectClass *oc, const void *data)
 
     cc->supports_yank = true;
 
-    cc->chr_parse = qemu_chr_parse_socket;
-    cc->chr_open = qmp_chardev_open_socket;
+    cc->chr_parse = tcp_chr_parse;
+    cc->chr_open = tcp_chr_open;
     cc->chr_wait_connected = tcp_chr_wait_connected;
     cc->chr_write = tcp_chr_write;
     cc->chr_sync_read = tcp_chr_sync_read;
     cc->chr_disconnect = tcp_chr_disconnect;
-    cc->chr_get_msgfds = tcp_get_msgfds;
-    cc->chr_set_msgfds = tcp_set_msgfds;
+    cc->chr_get_msgfds = tcp_chr_get_msgfds;
+    cc->chr_set_msgfds = tcp_chr_set_msgfds;
     cc->chr_add_client = tcp_chr_add_client;
     cc->chr_add_watch = tcp_chr_add_watch;
     cc->chr_update_read_handler = tcp_chr_update_read_handler;
diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
index b7e9af1388..f0920a23fa 100644
--- a/chardev/char-stdio.c
+++ b/chardev/char-stdio.c
@@ -56,7 +56,7 @@ static void term_exit(void)
     }
 }
 
-static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo)
+static void stdio_chr_set_echo(Chardev *chr, bool echo)
 {
     struct termios tty;
 
@@ -82,13 +82,13 @@ static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo)
 static void term_stdio_handler(int sig)
 {
     /* restore echo after resume from suspend. */
-    qemu_chr_set_echo_stdio(NULL, stdio_echo_state);
+    stdio_chr_set_echo(NULL, stdio_echo_state);
 }
 
-static void qemu_chr_open_stdio(Chardev *chr,
-                                ChardevBackend *backend,
-                                bool *be_opened,
-                                Error **errp)
+static void stdio_chr_open(Chardev *chr,
+                           ChardevBackend *backend,
+                           bool *be_opened,
+                           Error **errp)
 {
     ChardevStdio *opts = backend->u.stdio.data;
     struct sigaction act;
@@ -122,11 +122,11 @@ static void qemu_chr_open_stdio(Chardev *chr,
     sigaction(SIGCONT, &act, NULL);
 
     stdio_allow_signal = !opts->has_signal || opts->signal;
-    qemu_chr_set_echo_stdio(chr, false);
+    stdio_chr_set_echo(chr, false);
 }
 #endif
 
-static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
+static void stdio_chr_parse(QemuOpts *opts, ChardevBackend *backend,
                                  Error **errp)
 {
     ChardevStdio *stdio;
@@ -142,10 +142,10 @@ static void char_stdio_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_stdio;
+    cc->chr_parse = stdio_chr_parse;
 #ifndef _WIN32
-    cc->chr_open = qemu_chr_open_stdio;
-    cc->chr_set_echo = qemu_chr_set_echo_stdio;
+    cc->chr_open = stdio_chr_open;
+    cc->chr_set_echo = stdio_chr_set_echo;
 #endif
 }
 
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index a6f496ac7b..099f76b8c2 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -131,8 +131,7 @@ static void char_udp_finalize(Object *obj)
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }
 
-static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
-                               Error **errp)
+static void udp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     const char *host = qemu_opt_get(opts, "host");
     const char *port = qemu_opt_get(opts, "port");
@@ -189,10 +188,10 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
     }
 }
 
-static void qmp_chardev_open_udp(Chardev *chr,
-                                 ChardevBackend *backend,
-                                 bool *be_opened,
-                                 Error **errp)
+static void upd_chr_open(Chardev *chr,
+                         ChardevBackend *backend,
+                         bool *be_opened,
+                         Error **errp)
 {
     ChardevUdp *udp = backend->u.udp.data;
     SocketAddress *local_addr = socket_address_flatten(udp->local);
@@ -223,8 +222,8 @@ static void char_udp_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_udp;
-    cc->chr_open = qmp_chardev_open_udp;
+    cc->chr_parse = udp_chr_parse;
+    cc->chr_open = upd_chr_open;
     cc->chr_write = udp_chr_write;
     cc->chr_update_read_handler = udp_chr_update_read_handler;
 }
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index 26e67aef1c..866f3a2039 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -128,7 +128,7 @@ static void win_stdio_thread_wait_func(void *opaque)
     SetEvent(stdio->hInputDoneEvent);
 }
 
-static void qemu_chr_set_echo_win_stdio(Chardev *chr, bool echo)
+static void win_stiod_chr_set_echo(Chardev *chr, bool echo)
 {
     WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr);
     DWORD              dwMode = 0;
@@ -142,10 +142,10 @@ static void qemu_chr_set_echo_win_stdio(Chardev *chr, bool echo)
     }
 }
 
-static void qemu_chr_open_stdio(Chardev *chr,
-                                ChardevBackend *backend,
-                                bool *be_opened,
-                                Error **errp)
+static void win_stdio_chr_open(Chardev *chr,
+                               ChardevBackend *backend,
+                               bool *be_opened,
+                               Error **errp)
 {
     ChardevStdio *opts = backend->u.stdio.data;
     bool stdio_allow_signal = !opts->has_signal || opts->signal;
@@ -206,7 +206,7 @@ static void qemu_chr_open_stdio(Chardev *chr,
 
     SetConsoleMode(stdio->hStdIn, dwMode);
 
-    qemu_chr_set_echo_win_stdio(chr, false);
+    win_stiod_chr_set_echo(chr, false);
 
     return;
 
@@ -237,7 +237,7 @@ static void char_win_stdio_finalize(Object *obj)
     }
 }
 
-static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len)
+static int win_stdio_chr_write(Chardev *chr, const uint8_t *buf, int len)
 {
     HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
     DWORD   dwSize;
@@ -260,9 +260,9 @@ static void char_win_stdio_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_open = qemu_chr_open_stdio;
-    cc->chr_write = win_stdio_write;
-    cc->chr_set_echo = qemu_chr_set_echo_win_stdio;
+    cc->chr_open = win_stdio_chr_open;
+    cc->chr_write = win_stdio_chr_write;
+    cc->chr_set_echo = win_stiod_chr_set_echo;
 }
 
 static const TypeInfo char_win_stdio_type_info = {
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index 8405016489..d07cd998cb 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -178,7 +178,7 @@ static const QemuInputHandler msmouse_handler = {
     .sync  = msmouse_input_sync,
 };
 
-static int msmouse_ioctl(Chardev *chr, int cmd, void *arg)
+static int msmouse_chr_ioctl(Chardev *chr, int cmd, void *arg)
 {
     MouseChardev *mouse = MOUSE_CHARDEV(chr);
     int c, i, j;
@@ -274,7 +274,7 @@ static void char_msmouse_class_init(ObjectClass *oc, const void *data)
     cc->chr_open = msmouse_chr_open;
     cc->chr_write = msmouse_chr_write;
     cc->chr_accept_input = msmouse_chr_accept_input;
-    cc->chr_ioctl = msmouse_ioctl;
+    cc->chr_ioctl = msmouse_chr_ioctl;
 }
 
 static const TypeInfo char_msmouse_type_info = {
diff --git a/chardev/spice.c b/chardev/spice.c
index d55b3693b6..800784da26 100644
--- a/chardev/spice.c
+++ b/chardev/spice.c
@@ -215,7 +215,7 @@ static void char_spice_finalize(Object *obj)
     g_free((char *)s->sin.portname);
 }
 
-static void spice_vmc_set_fe_open(struct Chardev *chr, int fe_open)
+static void spice_vmc_chr_set_fe_open(struct Chardev *chr, int fe_open)
 {
     SpiceChardev *s = SPICE_CHARDEV(chr);
     if (fe_open) {
@@ -225,7 +225,7 @@ static void spice_vmc_set_fe_open(struct Chardev *chr, int fe_open)
     }
 }
 
-static void spice_port_set_fe_open(struct Chardev *chr, int fe_open)
+static void spice_port_chr_set_fe_open(struct Chardev *chr, int fe_open)
 {
     SpiceChardev *s = SPICE_CHARDEV(chr);
 
@@ -251,10 +251,10 @@ static void chr_open(Chardev *chr, const char *subtype)
     s->sin.subtype = g_strdup(subtype);
 }
 
-static void qemu_chr_open_spice_vmc(Chardev *chr,
-                                    ChardevBackend *backend,
-                                    bool *be_opened,
-                                    Error **errp)
+static void spice_vmc_chr_open(Chardev *chr,
+                               ChardevBackend *backend,
+                               bool *be_opened,
+                               Error **errp)
 {
     ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
     const char *type = spicevmc->type;
@@ -287,10 +287,10 @@ static void qemu_chr_open_spice_vmc(Chardev *chr,
     chr_open(chr, type);
 }
 
-static void qemu_chr_open_spice_port(Chardev *chr,
-                                     ChardevBackend *backend,
-                                     bool *be_opened,
-                                     Error **errp)
+static void spice_port_chr_open(Chardev *chr,
+                                ChardevBackend *backend,
+                                bool *be_opened,
+                                Error **errp)
 {
     ChardevSpicePort *spiceport = backend->u.spiceport.data;
     const char *name = spiceport->fqdn;
@@ -315,8 +315,8 @@ static void qemu_chr_open_spice_port(Chardev *chr,
     vmc_register_interface(s);
 }
 
-static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend,
-                                     Error **errp)
+static void spice_vmc_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                                Error **errp)
 {
     const char *name = qemu_opt_get(opts, "name");
     ChardevSpiceChannel *spicevmc;
@@ -331,8 +331,8 @@ static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend,
     spicevmc->type = g_strdup(name);
 }
 
-static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
-                                      Error **errp)
+static void spice_port_chr_parse(QemuOpts *opts, ChardevBackend *backend,
+                                 Error **errp)
 {
     const char *name = qemu_opt_get(opts, "name");
     ChardevSpicePort *spiceport;
@@ -370,9 +370,9 @@ static void char_spicevmc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_spice_vmc;
-    cc->chr_open = qemu_chr_open_spice_vmc;
-    cc->chr_set_fe_open = spice_vmc_set_fe_open;
+    cc->chr_parse = spice_vmc_chr_parse;
+    cc->chr_open = spice_vmc_chr_open;
+    cc->chr_set_fe_open = spice_vmc_chr_set_fe_open;
 }
 
 static const TypeInfo char_spicevmc_type_info = {
@@ -386,9 +386,9 @@ static void char_spiceport_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_parse = qemu_chr_parse_spice_port;
-    cc->chr_open = qemu_chr_open_spice_port;
-    cc->chr_set_fe_open = spice_port_set_fe_open;
+    cc->chr_parse = spice_port_chr_parse;
+    cc->chr_open = spice_port_chr_open;
+    cc->chr_set_fe_open = spice_port_chr_set_fe_open;
 }
 
 static const TypeInfo char_spiceport_type_info = {
diff --git a/gdbstub/system.c b/gdbstub/system.c
index fe2afeb107..61b2b4b8da 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -225,7 +225,7 @@ static void gdb_sigterm_handler(int signal)
 }
 #endif
 
-static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
+static int gdb_chr_write(Chardev *chr, const uint8_t *buf, int len)
 {
     g_autoptr(GString) hex_buf = g_string_new("O");
     gdb_memtohex(hex_buf, buf, len);
@@ -233,7 +233,7 @@ static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
     return len;
 }
 
-static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
+static void gdb_chr_open(Chardev *chr, ChardevBackend *backend,
                              bool *be_opened, Error **errp)
 {
     *be_opened = false;
@@ -244,8 +244,8 @@ static void char_gdb_class_init(ObjectClass *oc, const void *data)
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
     cc->internal = true;
-    cc->chr_open = gdb_monitor_open;
-    cc->chr_write = gdb_monitor_write;
+    cc->chr_open = gdb_chr_open;
+    cc->chr_write = gdb_chr_write;
 }
 
 #define TYPE_CHARDEV_GDB "chardev-gdb"
diff --git a/scripts/codeconverter/codeconverter/test_regexps.py b/scripts/codeconverter/codeconverter/test_regexps.py
index d3a5cc3ad3..2b9f5b8011 100644
--- a/scripts/codeconverter/codeconverter/test_regexps.py
+++ b/scripts/codeconverter/codeconverter/test_regexps.py
@@ -57,7 +57,7 @@ def fullmatch(regexp, s):
 
     print(RE_TYPEINFO_START)
     assert re.search(RE_TYPEINFO_START, r'''
-    cc->chr_open = qmp_chardev_open_file;
+    cc->chr_open = file_chr_open;
 }
 
 static const TypeInfo char_file_type_info = {
diff --git a/ui/gtk.c b/ui/gtk.c
index 7aa97907ed..b5498a7ce3 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1963,7 +1963,7 @@ static void gd_vc_chr_set_echo(Chardev *chr, bool echo)
 
 static int nb_vcs;
 static Chardev *vcs[MAX_VCS];
-static void gd_vc_open(Chardev *chr,
+static void gd_vc_chr_open(Chardev *chr,
                        ChardevBackend *backend,
                        bool *be_opened,
                        Error **errp)
@@ -1985,7 +1985,7 @@ static void char_gd_vc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_open = gd_vc_open;
+    cc->chr_open = gd_vc_chr_open;
     cc->chr_write = gd_vc_chr_write;
     cc->chr_accept_input = gd_vc_chr_accept_input;
     cc->chr_set_echo = gd_vc_chr_set_echo;
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 1/8] chardev: ChardevClass: consistent naming for handlers Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-12-01 12:57   ` Marc-André Lureau
  2025-11-29 13:43 ` [PATCH 4/8] chardev: .chr_open(): add boolean return value Vladimir Sementsov-Ogievskiy
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: pbonzini, qemu-devel, vsementsov, d-tatianin, Samuel Thibault,
	Alex Bennée, Philippe Mathieu-Daudé

The logic around the parameter is rather tricky. Let's instead
explicitly send CHR_EVENT_OPENED in all bakends where needed.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/baum.c           |  7 +++----
 chardev/char-console.c   |  5 ++---
 chardev/char-file.c      |  7 +++----
 chardev/char-hub.c       | 11 +++++------
 chardev/char-mux.c       | 19 +++++++++++--------
 chardev/char-null.c      |  7 ++-----
 chardev/char-parallel.c  | 15 ++++-----------
 chardev/char-pipe.c      | 14 ++++++--------
 chardev/char-pty.c       |  6 +-----
 chardev/char-ringbuf.c   |  3 ++-
 chardev/char-serial.c    | 18 +++++++++---------
 chardev/char-socket.c    | 10 +++-------
 chardev/char-stdio.c     |  7 +++----
 chardev/char-udp.c       |  6 +-----
 chardev/char-win-stdio.c |  2 +-
 chardev/char.c           | 11 +++--------
 chardev/msmouse.c        |  4 ++--
 chardev/spice.c          | 13 ++++---------
 chardev/wctablet.c       |  5 ++---
 gdbstub/system.c         |  5 ++---
 include/chardev/char.h   |  3 +--
 ui/console-vc.c          |  7 ++-----
 ui/dbus-chardev.c        |  6 ++----
 ui/gtk.c                 |  9 +++------
 ui/spice-app.c           | 10 +++-------
 ui/vdagent.c             |  3 +--
 26 files changed, 81 insertions(+), 132 deletions(-)

diff --git a/chardev/baum.c b/chardev/baum.c
index 6b81c97d10..58b74dc98d 100644
--- a/chardev/baum.c
+++ b/chardev/baum.c
@@ -642,10 +642,7 @@ static void char_braille_finalize(Object *obj)
     }
 }
 
-static void baum_chr_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void baum_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     BaumChardev *baum = BAUM_CHARDEV(chr);
     brlapi_handle_t *handle;
@@ -670,6 +667,8 @@ static void baum_chr_open(Chardev *chr,
      * as an integer, but in practice it seems to work
      */
     qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void char_braille_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-console.c b/chardev/char-console.c
index f3ef1a7748..423f0f4cc4 100644
--- a/chardev/char-console.c
+++ b/chardev/char-console.c
@@ -26,12 +26,11 @@
 #include "chardev/char-win.h"
 #include "qemu/module.h"
 
-static void console_chr_open(Chardev *chr,
-                             ChardevBackend *backend,
-                             bool *be_opened,
+static void console_chr_open(Chardev *chr, ChardevBackend *backend,
                              Error **errp)
 {
     win_chr_set_file(chr, GetStdHandle(STD_OUTPUT_HANDLE), true);
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void char_console_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-file.c b/chardev/char-file.c
index 568600bb7c..34ef386abc 100644
--- a/chardev/char-file.c
+++ b/chardev/char-file.c
@@ -34,10 +34,7 @@
 #include "chardev/char-fd.h"
 #endif
 
-static void file_chr_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevFile *file = backend->u.file.data;
 #ifdef _WIN32
@@ -100,6 +97,8 @@ static void file_chr_open(Chardev *chr,
         return;
     }
 #endif
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void file_chr_parse(QemuOpts *opts, ChardevBackend *backend,
diff --git a/chardev/char-hub.c b/chardev/char-hub.c
index 11556dfa72..aa6058c2f6 100644
--- a/chardev/char-hub.c
+++ b/chardev/char-hub.c
@@ -203,10 +203,7 @@ static void hub_chr_update_read_handlers(Chardev *chr)
     }
 }
 
-static void hub_chr_open(Chardev *chr,
-                         ChardevBackend *backend,
-                         bool *be_opened,
-                         Error **errp)
+static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHub *hub = backend->u.hub.data;
     HubChardev *d = HUB_CHARDEV(chr);
@@ -241,8 +238,10 @@ static void hub_chr_open(Chardev *chr,
         list = list->next;
     }
 
-    /* Closed until an explicit event from backend */
-    *be_opened = false;
+    /*
+     * Closed until an explicit event from backend, so we don't
+     * send CHR_EVENT_OPENED now.
+     */
 }
 
 static void hub_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index f38d66b21f..7210df431f 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -361,10 +361,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
     mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 }
 
-static void mux_chr_open(Chardev *chr,
-                         ChardevBackend *backend,
-                         bool *be_opened,
-                         Error **errp)
+static void mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevMux *mux = backend->u.mux.data;
     Chardev *drv;
@@ -377,11 +374,17 @@ static void mux_chr_open(Chardev *chr,
     }
 
     d->focus = -1;
-    /* only default to opened state if we've realized the initial
-     * set of muxes
+    if (!qemu_chr_fe_init(&d->chr, drv, errp)) {
+        return;
+    }
+
+    /*
+     * Only move to opened state if we've realized
+     * the initial set of muxes:
      */
-    *be_opened = muxes_opened;
-    qemu_chr_fe_init(&d->chr, drv, errp);
+    if (muxes_opened) {
+        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    }
 }
 
 static void mux_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-null.c b/chardev/char-null.c
index 674603b380..900b5febb6 100644
--- a/chardev/char-null.c
+++ b/chardev/char-null.c
@@ -26,12 +26,9 @@
 #include "chardev/char.h"
 #include "qemu/module.h"
 
-static void null_chr_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void null_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
-    *be_opened = false;
+    /* do not send CHR_EVENT_OPENED */
 }
 
 static void char_null_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index 1be1ef4629..359efa3c9c 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -157,10 +157,7 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void parallel_chr_open_fd(Chardev *chr,
-                                int fd,
-                                bool *be_opened,
-                                Error **errp)
+static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
 
@@ -172,6 +169,7 @@ static void parallel_chr_open_fd(Chardev *chr,
     }
 
     drv->mode = IEEE1284_MODE_COMPAT;
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 #endif /* __linux__ */
 
@@ -227,21 +225,16 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void parallel_chr_open_fd(Chardev *chr,
-                                int fd,
-                                bool *be_opened,
-                                Error **errp)
+static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
     drv->fd = fd;
-    *be_opened = false;
 }
 #endif
 
 #ifdef HAVE_CHARDEV_PARALLEL
 static void parallel_chr_open(Chardev *chr,
                               ChardevBackend *backend,
-                              bool *be_opened,
                               Error **errp)
 {
     ChardevHostdev *parallel = backend->u.parallel.data;
@@ -251,7 +244,7 @@ static void parallel_chr_open(Chardev *chr,
     if (fd < 0) {
         return;
     }
-    parallel_chr_open_fd(chr, fd, be_opened, errp);
+    parallel_chr_open_fd(chr, fd, errp);
 }
 
 static void parallel_chr_parse(QemuOpts *opts, ChardevBackend *backend,
diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c
index e84492d42b..2f26372dfc 100644
--- a/chardev/char-pipe.c
+++ b/chardev/char-pipe.c
@@ -103,10 +103,7 @@ static int win_chr_pipe_init(Chardev *chr, const char *filename,
     return -1;
 }
 
-static void pipe_chr_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     const char *filename = opts->device;
@@ -114,14 +111,13 @@ static void pipe_chr_open(Chardev *chr,
     if (win_chr_pipe_init(chr, filename, errp) < 0) {
         return;
     }
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 #else
 
-static void pipe_chr_open(Chardev *chr,
-                          ChardevBackend *backend,
-                          bool *be_opened,
-                          Error **errp)
+static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     int fd_in, fd_out;
@@ -158,6 +154,8 @@ static void pipe_chr_open(Chardev *chr,
         }
         return;
     }
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 #endif /* !_WIN32 */
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 909ab01f5f..d4d69a29a9 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -331,10 +331,7 @@ static int qemu_openpty_raw(int *aslave, char *pty_name)
     return amaster;
 }
 
-static void pty_chr_open(Chardev *chr,
-                         ChardevBackend *backend,
-                         bool *be_opened,
-                         Error **errp)
+static void pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     PtyChardev *s;
     int master_fd, slave_fd;
@@ -364,7 +361,6 @@ static void pty_chr_open(Chardev *chr,
     qio_channel_set_name(s->ioc, name);
     g_free(name);
     s->timer_src = NULL;
-    *be_opened = false;
 
     /* create symbolic link */
     if (path) {
diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 19652fe2b3..30b17a96d3 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -94,7 +94,6 @@ static void char_ringbuf_finalize(Object *obj)
 
 static void ringbuf_chr_open(Chardev *chr,
                              ChardevBackend *backend,
-                             bool *be_opened,
                              Error **errp)
 {
     ChardevRingbuf *opts = backend->u.ringbuf.data;
@@ -111,6 +110,8 @@ static void ringbuf_chr_open(Chardev *chr,
     d->prod = 0;
     d->cons = 0;
     d->cbuf = g_malloc0(d->size);
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 void qmp_ringbuf_write(const char *device, const char *data,
diff --git a/chardev/char-serial.c b/chardev/char-serial.c
index 54c2b3935c..9995f18425 100644
--- a/chardev/char-serial.c
+++ b/chardev/char-serial.c
@@ -41,14 +41,15 @@
 
 #ifdef _WIN32
 
-static void serial_chr_open(Chardev *chr,
-                            ChardevBackend *backend,
-                            bool *be_opened,
-                            Error **errp)
+static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
+    int ret = win_chr_serial_init(chr, serial->device, errp);
+    if (ret < 0) {
+        return;
+    }
 
-    win_chr_serial_init(chr, serial->device, errp);
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 #elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__)      \
@@ -258,10 +259,7 @@ static int serial_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void serial_chr_open(Chardev *chr,
-                            ChardevBackend *backend,
-                            bool *be_opened,
-                            Error **errp)
+static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
     int fd;
@@ -281,6 +279,8 @@ static void serial_chr_open(Chardev *chr,
         close(fd);
         return;
     }
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 #endif /* __linux__ || __sun__ */
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 329cd9f0a8..3f57ef4016 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1365,10 +1365,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
 }
 
 
-static void tcp_chr_open(Chardev *chr,
-                         ChardevBackend *backend,
-                         bool *be_opened,
-                         Error **errp)
+static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
     ChardevSocket *sock = backend->u.socket.data;
@@ -1439,9 +1436,6 @@ static void tcp_chr_open(Chardev *chr,
     }
     s->registered_yank = true;
 
-    /* be isn't opened until we get a connection */
-    *be_opened = false;
-
     update_disconnected_filename(s);
 
     if (s->is_listen) {
@@ -1454,6 +1448,8 @@ static void tcp_chr_open(Chardev *chr,
             return;
         }
     }
+
+    /* be isn't opened until we get a connection */
 }
 
 static void tcp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
index f0920a23fa..534f6ed565 100644
--- a/chardev/char-stdio.c
+++ b/chardev/char-stdio.c
@@ -85,10 +85,7 @@ static void term_stdio_handler(int sig)
     stdio_chr_set_echo(NULL, stdio_echo_state);
 }
 
-static void stdio_chr_open(Chardev *chr,
-                           ChardevBackend *backend,
-                           bool *be_opened,
-                           Error **errp)
+static void stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevStdio *opts = backend->u.stdio.data;
     struct sigaction act;
@@ -123,6 +120,8 @@ static void stdio_chr_open(Chardev *chr,
 
     stdio_allow_signal = !opts->has_signal || opts->signal;
     stdio_chr_set_echo(chr, false);
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 #endif
 
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 099f76b8c2..b835a967e1 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -188,10 +188,7 @@ static void udp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
     }
 }
 
-static void upd_chr_open(Chardev *chr,
-                         ChardevBackend *backend,
-                         bool *be_opened,
-                         Error **errp)
+static void upd_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevUdp *udp = backend->u.udp.data;
     SocketAddress *local_addr = socket_address_flatten(udp->local);
@@ -215,7 +212,6 @@ static void upd_chr_open(Chardev *chr,
 
     s->ioc = QIO_CHANNEL(sioc);
     /* be isn't opened until we get a connection */
-    *be_opened = false;
 }
 
 static void char_udp_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index 866f3a2039..0535960ff1 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -144,7 +144,6 @@ static void win_stiod_chr_set_echo(Chardev *chr, bool echo)
 
 static void win_stdio_chr_open(Chardev *chr,
                                ChardevBackend *backend,
-                               bool *be_opened,
                                Error **errp)
 {
     ChardevStdio *opts = backend->u.stdio.data;
@@ -208,6 +207,7 @@ static void win_stdio_chr_open(Chardev *chr,
 
     win_stiod_chr_set_echo(chr, false);
 
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
     return;
 
 err3:
diff --git a/chardev/char.c b/chardev/char.c
index df37d1df16..44bfed3627 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -246,8 +246,7 @@ int qemu_chr_add_client(Chardev *s, int fd)
         CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
 }
 
-static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
-                           bool *be_opened, Error **errp)
+static void qemu_char_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevClass *cc = CHARDEV_GET_CLASS(chr);
     /* Any ChardevCommon member would work */
@@ -268,7 +267,7 @@ static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
     }
 
     if (cc->chr_open) {
-        cc->chr_open(chr, backend, be_opened, errp);
+        cc->chr_open(chr, backend, errp);
     }
 }
 
@@ -1009,7 +1008,6 @@ static Chardev *chardev_new(const char *id, const char *typename,
     Object *obj;
     Chardev *chr = NULL;
     Error *local_err = NULL;
-    bool be_opened = true;
 
     assert(g_str_has_prefix(typename, "chardev-"));
     assert(id);
@@ -1020,7 +1018,7 @@ static Chardev *chardev_new(const char *id, const char *typename,
     chr->label = g_strdup(id);
     chr->gcontext = gcontext;
 
-    qemu_char_open(chr, backend, &be_opened, &local_err);
+    qemu_char_open(chr, backend, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         object_unref(obj);
@@ -1030,9 +1028,6 @@ static Chardev *chardev_new(const char *id, const char *typename,
     if (!chr->filename) {
         chr->filename = g_strdup(typename + 8);
     }
-    if (be_opened) {
-        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
-    }
 
     return chr;
 }
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index d07cd998cb..9dc04e3b3e 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -255,16 +255,16 @@ static void char_msmouse_finalize(Object *obj)
 
 static void msmouse_chr_open(Chardev *chr,
                              ChardevBackend *backend,
-                             bool *be_opened,
                              Error **errp)
 {
     MouseChardev *mouse = MOUSE_CHARDEV(chr);
 
-    *be_opened = false;
     mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
                                             &msmouse_handler);
     mouse->tiocm = 0;
     fifo8_create(&mouse->outbuf, MSMOUSE_BUF_SZ);
+
+    /* Never send CHR_EVENT_OPENED */
 }
 
 static void char_msmouse_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/spice.c b/chardev/spice.c
index 800784da26..612f358885 100644
--- a/chardev/spice.c
+++ b/chardev/spice.c
@@ -251,9 +251,7 @@ static void chr_open(Chardev *chr, const char *subtype)
     s->sin.subtype = g_strdup(subtype);
 }
 
-static void spice_vmc_chr_open(Chardev *chr,
-                               ChardevBackend *backend,
-                               bool *be_opened,
+static void spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
                                Error **errp)
 {
     ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
@@ -277,19 +275,17 @@ static void spice_vmc_chr_open(Chardev *chr,
         return;
     }
 
-    *be_opened = false;
 #if SPICE_SERVER_VERSION < 0x000e02
     /* Spice < 0.14.2 doesn't explicitly open smartcard chardev */
     if (strcmp(type, "smartcard") == 0) {
-        *be_opened = true;
+        chr_open(chr, type);
+        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
     }
 #endif
     chr_open(chr, type);
 }
 
-static void spice_port_chr_open(Chardev *chr,
-                                ChardevBackend *backend,
-                                bool *be_opened,
+static void spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
                                 Error **errp)
 {
     ChardevSpicePort *spiceport = backend->u.spiceport.data;
@@ -308,7 +304,6 @@ static void spice_port_chr_open(Chardev *chr,
 
     chr_open(chr, "port");
 
-    *be_opened = false;
     s = SPICE_CHARDEV(chr);
     s->sin.portname = g_strdup(name);
 
diff --git a/chardev/wctablet.c b/chardev/wctablet.c
index 8285a56e7b..65b2ceb58c 100644
--- a/chardev/wctablet.c
+++ b/chardev/wctablet.c
@@ -326,13 +326,10 @@ static void wctablet_chr_finalize(Object *obj)
 
 static void wctablet_chr_open(Chardev *chr,
                               ChardevBackend *backend,
-                              bool *be_opened,
                               Error **errp)
 {
     TabletChardev *tablet = WCTABLET_CHARDEV(chr);
 
-    *be_opened = true;
-
     /* init state machine */
     memcpy(tablet->outbuf, WC_FULL_CONFIG_STRING, WC_FULL_CONFIG_STRING_LENGTH);
     tablet->outlen = WC_FULL_CONFIG_STRING_LENGTH;
@@ -340,6 +337,8 @@ static void wctablet_chr_open(Chardev *chr,
 
     tablet->hs = qemu_input_handler_register((DeviceState *)tablet,
                                              &wctablet_handler);
+
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void wctablet_chr_class_init(ObjectClass *oc, const void *data)
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 61b2b4b8da..49da1f73cc 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -233,10 +233,9 @@ static int gdb_chr_write(Chardev *chr, const uint8_t *buf, int len)
     return len;
 }
 
-static void gdb_chr_open(Chardev *chr, ChardevBackend *backend,
-                             bool *be_opened, Error **errp)
+static void gdb_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
-    *be_opened = false;
+    /* Never send CHR_EVENT_OPENED */
 }
 
 static void char_gdb_class_init(ObjectClass *oc, const void *data)
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 2baf2a8a1a..47c75c3582 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -260,8 +260,7 @@ struct ChardevClass {
     void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 
     /* called after construction, open/starts the backend */
-    void (*chr_open)(Chardev *chr, ChardevBackend *backend,
-                 bool *be_opened, Error **errp);
+    void (*chr_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
 
     /* write buf to the backend */
     int (*chr_write)(Chardev *s, const uint8_t *buf, int len);
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 931068d43a..4c8ea4c148 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -1093,10 +1093,7 @@ void qemu_text_console_update_size(QemuTextConsole *c)
     dpy_text_resize(QEMU_CONSOLE(c), c->width, c->height);
 }
 
-static void vc_chr_open(Chardev *chr,
-                        ChardevBackend *backend,
-                        bool *be_opened,
-                        Error **errp)
+static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevVC *vc = backend->u.vc.data;
     VCChardev *drv = VC_CHARDEV(chr);
@@ -1144,7 +1141,7 @@ static void vc_chr_open(Chardev *chr,
         drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
     }
 
-    *be_opened = true;
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c
index f6c426e220..3e471f84cd 100644
--- a/ui/dbus-chardev.c
+++ b/ui/dbus-chardev.c
@@ -176,9 +176,7 @@ dbus_chr_send_break(
     return DBUS_METHOD_INVOCATION_HANDLED;
 }
 
-static void
-dbus_chr_open(Chardev *chr, ChardevBackend *backend,
-              bool *be_opened, Error **errp)
+static void dbus_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ERRP_GUARD();
 
@@ -211,7 +209,7 @@ dbus_chr_open(Chardev *chr, ChardevBackend *backend,
         return;
     }
     CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_open(
-        chr, be, be_opened, errp);
+        chr, be, errp);
 }
 
 static void
diff --git a/ui/gtk.c b/ui/gtk.c
index b5498a7ce3..3eeb5baa11 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1963,10 +1963,7 @@ static void gd_vc_chr_set_echo(Chardev *chr, bool echo)
 
 static int nb_vcs;
 static Chardev *vcs[MAX_VCS];
-static void gd_vc_chr_open(Chardev *chr,
-                       ChardevBackend *backend,
-                       bool *be_opened,
-                       Error **errp)
+static void gd_vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     if (nb_vcs == MAX_VCS) {
         error_setg(errp, "Maximum number of consoles reached");
@@ -1975,10 +1972,10 @@ static void gd_vc_chr_open(Chardev *chr,
 
     vcs[nb_vcs++] = chr;
 
-    /* console/chardev init sometimes completes elsewhere in a 2nd
+    /*
+     * console/chardev init sometimes completes elsewhere in a 2nd
      * stage, so defer OPENED events until they are fully initialized
      */
-    *be_opened = false;
 }
 
 static void char_gd_vc_class_init(ObjectClass *oc, const void *data)
diff --git a/ui/spice-app.c b/ui/spice-app.c
index ea0b62a22b..7ac9ae4e78 100644
--- a/ui/spice-app.c
+++ b/ui/spice-app.c
@@ -49,8 +49,7 @@ struct VCChardev {
 
 struct VCChardevClass {
     ChardevClass parent;
-    void (*parent_open)(Chardev *chr, ChardevBackend *backend,
-                        bool *be_opened, Error **errp);
+    void (*parent_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
 };
 
 #define TYPE_CHARDEV_VC "chardev-vc"
@@ -67,10 +66,7 @@ chr_spice_backend_new(void)
     return be;
 }
 
-static void vc_chr_open(Chardev *chr,
-                        ChardevBackend *backend,
-                        bool *be_opened,
-                        Error **errp)
+static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     VCChardevClass *vc = CHARDEV_VC_GET_CLASS(chr);
     ChardevBackend *be;
@@ -87,7 +83,7 @@ static void vc_chr_open(Chardev *chr,
     be = chr_spice_backend_new();
     be->u.spiceport.data->fqdn = fqdn ?
         g_strdup(fqdn) : g_strdup_printf("org.qemu.console.%s", chr->label);
-    vc->parent_open(chr, be, be_opened, errp);
+    vc->parent_open(chr, be, errp);
     qapi_free_ChardevBackend(be);
 }
 
diff --git a/ui/vdagent.c b/ui/vdagent.c
index 9972a9c476..3becc6c076 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -662,7 +662,6 @@ static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
 
 static void vdagent_chr_open(Chardev *chr,
                              ChardevBackend *backend,
-                             bool *be_opened,
                              Error **errp)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
@@ -692,7 +691,7 @@ static void vdagent_chr_open(Chardev *chr,
                                                    &vdagent_mouse_handler);
     }
 
-    *be_opened = true;
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void vdagent_clipboard_peer_register(VDAgentChardev *vd)
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/8] chardev: .chr_open(): add boolean return value
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (2 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 14:08   ` Philippe Mathieu-Daudé
  2025-11-29 13:43 ` [PATCH 5/8] chardev/char-pty: store pty_name into PtyChardev state Vladimir Sementsov-Ogievskiy
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: pbonzini, qemu-devel, vsementsov, d-tatianin, Samuel Thibault,
	Alex Bennée, Philippe Mathieu-Daudé

Add boolean return value to follow common recommendations for functions
with errrp in include/qapi/error.h

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/baum.c           |  5 +++--
 chardev/char-console.c   |  1 +
 chardev/char-file.c      | 13 +++++++------
 chardev/char-hub.c       | 11 ++++++-----
 chardev/char-mux.c       |  8 +++++---
 chardev/char-null.c      |  4 ++--
 chardev/char-parallel.c  | 14 ++++++++------
 chardev/char-pipe.c      | 12 +++++++-----
 chardev/char-pty.c       |  9 ++++++---
 chardev/char-ringbuf.c   |  5 +++--
 chardev/char-serial.c    | 15 +++++++++------
 chardev/char-socket.c    | 17 +++++++++--------
 chardev/char-stdio.c     | 11 ++++++-----
 chardev/char-udp.c       |  5 +++--
 chardev/char-win-stdio.c |  7 ++++---
 chardev/msmouse.c        |  3 ++-
 chardev/spice.c          | 13 ++++++++-----
 chardev/wctablet.c       |  3 ++-
 gdbstub/system.c         |  3 ++-
 include/chardev/char.h   |  2 +-
 ui/console-vc.c          |  3 ++-
 ui/dbus-chardev.c        |  6 +++---
 ui/gtk.c                 |  5 +++--
 ui/spice-app.c           | 10 ++++++----
 ui/vdagent.c             | 10 +++++-----
 25 files changed, 113 insertions(+), 82 deletions(-)

diff --git a/chardev/baum.c b/chardev/baum.c
index 58b74dc98d..0b0247dde0 100644
--- a/chardev/baum.c
+++ b/chardev/baum.c
@@ -642,7 +642,7 @@ static void char_braille_finalize(Object *obj)
     }
 }
 
-static void baum_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool baum_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     BaumChardev *baum = BAUM_CHARDEV(chr);
     brlapi_handle_t *handle;
@@ -656,7 +656,7 @@ static void baum_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
                    brlapi_strerror(brlapi_error_location()));
         g_free(handle);
         baum->brlapi = NULL;
-        return;
+        return false;
     }
     baum->deferred_init = 0;
 
@@ -669,6 +669,7 @@ static void baum_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void char_braille_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-console.c b/chardev/char-console.c
index 423f0f4cc4..c911cc62e3 100644
--- a/chardev/char-console.c
+++ b/chardev/char-console.c
@@ -31,6 +31,7 @@ static void console_chr_open(Chardev *chr, ChardevBackend *backend,
 {
     win_chr_set_file(chr, GetStdHandle(STD_OUTPUT_HANDLE), true);
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void char_console_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-file.c b/chardev/char-file.c
index 34ef386abc..b0dd9d5f87 100644
--- a/chardev/char-file.c
+++ b/chardev/char-file.c
@@ -34,7 +34,7 @@
 #include "chardev/char-fd.h"
 #endif
 
-static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevFile *file = backend->u.file.data;
 #ifdef _WIN32
@@ -44,7 +44,7 @@ static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
     if (file->in) {
         error_setg(errp, "input file not supported");
-        return;
+        return false;
     }
 
     if (file->has_append && file->append) {
@@ -61,7 +61,7 @@ static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
                      FILE_ATTRIBUTE_NORMAL, NULL);
     if (out == INVALID_HANDLE_VALUE) {
         error_setg(errp, "open %s failed", file->out);
-        return;
+        return false;
     }
 
     win_chr_set_file(chr, out, false);
@@ -77,7 +77,7 @@ static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
     out = qmp_chardev_open_file_source(file->out, flags, errp);
     if (out < 0) {
-        return;
+        return false;
     }
 
     if (file->in) {
@@ -85,7 +85,7 @@ static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         in = qmp_chardev_open_file_source(file->in, flags, errp);
         if (in < 0) {
             qemu_close(out);
-            return;
+            return false;
         }
     }
 
@@ -94,11 +94,12 @@ static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         if (in >= 0) {
             qemu_close(in);
         }
-        return;
+        return false;
     }
 #endif
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void file_chr_parse(QemuOpts *opts, ChardevBackend *backend,
diff --git a/chardev/char-hub.c b/chardev/char-hub.c
index aa6058c2f6..05cf722b5b 100644
--- a/chardev/char-hub.c
+++ b/chardev/char-hub.c
@@ -203,7 +203,7 @@ static void hub_chr_update_read_handlers(Chardev *chr)
     }
 }
 
-static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHub *hub = backend->u.hub.data;
     HubChardev *d = HUB_CHARDEV(chr);
@@ -213,7 +213,7 @@ static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
     if (list == NULL) {
         error_setg(errp, "hub: 'chardevs' list is not defined");
-        return;
+        return false;
     }
 
     while (list) {
@@ -223,17 +223,17 @@ static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         if (s == NULL) {
             error_setg(errp, "hub: chardev can't be found by id '%s'",
                        list->value);
-            return;
+            return false;
         }
         if (CHARDEV_IS_HUB(s) || CHARDEV_IS_MUX(s)) {
             error_setg(errp, "hub: multiplexers and hub devices can't be "
                        "stacked, check chardev '%s', chardev should not "
                        "be a hub device or have 'mux=on' enabled",
                        list->value);
-            return;
+            return false;
         }
         if (!hub_chr_attach_chardev(d, s, errp)) {
-            return;
+            return false;
         }
         list = list->next;
     }
@@ -242,6 +242,7 @@ static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
      * Closed until an explicit event from backend, so we don't
      * send CHR_EVENT_OPENED now.
      */
+    return true;
 }
 
 static void hub_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 7210df431f..881443d869 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -361,7 +361,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
     mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 }
 
-static void mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevMux *mux = backend->u.mux.data;
     Chardev *drv;
@@ -370,12 +370,12 @@ static void mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     drv = qemu_chr_find(mux->chardev);
     if (drv == NULL) {
         error_setg(errp, "mux: base chardev %s not found", mux->chardev);
-        return;
+        return false;
     }
 
     d->focus = -1;
     if (!qemu_chr_fe_init(&d->chr, drv, errp)) {
-        return;
+        return false;
     }
 
     /*
@@ -385,6 +385,8 @@ static void mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     if (muxes_opened) {
         qemu_chr_be_event(chr, CHR_EVENT_OPENED);
     }
+
+    return true;
 }
 
 static void mux_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-null.c b/chardev/char-null.c
index 900b5febb6..d5a101178b 100644
--- a/chardev/char-null.c
+++ b/chardev/char-null.c
@@ -26,9 +26,9 @@
 #include "chardev/char.h"
 #include "qemu/module.h"
 
-static void null_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool null_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
-    /* do not send CHR_EVENT_OPENED */
+    return true;
 }
 
 static void char_null_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index 359efa3c9c..cbf87e660d 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -157,7 +157,7 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
+static bool parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
 
@@ -165,11 +165,12 @@ static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
 
     if (ioctl(fd, PPCLAIM) < 0) {
         error_setg_errno(errp, errno, "not a parallel port");
-        return;
+        return false;
     }
 
     drv->mode = IEEE1284_MODE_COMPAT;
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 #endif /* __linux__ */
 
@@ -225,15 +226,16 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
+static bool parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
 {
     ParallelChardev *drv = PARALLEL_CHARDEV(chr);
     drv->fd = fd;
+    return true;
 }
 #endif
 
 #ifdef HAVE_CHARDEV_PARALLEL
-static void parallel_chr_open(Chardev *chr,
+static bool parallel_chr_open(Chardev *chr,
                               ChardevBackend *backend,
                               Error **errp)
 {
@@ -242,9 +244,9 @@ static void parallel_chr_open(Chardev *chr,
 
     fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
     if (fd < 0) {
-        return;
+        return false;
     }
-    parallel_chr_open_fd(chr, fd, errp);
+    return parallel_chr_open_fd(chr, fd, errp);
 }
 
 static void parallel_chr_parse(QemuOpts *opts, ChardevBackend *backend,
diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c
index 2f26372dfc..472b3e0801 100644
--- a/chardev/char-pipe.c
+++ b/chardev/char-pipe.c
@@ -103,21 +103,22 @@ static int win_chr_pipe_init(Chardev *chr, const char *filename,
     return -1;
 }
 
-static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     const char *filename = opts->device;
 
     if (win_chr_pipe_init(chr, filename, errp) < 0) {
-        return;
+        return false;
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 #else
 
-static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *opts = backend->u.pipe.data;
     int fd_in, fd_out;
@@ -143,7 +144,7 @@ static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         );
         if (fd_in < 0) {
             error_setg_file_open(errp, errno, filename);
-            return;
+            return false;
         }
     }
 
@@ -152,10 +153,11 @@ static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         if (fd_out != fd_in) {
             close(fd_out);
         }
-        return;
+        return false;
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 #endif /* !_WIN32 */
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index d4d69a29a9..9e26e97baf 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -331,7 +331,7 @@ static int qemu_openpty_raw(int *aslave, char *pty_name)
     return amaster;
 }
 
-static void pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     PtyChardev *s;
     int master_fd, slave_fd;
@@ -342,13 +342,13 @@ static void pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     master_fd = qemu_openpty_raw(&slave_fd, pty_name);
     if (master_fd < 0) {
         error_setg_errno(errp, errno, "Failed to create PTY");
-        return;
+        return false;
     }
 
     close(slave_fd);
     if (!qemu_set_blocking(master_fd, false, errp)) {
         close(master_fd);
-        return;
+        return false;
     }
 
     chr->filename = g_strdup_printf("pty:%s", pty_name);
@@ -368,10 +368,13 @@ static void pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
         if (res != 0) {
             error_setg_errno(errp, errno, "Failed to create PTY symlink");
+            return false;
         } else {
             s->path = g_strdup(path);
         }
     }
+
+    return true;
 }
 
 static void pty_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 30b17a96d3..8f998d26a4 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -92,7 +92,7 @@ static void char_ringbuf_finalize(Object *obj)
     g_free(d->cbuf);
 }
 
-static void ringbuf_chr_open(Chardev *chr,
+static bool ringbuf_chr_open(Chardev *chr,
                              ChardevBackend *backend,
                              Error **errp)
 {
@@ -104,7 +104,7 @@ static void ringbuf_chr_open(Chardev *chr,
     /* The size must be power of 2 */
     if (d->size & (d->size - 1)) {
         error_setg(errp, "size of ringbuf chardev must be power of two");
-        return;
+        return false;
     }
 
     d->prod = 0;
@@ -112,6 +112,7 @@ static void ringbuf_chr_open(Chardev *chr,
     d->cbuf = g_malloc0(d->size);
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 void qmp_ringbuf_write(const char *device, const char *data,
diff --git a/chardev/char-serial.c b/chardev/char-serial.c
index 9995f18425..0c73bafc54 100644
--- a/chardev/char-serial.c
+++ b/chardev/char-serial.c
@@ -41,15 +41,17 @@
 
 #ifdef _WIN32
 
-static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
     int ret = win_chr_serial_init(chr, serial->device, errp);
     if (ret < 0) {
-        return;
+        return false;
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+
+    return true;
 }
 
 #elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__)      \
@@ -259,7 +261,7 @@ static int serial_chr_ioctl(Chardev *chr, int cmd, void *arg)
     return 0;
 }
 
-static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevHostdev *serial = backend->u.serial.data;
     int fd;
@@ -267,20 +269,21 @@ static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK,
                                       errp);
     if (fd < 0) {
-        return;
+        return false;
     }
     if (!qemu_set_blocking(fd, false, errp)) {
         close(fd);
-        return;
+        return false;
     }
     tty_serial_init(fd, 115200, 'N', 8, 1);
 
     if (!qemu_chr_open_fd(chr, fd, fd, errp)) {
         close(fd);
-        return;
+        return false;
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 #endif /* __linux__ || __sun__ */
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 3f57ef4016..31c9acd164 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1365,7 +1365,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
 }
 
 
-static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
     ChardevSocket *sock = backend->u.socket.data;
@@ -1390,7 +1390,7 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         if (!creds) {
             error_setg(errp, "No TLS credentials with id '%s'",
                        sock->tls_creds);
-            return;
+            return false;
         }
         s->tls_creds = (QCryptoTLSCreds *)
             object_dynamic_cast(creds,
@@ -1398,7 +1398,7 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         if (!s->tls_creds) {
             error_setg(errp, "Object with id '%s' is not TLS credentials",
                        sock->tls_creds);
-            return;
+            return false;
         }
         object_ref(OBJECT(s->tls_creds));
         if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
@@ -1406,7 +1406,7 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
                                           ? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
                                           : QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
                                           errp)) {
-            return;
+            return false;
         }
     }
     s->tls_authz = g_strdup(sock->tls_authz);
@@ -1414,7 +1414,7 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     s->addr = addr = socket_address_flatten(sock->addr);
 
     if (!qmp_chardev_validate_socket(sock, addr, errp)) {
-        return;
+        return false;
     }
 
     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
@@ -1431,7 +1431,7 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
      */
     if (!chr->handover_yank_instance) {
         if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
-            return;
+            return false;
         }
     }
     s->registered_yank = true;
@@ -1441,15 +1441,16 @@ static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     if (s->is_listen) {
         if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
                                            is_waitconnect, errp) < 0) {
-            return;
+            return false;
         }
     } else {
         if (qmp_chardev_open_socket_client(chr, reconnect_ms, errp) < 0) {
-            return;
+            return false;
         }
     }
 
     /* be isn't opened until we get a connection */
+    return true;
 }
 
 static void tcp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
index 534f6ed565..fe1cbb2d88 100644
--- a/chardev/char-stdio.c
+++ b/chardev/char-stdio.c
@@ -85,19 +85,19 @@ static void term_stdio_handler(int sig)
     stdio_chr_set_echo(NULL, stdio_echo_state);
 }
 
-static void stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevStdio *opts = backend->u.stdio.data;
     struct sigaction act;
 
     if (is_daemonized()) {
         error_setg(errp, "cannot use stdio with -daemonize");
-        return;
+        return false;
     }
 
     if (stdio_in_use) {
         error_setg(errp, "cannot use stdio by multiple character devices");
-        return;
+        return false;
     }
 
     stdio_in_use = true;
@@ -105,11 +105,11 @@ static void stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     old_fd1_flags = fcntl(1, F_GETFL);
     tcgetattr(0, &oldtty);
     if (!qemu_set_blocking(0, false, errp)) {
-        return;
+        return false;
     }
 
     if (!qemu_chr_open_fd(chr, 0, 1, errp)) {
-        return;
+        return false;
     }
 
     atexit(term_exit);
@@ -122,6 +122,7 @@ static void stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     stdio_chr_set_echo(chr, false);
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 #endif
 
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index b835a967e1..3d3bc1f659 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -188,7 +188,7 @@ static void udp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
     }
 }
 
-static void upd_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool upd_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevUdp *udp = backend->u.udp.data;
     SocketAddress *local_addr = socket_address_flatten(udp->local);
@@ -203,7 +203,7 @@ static void upd_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     qapi_free_SocketAddress(remote_addr);
     if (ret < 0) {
         object_unref(OBJECT(sioc));
-        return;
+        return false;
     }
 
     name = g_strdup_printf("chardev-udp-%s", chr->label);
@@ -212,6 +212,7 @@ static void upd_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
     s->ioc = QIO_CHANNEL(sioc);
     /* be isn't opened until we get a connection */
+    return true;
 }
 
 static void char_udp_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index 0535960ff1..bb9c195a8b 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -142,7 +142,7 @@ static void win_stiod_chr_set_echo(Chardev *chr, bool echo)
     }
 }
 
-static void win_stdio_chr_open(Chardev *chr,
+static bool win_stdio_chr_open(Chardev *chr,
                                ChardevBackend *backend,
                                Error **errp)
 {
@@ -155,7 +155,7 @@ static void win_stdio_chr_open(Chardev *chr,
     stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
     if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
         error_setg(errp, "cannot open stdio: invalid handle");
-        return;
+        return false;
     }
 
     is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
@@ -208,7 +208,7 @@ static void win_stdio_chr_open(Chardev *chr,
     win_stiod_chr_set_echo(chr, false);
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
-    return;
+    return true;
 
 err3:
     qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
@@ -217,6 +217,7 @@ err2:
     CloseHandle(stdio->hInputDoneEvent);
 err1:
     qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
+    return false;
 }
 
 static void char_win_stdio_finalize(Object *obj)
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index 9dc04e3b3e..365f04546e 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -253,7 +253,7 @@ static void char_msmouse_finalize(Object *obj)
     fifo8_destroy(&mouse->outbuf);
 }
 
-static void msmouse_chr_open(Chardev *chr,
+static bool msmouse_chr_open(Chardev *chr,
                              ChardevBackend *backend,
                              Error **errp)
 {
@@ -265,6 +265,7 @@ static void msmouse_chr_open(Chardev *chr,
     fifo8_create(&mouse->outbuf, MSMOUSE_BUF_SZ);
 
     /* Never send CHR_EVENT_OPENED */
+    return true;
 }
 
 static void char_msmouse_class_init(ObjectClass *oc, const void *data)
diff --git a/chardev/spice.c b/chardev/spice.c
index 612f358885..d110ed96f4 100644
--- a/chardev/spice.c
+++ b/chardev/spice.c
@@ -251,7 +251,7 @@ static void chr_open(Chardev *chr, const char *subtype)
     s->sin.subtype = g_strdup(subtype);
 }
 
-static void spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
+static bool spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
                                Error **errp)
 {
     ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
@@ -272,7 +272,7 @@ static void spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
                           subtypes);
 
         g_free(subtypes);
-        return;
+        return false;
     }
 
 #if SPICE_SERVER_VERSION < 0x000e02
@@ -280,12 +280,14 @@ static void spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
     if (strcmp(type, "smartcard") == 0) {
         chr_open(chr, type);
         qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+        return true;
     }
 #endif
     chr_open(chr, type);
+    return true;
 }
 
-static void spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
+static bool spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
                                 Error **errp)
 {
     ChardevSpicePort *spiceport = backend->u.spiceport.data;
@@ -294,12 +296,12 @@ static void spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
 
     if (name == NULL) {
         error_setg(errp, "missing name parameter");
-        return;
+        return false;
     }
 
     if (!using_spice) {
         error_setg(errp, "spice not enabled");
-        return;
+        return false;
     }
 
     chr_open(chr, "port");
@@ -308,6 +310,7 @@ static void spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
     s->sin.portname = g_strdup(name);
 
     vmc_register_interface(s);
+    return true;
 }
 
 static void spice_vmc_chr_parse(QemuOpts *opts, ChardevBackend *backend,
diff --git a/chardev/wctablet.c b/chardev/wctablet.c
index 65b2ceb58c..214d5ca2e2 100644
--- a/chardev/wctablet.c
+++ b/chardev/wctablet.c
@@ -324,7 +324,7 @@ static void wctablet_chr_finalize(Object *obj)
     }
 }
 
-static void wctablet_chr_open(Chardev *chr,
+static bool wctablet_chr_open(Chardev *chr,
                               ChardevBackend *backend,
                               Error **errp)
 {
@@ -339,6 +339,7 @@ static void wctablet_chr_open(Chardev *chr,
                                              &wctablet_handler);
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void wctablet_chr_class_init(ObjectClass *oc, const void *data)
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 49da1f73cc..ec24d812b3 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -233,9 +233,10 @@ static int gdb_chr_write(Chardev *chr, const uint8_t *buf, int len)
     return len;
 }
 
-static void gdb_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool gdb_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     /* Never send CHR_EVENT_OPENED */
+    return true;
 }
 
 static void char_gdb_class_init(ObjectClass *oc, const void *data)
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 47c75c3582..23a227dca9 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -260,7 +260,7 @@ struct ChardevClass {
     void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 
     /* called after construction, open/starts the backend */
-    void (*chr_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
+    bool (*chr_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
 
     /* write buf to the backend */
     int (*chr_write)(Chardev *s, const uint8_t *buf, int len);
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 4c8ea4c148..f22806fed7 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -1093,7 +1093,7 @@ void qemu_text_console_update_size(QemuTextConsole *c)
     dpy_text_resize(QEMU_CONSOLE(c), c->width, c->height);
 }
 
-static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevVC *vc = backend->u.vc.data;
     VCChardev *drv = VC_CHARDEV(chr);
@@ -1142,6 +1142,7 @@ static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c
index 3e471f84cd..9442b47551 100644
--- a/ui/dbus-chardev.c
+++ b/ui/dbus-chardev.c
@@ -176,7 +176,7 @@ dbus_chr_send_break(
     return DBUS_METHOD_INVOCATION_HANDLED;
 }
 
-static void dbus_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool dbus_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ERRP_GUARD();
 
@@ -206,9 +206,9 @@ static void dbus_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_parse(
         opts, be, errp);
     if (*errp) {
-        return;
+        return false;
     }
-    CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_open(
+    return CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_open(
         chr, be, errp);
 }
 
diff --git a/ui/gtk.c b/ui/gtk.c
index 3eeb5baa11..e2c0135646 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1967,7 +1967,7 @@ static void gd_vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     if (nb_vcs == MAX_VCS) {
         error_setg(errp, "Maximum number of consoles reached");
-        return;
+        return false;
     }
 
     vcs[nb_vcs++] = chr;
@@ -1976,13 +1976,14 @@ static void gd_vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
      * console/chardev init sometimes completes elsewhere in a 2nd
      * stage, so defer OPENED events until they are fully initialized
      */
+    return true;
 }
 
 static void char_gd_vc_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    cc->chr_open = gd_vc_chr_open;
+    cc->chr_open = char_gtk_init;
     cc->chr_write = gd_vc_chr_write;
     cc->chr_accept_input = gd_vc_chr_accept_input;
     cc->chr_set_echo = gd_vc_chr_set_echo;
diff --git a/ui/spice-app.c b/ui/spice-app.c
index 7ac9ae4e78..9e55f27371 100644
--- a/ui/spice-app.c
+++ b/ui/spice-app.c
@@ -49,7 +49,7 @@ struct VCChardev {
 
 struct VCChardevClass {
     ChardevClass parent;
-    void (*parent_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
+    bool (*parent_init)(Chardev *chr, ChardevBackend *backend, Error **errp);
 };
 
 #define TYPE_CHARDEV_VC "chardev-vc"
@@ -66,11 +66,12 @@ chr_spice_backend_new(void)
     return be;
 }
 
-static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     VCChardevClass *vc = CHARDEV_VC_GET_CLASS(chr);
     ChardevBackend *be;
     const char *fqdn = NULL;
+    bool ok;
 
     if (strstart(chr->label, "serial", NULL)) {
         fqdn = "org.qemu.console.serial.0";
@@ -83,8 +84,9 @@ static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     be = chr_spice_backend_new();
     be->u.spiceport.data->fqdn = fqdn ?
         g_strdup(fqdn) : g_strdup_printf("org.qemu.console.%s", chr->label);
-    vc->parent_open(chr, be, errp);
+    ok = vc->parent_init(chr, be, errp);
     qapi_free_ChardevBackend(be);
+    return ok;
 }
 
 static void vc_chr_set_echo(Chardev *chr, bool echo)
@@ -102,7 +104,7 @@ static void char_vc_class_init(ObjectClass *oc, const void *data)
     VCChardevClass *vc = CHARDEV_VC_CLASS(oc);
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
-    vc->parent_open = cc->chr_open;
+    vc->parent_init = cc->chr_open;
 
     cc->chr_parse = vc_chr_parse;
     cc->chr_open = vc_chr_open;
diff --git a/ui/vdagent.c b/ui/vdagent.c
index 3becc6c076..d5c6e3340b 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -660,8 +660,7 @@ static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
 /* ------------------------------------------------------------------ */
 /* chardev backend                                                    */
 
-static void vdagent_chr_open(Chardev *chr,
-                             ChardevBackend *backend,
+static bool vdagent_chr_open(Chardev *chr, ChardevBackend *backend,
                              Error **errp)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
@@ -673,7 +672,7 @@ static void vdagent_chr_open(Chardev *chr,
      * so we have to byteswap everything on BE hosts.
      */
     error_setg(errp, "vdagent is not supported on bigendian hosts");
-    return;
+    return false;
 #endif
 
     vd->mouse = VDAGENT_MOUSE_DEFAULT;
@@ -692,6 +691,7 @@ static void vdagent_chr_open(Chardev *chr,
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    return true;
 }
 
 static void vdagent_clipboard_peer_register(VDAgentChardev *vd)
@@ -1074,7 +1074,7 @@ static const VMStateDescription vmstate_vdagent = {
     }
 };
 
-static void vdagent_chr_init(Object *obj)
+static void vdagent_chr_instance_init(Object *obj)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj);
 
@@ -1097,7 +1097,7 @@ static const TypeInfo vdagent_chr_type_info = {
     .name = TYPE_CHARDEV_QEMU_VDAGENT,
     .parent = TYPE_CHARDEV,
     .instance_size = sizeof(VDAgentChardev),
-    .instance_init = vdagent_chr_init,
+    .instance_init = vdagent_chr_instance_init,
     .instance_finalize = vdagent_chr_fini,
     .class_init = vdagent_chr_class_init,
 };
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/8] chardev/char-pty: store pty_name into PtyChardev state
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (3 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 4/8] chardev: .chr_open(): add boolean return value Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 6/8] chardev: introduce .chr_get_pty_name() handler Vladimir Sementsov-Ogievskiy
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: pbonzini, qemu-devel, vsementsov, d-tatianin

We'll use it in following commit.

Note the bonus: stop use blind strcpy().

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/char-pty.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 9e26e97baf..a582aa7bc7 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -43,6 +43,7 @@ struct PtyChardev {
     int connected;
     GSource *timer_src;
     char *path;
+    char *pty_name;
 };
 typedef struct PtyChardev PtyChardev;
 
@@ -303,7 +304,7 @@ static void cfmakeraw (struct termios *termios_p)
 #endif
 
 /* like openpty() but also makes it raw; return master fd */
-static int qemu_openpty_raw(int *aslave, char *pty_name)
+static int qemu_openpty_raw(int *aslave, char **pty_name)
 {
     int amaster;
     struct termios tty;
@@ -324,9 +325,7 @@ static int qemu_openpty_raw(int *aslave, char *pty_name)
     cfmakeraw(&tty);
     tcsetattr(*aslave, TCSAFLUSH, &tty);
 
-    if (pty_name) {
-        strcpy(pty_name, q_ptsname(amaster));
-    }
+    *pty_name = g_strdup(q_ptsname(amaster));
 
     return amaster;
 }
@@ -335,11 +334,12 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     PtyChardev *s;
     int master_fd, slave_fd;
-    char pty_name[PATH_MAX];
     char *name;
     char *path = backend->u.pty.data->path;
 
-    master_fd = qemu_openpty_raw(&slave_fd, pty_name);
+    s = PTY_CHARDEV(chr);
+
+    master_fd = qemu_openpty_raw(&slave_fd, &s->pty_name);
     if (master_fd < 0) {
         error_setg_errno(errp, errno, "Failed to create PTY");
         return false;
@@ -351,11 +351,10 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         return false;
     }
 
-    chr->filename = g_strdup_printf("pty:%s", pty_name);
+    chr->filename = g_strdup_printf("pty:%s", s->pty_name);
     qemu_printf("char device redirected to %s (label %s)\n",
-                pty_name, chr->label);
+                s->pty_name, chr->label);
 
-    s = PTY_CHARDEV(chr);
     s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd));
     name = g_strdup_printf("chardev-pty-%s", chr->label);
     qio_channel_set_name(s->ioc, name);
@@ -364,7 +363,7 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 
     /* create symbolic link */
     if (path) {
-        int res = symlink(pty_name, path);
+        int res = symlink(s->pty_name, path);
 
         if (res != 0) {
             error_setg_errno(errp, errno, "Failed to create PTY symlink");
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 6/8] chardev: introduce .chr_get_pty_name() handler
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (4 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 5/8] chardev/char-pty: store pty_name into PtyChardev state Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 7/8] chardev: rework filename handling Vladimir Sementsov-Ogievskiy
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau
  Cc: pbonzini, qemu-devel, vsementsov, d-tatianin, Stefano Stabellini,
	Anthony PERARD, Paul Durrant, Edgar E. Iglesias,
	open list:X86 Xen CPUs

Currently we do two wrong things:

1. Abuse s->filename to get pty_name from it

2. Violate layering with help of CHARDEV_IS_PTY()

Let's get rid of both, and introduce correct way to get pty name in
generic code, if available.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/char-pty.c     |  7 +++++++
 chardev/char.c         | 19 +++++++++++++------
 hw/char/xen_console.c  |  7 ++++---
 include/chardev/char.h |  7 +++++--
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index a582aa7bc7..047aade09e 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -387,6 +387,12 @@ static void pty_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
     pty->path = g_strdup(path);
 }
 
+static char *pty_chr_get_pty_name(Chardev *chr)
+{
+    PtyChardev *s = PTY_CHARDEV(chr);
+    return g_strdup(s->pty_name);
+}
+
 static void char_pty_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -396,6 +402,7 @@ static void char_pty_class_init(ObjectClass *oc, const void *data)
     cc->chr_write = pty_chr_write;
     cc->chr_update_read_handler = pty_chr_update_read_handler;
     cc->chr_add_watch = pty_chr_add_watch;
+    cc->chr_get_pty_name = pty_chr_get_pty_name;
 }
 
 static const TypeInfo char_pty_type_info = {
diff --git a/chardev/char.c b/chardev/char.c
index 44bfed3627..0dc792b88f 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -1090,9 +1090,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
     }
 
     ret = g_new0(ChardevReturn, 1);
-    if (CHARDEV_IS_PTY(chr)) {
-        ret->pty = g_strdup(chr->filename + 4);
-    }
+    ret->pty = qemu_chr_get_pty_name(chr);
 
     return ret;
 
@@ -1101,6 +1099,17 @@ err:
     return NULL;
 }
 
+char *qemu_chr_get_pty_name(Chardev *chr)
+{
+    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
+
+    if (cc->chr_get_pty_name) {
+        return cc->chr_get_pty_name(chr);
+    }
+
+    return NULL;
+}
+
 ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
                                   Error **errp)
 {
@@ -1192,9 +1201,7 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
     object_unref(OBJECT(chr_new));
 
     ret = g_new0(ChardevReturn, 1);
-    if (CHARDEV_IS_PTY(chr_new)) {
-        ret->pty = g_strdup(chr_new->filename + 4);
-    }
+    ret->pty = qemu_chr_get_pty_name(chr_new);
 
     return ret;
 }
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index a639fb0b11..7502de46e4 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -418,6 +418,7 @@ static void xen_console_realize(XenDevice *xendev, Error **errp)
     XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
     Chardev *cs = qemu_chr_fe_get_driver(&con->chr);
     unsigned int u;
+    g_autofree char *pty_name = NULL;
 
     if (!cs) {
         error_setg(errp, "no backing character device");
@@ -450,9 +451,9 @@ static void xen_console_realize(XenDevice *xendev, Error **errp)
 
     trace_xen_console_realize(con->dev, object_get_typename(OBJECT(cs)));
 
-    if (CHARDEV_IS_PTY(cs)) {
-        /* Strip the leading 'pty:' */
-        xen_device_frontend_printf(xendev, "tty", "%s", cs->filename + 4);
+    pty_name = qemu_chr_get_pty_name(cs);
+    if (pty_name) {
+        xen_device_frontend_printf(xendev, "tty", "%s", pty_name);
     }
 
     /* No normal PV driver initialization for the primary console under Xen */
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 23a227dca9..d36e50b99e 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -247,8 +247,6 @@ OBJECT_DECLARE_TYPE(Chardev, ChardevClass, CHARDEV)
 
 #define CHARDEV_IS_RINGBUF(chr) \
     object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF)
-#define CHARDEV_IS_PTY(chr) \
-    object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY)
 
 struct ChardevClass {
     ObjectClass parent_class;
@@ -306,6 +304,9 @@ struct ChardevClass {
 
     /* handle various events */
     void (*chr_be_event)(Chardev *s, QEMUChrEvent event);
+
+    /* return PTY name if available */
+    char *(*chr_get_pty_name)(Chardev *s);
 };
 
 Chardev *qemu_chardev_new(const char *id, const char *typename,
@@ -320,4 +321,6 @@ GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
 void suspend_mux_open(void);
 void resume_mux_open(void);
 
+char *qemu_chr_get_pty_name(Chardev *chr);
+
 #endif
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 7/8] chardev: rework filename handling
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (5 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 6/8] chardev: introduce .chr_get_pty_name() handler Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 13:43 ` [PATCH 8/8] chardev/char: qemu_char_open(): add return value Vladimir Sementsov-Ogievskiy
  2025-12-01 13:00 ` [PATCH for-11.0 0/8] chardev: cleanup Marc-André Lureau
  8 siblings, 0 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: pbonzini, qemu-devel, vsementsov, d-tatianin

We have the following flaws with it:

1. Layring violation by modifying generic state directly in backends

2. Tricky generic logic: we should check, did backend set the
generic state field, and fill it when not.

Let's fix them all by making filename a private field with getter
and setter. And move the "default logic" into getter.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/char-pty.c     |  4 +++-
 chardev/char-socket.c  | 17 ++++++++---------
 chardev/char.c         |  8 ++------
 hw/misc/ivshmem-pci.c  |  4 ++--
 include/chardev/char.h | 21 ++++++++++++++++++++-
 5 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 047aade09e..f4294679be 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -336,6 +336,7 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
     int master_fd, slave_fd;
     char *name;
     char *path = backend->u.pty.data->path;
+    g_autofree char *filename = NULL;
 
     s = PTY_CHARDEV(chr);
 
@@ -351,7 +352,8 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         return false;
     }
 
-    chr->filename = g_strdup_printf("pty:%s", s->pty_name);
+    filename = g_strdup_printf("pty:%s", s->pty_name);
+    qemu_chr_set_filename(chr, filename);
     qemu_printf("char device redirected to %s (label %s)\n",
                 s->pty_name, chr->label);
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 31c9acd164..9387760009 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -384,8 +384,7 @@ static void tcp_chr_free_connection(Chardev *chr)
     s->sioc = NULL;
     object_unref(OBJECT(s->ioc));
     s->ioc = NULL;
-    g_free(chr->filename);
-    chr->filename = NULL;
+    qemu_chr_set_filename(chr, NULL);
     tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
 }
 
@@ -443,11 +442,11 @@ static void update_disconnected_filename(SocketChardev *s)
 {
     Chardev *chr = CHARDEV(s);
 
-    g_free(chr->filename);
     if (s->addr) {
-        chr->filename = qemu_chr_socket_address(s, "disconnected:");
+        g_autofree char *filename = qemu_chr_socket_address(s, "disconnected:");
+        qemu_chr_set_filename(chr, filename);
     } else {
-        chr->filename = g_strdup("disconnected:socket");
+        qemu_chr_set_filename(chr, "disconnected:socket");
     }
 }
 
@@ -638,9 +637,9 @@ static void tcp_chr_connect(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
     SocketChardev *s = SOCKET_CHARDEV(opaque);
+    g_autofree char *filename = qemu_chr_compute_filename(s);
 
-    g_free(chr->filename);
-    chr->filename = qemu_chr_compute_filename(s);
+    qemu_chr_set_filename(chr, filename);
 
     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
     update_ioc_handlers(s);
@@ -1000,8 +999,8 @@ static void tcp_chr_accept_server_sync(Chardev *chr)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
     QIOChannelSocket *sioc;
-    info_report("QEMU waiting for connection on: %s",
-                chr->filename);
+    g_autofree char *filename = qemu_chr_get_filename(chr);
+    info_report("QEMU waiting for connection on: %s", filename);
     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
     sioc = qio_net_listener_wait_client(s->listener);
     tcp_chr_set_client_ioc_name(chr, sioc);
diff --git a/chardev/char.c b/chardev/char.c
index 0dc792b88f..bdd907f015 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -309,7 +309,7 @@ static void char_finalize(Object *obj)
     if (chr->fe) {
         chr->fe->chr = NULL;
     }
-    g_free(chr->filename);
+    qemu_chr_set_filename(chr, NULL);
     g_free(chr->label);
     if (chr->logfd != -1) {
         close(chr->logfd);
@@ -796,7 +796,7 @@ static int qmp_query_chardev_foreach(Object *obj, void *data)
     ChardevInfo *value = g_malloc0(sizeof(*value));
 
     value->label = g_strdup(chr->label);
-    value->filename = g_strdup(chr->filename);
+    value->filename = qemu_chr_get_filename(chr);
     value->frontend_open = chr->fe && chr->fe->fe_is_open;
 
     QAPI_LIST_PREPEND(*list, value);
@@ -1025,10 +1025,6 @@ static Chardev *chardev_new(const char *id, const char *typename,
         return NULL;
     }
 
-    if (!chr->filename) {
-        chr->filename = g_strdup(typename + 8);
-    }
-
     return chr;
 }
 
diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c
index 636d0b83de..2c7b987241 100644
--- a/hw/misc/ivshmem-pci.c
+++ b/hw/misc/ivshmem-pci.c
@@ -873,10 +873,10 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
         host_memory_backend_set_mapped(s->hostmem, true);
     } else {
         Chardev *chr = qemu_chr_fe_get_driver(&s->server_chr);
+        char *filename = qemu_chr_get_filename(chr);
         assert(chr);
 
-        IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
-                        chr->filename);
+        IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", filename);
 
         /* we allocate enough space for 16 peers and grow as needed */
         resize_peers(s, 16);
diff --git a/include/chardev/char.h b/include/chardev/char.h
index d36e50b99e..ffeb4a4e3b 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -62,7 +62,7 @@ struct Chardev {
     QemuMutex chr_write_lock;
     CharFrontend *fe;
     char *label;
-    char *filename;
+    char *_filename;
     int logfd;
     int be_open;
     /* used to coordinate the chardev-change special-case: */
@@ -72,6 +72,25 @@ struct Chardev {
     DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
 };
 
+static inline char *qemu_chr_get_filename(Chardev *chr)
+{
+    const char *typename;
+
+    if (chr->_filename) {
+        return g_strdup(chr->_filename);
+    }
+
+    typename = object_get_typename(OBJECT(chr));
+    assert(g_str_has_prefix(typename, "chardev-"));
+    return g_strdup(typename + 8);
+}
+
+static inline void qemu_chr_set_filename(Chardev *chr, const char *filename)
+{
+    g_free(chr->_filename);
+    chr->_filename = g_strdup(filename);
+}
+
 /**
  * qemu_chr_new_from_opts:
  * @opts: see qemu-config.c for a list of valid options
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 8/8] chardev/char: qemu_char_open(): add return value
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (6 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 7/8] chardev: rework filename handling Vladimir Sementsov-Ogievskiy
@ 2025-11-29 13:43 ` Vladimir Sementsov-Ogievskiy
  2025-11-29 14:17   ` Philippe Mathieu-Daudé
  2025-12-01 13:00 ` [PATCH for-11.0 0/8] chardev: cleanup Marc-André Lureau
  8 siblings, 1 reply; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-11-29 13:43 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: pbonzini, qemu-devel, vsementsov, d-tatianin

Accordingly with recommendations in include/qapi/error.h accompany
errp by boolean return value and get rid of error propagation.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 chardev/char.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/chardev/char.c b/chardev/char.c
index bdd907f015..fadbda5907 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -246,7 +246,7 @@ int qemu_chr_add_client(Chardev *s, int fd)
         CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
 }
 
-static void qemu_char_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool qemu_char_open(Chardev *chr, ChardevBackend *backend, Error **errp)
 {
     ChardevClass *cc = CHARDEV_GET_CLASS(chr);
     /* Any ChardevCommon member would work */
@@ -262,13 +262,15 @@ static void qemu_char_open(Chardev *chr, ChardevBackend *backend, Error **errp)
         }
         chr->logfd = qemu_create(common->logfile, flags, 0666, errp);
         if (chr->logfd < 0) {
-            return;
+            return false;
         }
     }
 
-    if (cc->chr_open) {
-        cc->chr_open(chr, backend, errp);
+    if (cc->chr_open && !cc->chr_open(chr, backend, errp)) {
+        return false;
     }
+
+    return true;
 }
 
 static void char_init(Object *obj)
@@ -1007,7 +1009,6 @@ static Chardev *chardev_new(const char *id, const char *typename,
 {
     Object *obj;
     Chardev *chr = NULL;
-    Error *local_err = NULL;
 
     assert(g_str_has_prefix(typename, "chardev-"));
     assert(id);
@@ -1018,9 +1019,7 @@ static Chardev *chardev_new(const char *id, const char *typename,
     chr->label = g_strdup(id);
     chr->gcontext = gcontext;
 
-    qemu_char_open(chr, backend, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (!qemu_char_open(chr, backend, errp)) {
         object_unref(obj);
         return NULL;
     }
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations
  2025-11-29 13:43 ` [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations Vladimir Sementsov-Ogievskiy
@ 2025-11-29 14:07   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-29 14:07 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, marcandre.lureau
  Cc: pbonzini, qemu-devel, d-tatianin, Alex Bennée,
	Eduardo Habkost

On 29/11/25 14:43, Vladimir Sementsov-Ogievskiy wrote:
> Most handlers implementations has name like {unit_name}_{handler_name},
> which is usual and well-recognized pattern. Convert the rest (especially
> with useless qemu_ prefixes and misleading qmp_ prefixes) to the common
> pattern.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>   chardev/char-console.c                        | 10 ++---
>   chardev/char-file.c                           | 16 ++++----
>   chardev/char-hub.c                            | 15 ++++---
>   chardev/char-mux.c                            | 15 ++++---
>   chardev/char-parallel.c                       | 28 ++++++-------
>   chardev/char-pipe.c                           | 24 +++++------
>   chardev/char-pty.c                            | 19 +++++----
>   chardev/char-ringbuf.c                        | 16 ++++----
>   chardev/char-serial.c                         | 28 ++++++-------
>   chardev/char-socket.c                         | 25 ++++++------
>   chardev/char-stdio.c                          | 22 +++++-----
>   chardev/char-udp.c                            | 15 ++++---
>   chardev/char-win-stdio.c                      | 20 +++++-----
>   chardev/msmouse.c                             |  4 +-
>   chardev/spice.c                               | 40 +++++++++----------
>   gdbstub/system.c                              |  8 ++--
>   .../codeconverter/test_regexps.py             |  2 +-
>   ui/gtk.c                                      |  4 +-
>   18 files changed, 153 insertions(+), 158 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 4/8] chardev: .chr_open(): add boolean return value
  2025-11-29 13:43 ` [PATCH 4/8] chardev: .chr_open(): add boolean return value Vladimir Sementsov-Ogievskiy
@ 2025-11-29 14:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-29 14:08 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, marcandre.lureau
  Cc: pbonzini, qemu-devel, d-tatianin, Samuel Thibault,
	Alex Bennée

On 29/11/25 14:43, Vladimir Sementsov-Ogievskiy wrote:
> Add boolean return value to follow common recommendations for functions
> with errrp in include/qapi/error.h
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>   chardev/baum.c           |  5 +++--
>   chardev/char-console.c   |  1 +
>   chardev/char-file.c      | 13 +++++++------
>   chardev/char-hub.c       | 11 ++++++-----
>   chardev/char-mux.c       |  8 +++++---
>   chardev/char-null.c      |  4 ++--
>   chardev/char-parallel.c  | 14 ++++++++------
>   chardev/char-pipe.c      | 12 +++++++-----
>   chardev/char-pty.c       |  9 ++++++---
>   chardev/char-ringbuf.c   |  5 +++--
>   chardev/char-serial.c    | 15 +++++++++------
>   chardev/char-socket.c    | 17 +++++++++--------
>   chardev/char-stdio.c     | 11 ++++++-----
>   chardev/char-udp.c       |  5 +++--
>   chardev/char-win-stdio.c |  7 ++++---
>   chardev/msmouse.c        |  3 ++-
>   chardev/spice.c          | 13 ++++++++-----
>   chardev/wctablet.c       |  3 ++-
>   gdbstub/system.c         |  3 ++-
>   include/chardev/char.h   |  2 +-
>   ui/console-vc.c          |  3 ++-
>   ui/dbus-chardev.c        |  6 +++---
>   ui/gtk.c                 |  5 +++--
>   ui/spice-app.c           | 10 ++++++----
>   ui/vdagent.c             | 10 +++++-----
>   25 files changed, 113 insertions(+), 82 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 8/8] chardev/char: qemu_char_open(): add return value
  2025-11-29 13:43 ` [PATCH 8/8] chardev/char: qemu_char_open(): add return value Vladimir Sementsov-Ogievskiy
@ 2025-11-29 14:17   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-29 14:17 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, marcandre.lureau
  Cc: pbonzini, qemu-devel, d-tatianin

On 29/11/25 14:43, Vladimir Sementsov-Ogievskiy wrote:
> Accordingly with recommendations in include/qapi/error.h accompany
> errp by boolean return value and get rid of error propagation.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>   chardev/char.c | 15 +++++++--------
>   1 file changed, 7 insertions(+), 8 deletions(-)


> -    if (cc->chr_open) {
> -        cc->chr_open(chr, backend, errp);
> +    if (cc->chr_open && !cc->chr_open(chr, backend, errp)) {
> +        return false;
>       }
> +
> +    return true;
>   }

Alternatively:

     if (!cc->chr_open) {
         return true;
     }
     return cc->chr_open(chr, backend, errp);

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter
  2025-11-29 13:43 ` [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter Vladimir Sementsov-Ogievskiy
@ 2025-12-01 12:57   ` Marc-André Lureau
  2025-12-04 13:34     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 1 reply; 15+ messages in thread
From: Marc-André Lureau @ 2025-12-01 12:57 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy
  Cc: pbonzini, qemu-devel, d-tatianin, Samuel Thibault,
	Alex Bennée, Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 29236 bytes --]

Hi

On Sat, Nov 29, 2025 at 5:44 PM Vladimir Sementsov-Ogievskiy <
vsementsov@yandex-team.ru> wrote:

> The logic around the parameter is rather tricky. Let's instead
> explicitly send CHR_EVENT_OPENED in all bakends where needed.
>

backends

I like the general idea, I wonder if I miss something though


>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  chardev/baum.c           |  7 +++----
>  chardev/char-console.c   |  5 ++---
>  chardev/char-file.c      |  7 +++----
>  chardev/char-hub.c       | 11 +++++------
>  chardev/char-mux.c       | 19 +++++++++++--------
>  chardev/char-null.c      |  7 ++-----
>  chardev/char-parallel.c  | 15 ++++-----------
>  chardev/char-pipe.c      | 14 ++++++--------
>  chardev/char-pty.c       |  6 +-----
>  chardev/char-ringbuf.c   |  3 ++-
>  chardev/char-serial.c    | 18 +++++++++---------
>  chardev/char-socket.c    | 10 +++-------
>  chardev/char-stdio.c     |  7 +++----
>  chardev/char-udp.c       |  6 +-----
>  chardev/char-win-stdio.c |  2 +-
>  chardev/char.c           | 11 +++--------
>  chardev/msmouse.c        |  4 ++--
>  chardev/spice.c          | 13 ++++---------
>  chardev/wctablet.c       |  5 ++---
>  gdbstub/system.c         |  5 ++---
>  include/chardev/char.h   |  3 +--
>  ui/console-vc.c          |  7 ++-----
>  ui/dbus-chardev.c        |  6 ++----
>  ui/gtk.c                 |  9 +++------
>  ui/spice-app.c           | 10 +++-------
>  ui/vdagent.c             |  3 +--
>  26 files changed, 81 insertions(+), 132 deletions(-)
>
> diff --git a/chardev/baum.c b/chardev/baum.c
> index 6b81c97d10..58b74dc98d 100644
> --- a/chardev/baum.c
> +++ b/chardev/baum.c
> @@ -642,10 +642,7 @@ static void char_braille_finalize(Object *obj)
>      }
>  }
>
> -static void baum_chr_open(Chardev *chr,
> -                          ChardevBackend *backend,
> -                          bool *be_opened,
> -                          Error **errp)
> +static void baum_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      BaumChardev *baum = BAUM_CHARDEV(chr);
>      brlapi_handle_t *handle;
> @@ -670,6 +667,8 @@ static void baum_chr_open(Chardev *chr,
>       * as an integer, but in practice it seems to work
>       */
>      qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void char_braille_class_init(ObjectClass *oc, const void *data)
> diff --git a/chardev/char-console.c b/chardev/char-console.c
> index f3ef1a7748..423f0f4cc4 100644
> --- a/chardev/char-console.c
> +++ b/chardev/char-console.c
> @@ -26,12 +26,11 @@
>  #include "chardev/char-win.h"
>  #include "qemu/module.h"
>
> -static void console_chr_open(Chardev *chr,
> -                             ChardevBackend *backend,
> -                             bool *be_opened,
> +static void console_chr_open(Chardev *chr, ChardevBackend *backend,
>                               Error **errp)
>  {
>      win_chr_set_file(chr, GetStdHandle(STD_OUTPUT_HANDLE), true);
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void char_console_class_init(ObjectClass *oc, const void *data)
> diff --git a/chardev/char-file.c b/chardev/char-file.c
> index 568600bb7c..34ef386abc 100644
> --- a/chardev/char-file.c
> +++ b/chardev/char-file.c
> @@ -34,10 +34,7 @@
>  #include "chardev/char-fd.h"
>  #endif
>
> -static void file_chr_open(Chardev *chr,
> -                          ChardevBackend *backend,
> -                          bool *be_opened,
> -                          Error **errp)
> +static void file_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevFile *file = backend->u.file.data;
>  #ifdef _WIN32
> @@ -100,6 +97,8 @@ static void file_chr_open(Chardev *chr,
>          return;
>      }
>  #endif
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void file_chr_parse(QemuOpts *opts, ChardevBackend *backend,
> diff --git a/chardev/char-hub.c b/chardev/char-hub.c
> index 11556dfa72..aa6058c2f6 100644
> --- a/chardev/char-hub.c
> +++ b/chardev/char-hub.c
> @@ -203,10 +203,7 @@ static void hub_chr_update_read_handlers(Chardev *chr)
>      }
>  }
>
> -static void hub_chr_open(Chardev *chr,
> -                         ChardevBackend *backend,
> -                         bool *be_opened,
> -                         Error **errp)
> +static void hub_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevHub *hub = backend->u.hub.data;
>      HubChardev *d = HUB_CHARDEV(chr);
> @@ -241,8 +238,10 @@ static void hub_chr_open(Chardev *chr,
>          list = list->next;
>      }
>
> -    /* Closed until an explicit event from backend */
> -    *be_opened = false;
> +    /*
> +     * Closed until an explicit event from backend, so we don't
> +     * send CHR_EVENT_OPENED now.
> +     */
>  }
>
>  static void hub_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error
> **errp)
> diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> index f38d66b21f..7210df431f 100644
> --- a/chardev/char-mux.c
> +++ b/chardev/char-mux.c
> @@ -361,10 +361,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
>      mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
>  }
>
> -static void mux_chr_open(Chardev *chr,
> -                         ChardevBackend *backend,
> -                         bool *be_opened,
> -                         Error **errp)
> +static void mux_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevMux *mux = backend->u.mux.data;
>      Chardev *drv;
> @@ -377,11 +374,17 @@ static void mux_chr_open(Chardev *chr,
>      }
>
>      d->focus = -1;
> -    /* only default to opened state if we've realized the initial
> -     * set of muxes
> +    if (!qemu_chr_fe_init(&d->chr, drv, errp)) {
> +        return;
> +    }
> +
> +    /*
> +     * Only move to opened state if we've realized
> +     * the initial set of muxes:
>       */
> -    *be_opened = muxes_opened;
> -    qemu_chr_fe_init(&d->chr, drv, errp);
> +    if (muxes_opened) {
> +        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
> +    }
>  }
>
>  static void mux_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error
> **errp)
> diff --git a/chardev/char-null.c b/chardev/char-null.c
> index 674603b380..900b5febb6 100644
> --- a/chardev/char-null.c
> +++ b/chardev/char-null.c
> @@ -26,12 +26,9 @@
>  #include "chardev/char.h"
>  #include "qemu/module.h"
>
> -static void null_chr_open(Chardev *chr,
> -                          ChardevBackend *backend,
> -                          bool *be_opened,
> -                          Error **errp)
> +static void null_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
> -    *be_opened = false;
> +    /* do not send CHR_EVENT_OPENED */
>  }
>
>  static void char_null_class_init(ObjectClass *oc, const void *data)
> diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
> index 1be1ef4629..359efa3c9c 100644
> --- a/chardev/char-parallel.c
> +++ b/chardev/char-parallel.c
> @@ -157,10 +157,7 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd,
> void *arg)
>      return 0;
>  }
>
> -static void parallel_chr_open_fd(Chardev *chr,
> -                                int fd,
> -                                bool *be_opened,
> -                                Error **errp)
> +static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
>  {
>      ParallelChardev *drv = PARALLEL_CHARDEV(chr);
>
> @@ -172,6 +169,7 @@ static void parallel_chr_open_fd(Chardev *chr,
>      }
>
>      drv->mode = IEEE1284_MODE_COMPAT;
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>  #endif /* __linux__ */
>
> @@ -227,21 +225,16 @@ static int parallel_chr_ioctl(Chardev *chr, int cmd,
> void *arg)
>      return 0;
>  }
>
> -static void parallel_chr_open_fd(Chardev *chr,
> -                                int fd,
> -                                bool *be_opened,
> -                                Error **errp)
> +static void parallel_chr_open_fd(Chardev *chr, int fd, Error **errp)
>  {
>      ParallelChardev *drv = PARALLEL_CHARDEV(chr);
>      drv->fd = fd;
> -    *be_opened = false;
>  }
>  #endif
>
>  #ifdef HAVE_CHARDEV_PARALLEL
>  static void parallel_chr_open(Chardev *chr,
>                                ChardevBackend *backend,
> -                              bool *be_opened,
>                                Error **errp)
>  {
>      ChardevHostdev *parallel = backend->u.parallel.data;
> @@ -251,7 +244,7 @@ static void parallel_chr_open(Chardev *chr,
>      if (fd < 0) {
>          return;
>      }
> -    parallel_chr_open_fd(chr, fd, be_opened, errp);
> +    parallel_chr_open_fd(chr, fd, errp);
>  }
>
>  static void parallel_chr_parse(QemuOpts *opts, ChardevBackend *backend,
> diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c
> index e84492d42b..2f26372dfc 100644
> --- a/chardev/char-pipe.c
> +++ b/chardev/char-pipe.c
> @@ -103,10 +103,7 @@ static int win_chr_pipe_init(Chardev *chr, const char
> *filename,
>      return -1;
>  }
>
> -static void pipe_chr_open(Chardev *chr,
> -                          ChardevBackend *backend,
> -                          bool *be_opened,
> -                          Error **errp)
> +static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevHostdev *opts = backend->u.pipe.data;
>      const char *filename = opts->device;
> @@ -114,14 +111,13 @@ static void pipe_chr_open(Chardev *chr,
>      if (win_chr_pipe_init(chr, filename, errp) < 0) {
>          return;
>      }
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  #else
>
> -static void pipe_chr_open(Chardev *chr,
> -                          ChardevBackend *backend,
> -                          bool *be_opened,
> -                          Error **errp)
> +static void pipe_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevHostdev *opts = backend->u.pipe.data;
>      int fd_in, fd_out;
> @@ -158,6 +154,8 @@ static void pipe_chr_open(Chardev *chr,
>          }
>          return;
>      }
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  #endif /* !_WIN32 */
> diff --git a/chardev/char-pty.c b/chardev/char-pty.c
> index 909ab01f5f..d4d69a29a9 100644
> --- a/chardev/char-pty.c
> +++ b/chardev/char-pty.c
> @@ -331,10 +331,7 @@ static int qemu_openpty_raw(int *aslave, char
> *pty_name)
>      return amaster;
>  }
>
> -static void pty_chr_open(Chardev *chr,
> -                         ChardevBackend *backend,
> -                         bool *be_opened,
> -                         Error **errp)
> +static void pty_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      PtyChardev *s;
>      int master_fd, slave_fd;
> @@ -364,7 +361,6 @@ static void pty_chr_open(Chardev *chr,
>      qio_channel_set_name(s->ioc, name);
>      g_free(name);
>      s->timer_src = NULL;
> -    *be_opened = false;
>
>      /* create symbolic link */
>      if (path) {
> diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
> index 19652fe2b3..30b17a96d3 100644
> --- a/chardev/char-ringbuf.c
> +++ b/chardev/char-ringbuf.c
> @@ -94,7 +94,6 @@ static void char_ringbuf_finalize(Object *obj)
>
>  static void ringbuf_chr_open(Chardev *chr,
>                               ChardevBackend *backend,
> -                             bool *be_opened,
>                               Error **errp)
>  {
>      ChardevRingbuf *opts = backend->u.ringbuf.data;
> @@ -111,6 +110,8 @@ static void ringbuf_chr_open(Chardev *chr,
>      d->prod = 0;
>      d->cons = 0;
>      d->cbuf = g_malloc0(d->size);
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  void qmp_ringbuf_write(const char *device, const char *data,
> diff --git a/chardev/char-serial.c b/chardev/char-serial.c
> index 54c2b3935c..9995f18425 100644
> --- a/chardev/char-serial.c
> +++ b/chardev/char-serial.c
> @@ -41,14 +41,15 @@
>
>  #ifdef _WIN32
>
> -static void serial_chr_open(Chardev *chr,
> -                            ChardevBackend *backend,
> -                            bool *be_opened,
> -                            Error **errp)
> +static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevHostdev *serial = backend->u.serial.data;
> +    int ret = win_chr_serial_init(chr, serial->device, errp);
> +    if (ret < 0) {
> +        return;
> +    }
>
> -    win_chr_serial_init(chr, serial->device, errp);
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  #elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__)
> \
> @@ -258,10 +259,7 @@ static int serial_chr_ioctl(Chardev *chr, int cmd,
> void *arg)
>      return 0;
>  }
>
> -static void serial_chr_open(Chardev *chr,
> -                            ChardevBackend *backend,
> -                            bool *be_opened,
> -                            Error **errp)
> +static void serial_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevHostdev *serial = backend->u.serial.data;
>      int fd;
> @@ -281,6 +279,8 @@ static void serial_chr_open(Chardev *chr,
>          close(fd);
>          return;
>      }
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>  #endif /* __linux__ || __sun__ */
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index 329cd9f0a8..3f57ef4016 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -1365,10 +1365,7 @@ static bool
> qmp_chardev_validate_socket(ChardevSocket *sock,
>  }
>
>
> -static void tcp_chr_open(Chardev *chr,
> -                         ChardevBackend *backend,
> -                         bool *be_opened,
> -                         Error **errp)
> +static void tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      SocketChardev *s = SOCKET_CHARDEV(chr);
>      ChardevSocket *sock = backend->u.socket.data;
> @@ -1439,9 +1436,6 @@ static void tcp_chr_open(Chardev *chr,
>      }
>      s->registered_yank = true;
>
> -    /* be isn't opened until we get a connection */
> -    *be_opened = false;
> -
>      update_disconnected_filename(s);
>
>      if (s->is_listen) {
> @@ -1454,6 +1448,8 @@ static void tcp_chr_open(Chardev *chr,
>              return;
>          }
>      }
> +
> +    /* be isn't opened until we get a connection */
>  }
>
>  static void tcp_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error
> **errp)
> diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
> index f0920a23fa..534f6ed565 100644
> --- a/chardev/char-stdio.c
> +++ b/chardev/char-stdio.c
> @@ -85,10 +85,7 @@ static void term_stdio_handler(int sig)
>      stdio_chr_set_echo(NULL, stdio_echo_state);
>  }
>
> -static void stdio_chr_open(Chardev *chr,
> -                           ChardevBackend *backend,
> -                           bool *be_opened,
> -                           Error **errp)
> +static void stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevStdio *opts = backend->u.stdio.data;
>      struct sigaction act;
> @@ -123,6 +120,8 @@ static void stdio_chr_open(Chardev *chr,
>
>      stdio_allow_signal = !opts->has_signal || opts->signal;
>      stdio_chr_set_echo(chr, false);
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>  #endif
>
> diff --git a/chardev/char-udp.c b/chardev/char-udp.c
> index 099f76b8c2..b835a967e1 100644
> --- a/chardev/char-udp.c
> +++ b/chardev/char-udp.c
> @@ -188,10 +188,7 @@ static void udp_chr_parse(QemuOpts *opts,
> ChardevBackend *backend, Error **errp)
>      }
>  }
>
> -static void upd_chr_open(Chardev *chr,
> -                         ChardevBackend *backend,
> -                         bool *be_opened,
> -                         Error **errp)
> +static void upd_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevUdp *udp = backend->u.udp.data;
>      SocketAddress *local_addr = socket_address_flatten(udp->local);
> @@ -215,7 +212,6 @@ static void upd_chr_open(Chardev *chr,
>
>      s->ioc = QIO_CHANNEL(sioc);
>      /* be isn't opened until we get a connection */
> -    *be_opened = false;
>  }
>
>  static void char_udp_class_init(ObjectClass *oc, const void *data)
> diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
> index 866f3a2039..0535960ff1 100644
> --- a/chardev/char-win-stdio.c
> +++ b/chardev/char-win-stdio.c
> @@ -144,7 +144,6 @@ static void win_stiod_chr_set_echo(Chardev *chr, bool
> echo)
>
>  static void win_stdio_chr_open(Chardev *chr,
>                                 ChardevBackend *backend,
> -                               bool *be_opened,
>                                 Error **errp)
>  {
>      ChardevStdio *opts = backend->u.stdio.data;
> @@ -208,6 +207,7 @@ static void win_stdio_chr_open(Chardev *chr,
>
>      win_stiod_chr_set_echo(chr, false);
>
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>      return;
>
>  err3:
> diff --git a/chardev/char.c b/chardev/char.c
> index df37d1df16..44bfed3627 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -246,8 +246,7 @@ int qemu_chr_add_client(Chardev *s, int fd)
>          CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
>  }
>
> -static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
> -                           bool *be_opened, Error **errp)
> +static void qemu_char_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevClass *cc = CHARDEV_GET_CLASS(chr);
>      /* Any ChardevCommon member would work */
> @@ -268,7 +267,7 @@ static void qemu_char_open(Chardev *chr,
> ChardevBackend *backend,
>      }
>
>      if (cc->chr_open) {
> -        cc->chr_open(chr, backend, be_opened, errp);
> +        cc->chr_open(chr, backend, errp);
>      }
>  }
>
> @@ -1009,7 +1008,6 @@ static Chardev *chardev_new(const char *id, const
> char *typename,
>      Object *obj;
>      Chardev *chr = NULL;
>      Error *local_err = NULL;
> -    bool be_opened = true;
>
>      assert(g_str_has_prefix(typename, "chardev-"));
>      assert(id);
> @@ -1020,7 +1018,7 @@ static Chardev *chardev_new(const char *id, const
> char *typename,
>      chr->label = g_strdup(id);
>      chr->gcontext = gcontext;
>
> -    qemu_char_open(chr, backend, &be_opened, &local_err);
> +    qemu_char_open(chr, backend, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          object_unref(obj);
> @@ -1030,9 +1028,6 @@ static Chardev *chardev_new(const char *id, const
> char *typename,
>      if (!chr->filename) {
>          chr->filename = g_strdup(typename + 8);
>      }
> -    if (be_opened) {
> -        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
> -    }
>
>      return chr;
>  }
> diff --git a/chardev/msmouse.c b/chardev/msmouse.c
> index d07cd998cb..9dc04e3b3e 100644
> --- a/chardev/msmouse.c
> +++ b/chardev/msmouse.c
> @@ -255,16 +255,16 @@ static void char_msmouse_finalize(Object *obj)
>
>  static void msmouse_chr_open(Chardev *chr,
>                               ChardevBackend *backend,
> -                             bool *be_opened,
>                               Error **errp)
>  {
>      MouseChardev *mouse = MOUSE_CHARDEV(chr);
>
> -    *be_opened = false;
>      mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
>                                              &msmouse_handler);
>      mouse->tiocm = 0;
>      fifo8_create(&mouse->outbuf, MSMOUSE_BUF_SZ);
> +
> +    /* Never send CHR_EVENT_OPENED */
>  }
>
>  static void char_msmouse_class_init(ObjectClass *oc, const void *data)
> diff --git a/chardev/spice.c b/chardev/spice.c
> index 800784da26..612f358885 100644
> --- a/chardev/spice.c
> +++ b/chardev/spice.c
> @@ -251,9 +251,7 @@ static void chr_open(Chardev *chr, const char *subtype)
>      s->sin.subtype = g_strdup(subtype);
>  }
>
> -static void spice_vmc_chr_open(Chardev *chr,
> -                               ChardevBackend *backend,
> -                               bool *be_opened,
> +static void spice_vmc_chr_open(Chardev *chr, ChardevBackend *backend,
>                                 Error **errp)
>  {
>      ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
> @@ -277,19 +275,17 @@ static void spice_vmc_chr_open(Chardev *chr,
>          return;
>      }
>
> -    *be_opened = false;
>  #if SPICE_SERVER_VERSION < 0x000e02
>      /* Spice < 0.14.2 doesn't explicitly open smartcard chardev */
>      if (strcmp(type, "smartcard") == 0) {
> -        *be_opened = true;
> +        chr_open(chr, type);
> +        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>      }
>  #endi


Can you add a preliminary patch to drop support for spice < 0.15 ?
According to repology:
debian_13: 0.15.2
fedora_42: 0.15.1
opensuse_leap_15_4: 0.15.0
ubuntu_22_04: 0.15.0




> f
>      chr_open(chr, type);
>  }
>
> -static void spice_port_chr_open(Chardev *chr,
> -                                ChardevBackend *backend,
> -                                bool *be_opened,
> +static void spice_port_chr_open(Chardev *chr, ChardevBackend *backend,
>                                  Error **errp)
>  {
>      ChardevSpicePort *spiceport = backend->u.spiceport.data;
> @@ -308,7 +304,6 @@ static void spice_port_chr_open(Chardev *chr,
>
>      chr_open(chr, "port");
>
> -    *be_opened = false;
>      s = SPICE_CHARDEV(chr);
>      s->sin.portname = g_strdup(name);
>
> diff --git a/chardev/wctablet.c b/chardev/wctablet.c
> index 8285a56e7b..65b2ceb58c 100644
> --- a/chardev/wctablet.c
> +++ b/chardev/wctablet.c
> @@ -326,13 +326,10 @@ static void wctablet_chr_finalize(Object *obj)
>
>  static void wctablet_chr_open(Chardev *chr,
>                                ChardevBackend *backend,
> -                              bool *be_opened,
>                                Error **errp)
>  {
>      TabletChardev *tablet = WCTABLET_CHARDEV(chr);
>
> -    *be_opened = true;
> -
>      /* init state machine */
>      memcpy(tablet->outbuf, WC_FULL_CONFIG_STRING,
> WC_FULL_CONFIG_STRING_LENGTH);
>      tablet->outlen = WC_FULL_CONFIG_STRING_LENGTH;
> @@ -340,6 +337,8 @@ static void wctablet_chr_open(Chardev *chr,
>
>      tablet->hs = qemu_input_handler_register((DeviceState *)tablet,
>                                               &wctablet_handler);
> +
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void wctablet_chr_class_init(ObjectClass *oc, const void *data)
> diff --git a/gdbstub/system.c b/gdbstub/system.c
> index 61b2b4b8da..49da1f73cc 100644
> --- a/gdbstub/system.c
> +++ b/gdbstub/system.c
> @@ -233,10 +233,9 @@ static int gdb_chr_write(Chardev *chr, const uint8_t
> *buf, int len)
>      return len;
>  }
>
> -static void gdb_chr_open(Chardev *chr, ChardevBackend *backend,
> -                             bool *be_opened, Error **errp)
> +static void gdb_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
> -    *be_opened = false;
> +    /* Never send CHR_EVENT_OPENED */
>  }
>
>  static void char_gdb_class_init(ObjectClass *oc, const void *data)
> diff --git a/include/chardev/char.h b/include/chardev/char.h
> index 2baf2a8a1a..47c75c3582 100644
> --- a/include/chardev/char.h
> +++ b/include/chardev/char.h
> @@ -260,8 +260,7 @@ struct ChardevClass {
>      void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error
> **errp);
>
>      /* called after construction, open/starts the backend */
> -    void (*chr_open)(Chardev *chr, ChardevBackend *backend,
> -                 bool *be_opened, Error **errp);
> +    void (*chr_open)(Chardev *chr, ChardevBackend *backend, Error **errp);
>
>      /* write buf to the backend */
>      int (*chr_write)(Chardev *s, const uint8_t *buf, int len);
> diff --git a/ui/console-vc.c b/ui/console-vc.c
> index 931068d43a..4c8ea4c148 100644
> --- a/ui/console-vc.c
> +++ b/ui/console-vc.c
> @@ -1093,10 +1093,7 @@ void qemu_text_console_update_size(QemuTextConsole
> *c)
>      dpy_text_resize(QEMU_CONSOLE(c), c->width, c->height);
>  }
>
> -static void vc_chr_open(Chardev *chr,
> -                        ChardevBackend *backend,
> -                        bool *be_opened,
> -                        Error **errp)
> +static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ChardevVC *vc = backend->u.vc.data;
>      VCChardev *drv = VC_CHARDEV(chr);
> @@ -1144,7 +1141,7 @@ static void vc_chr_open(Chardev *chr,
>          drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
>      }
>
> -    *be_opened = true;
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error
> **errp)
> diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c
> index f6c426e220..3e471f84cd 100644
> --- a/ui/dbus-chardev.c
> +++ b/ui/dbus-chardev.c
> @@ -176,9 +176,7 @@ dbus_chr_send_break(
>      return DBUS_METHOD_INVOCATION_HANDLED;
>  }
>
> -static void
> -dbus_chr_open(Chardev *chr, ChardevBackend *backend,
> -              bool *be_opened, Error **errp)
> +static void dbus_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      ERRP_GUARD();
>
> @@ -211,7 +209,7 @@ dbus_chr_open(Chardev *chr, ChardevBackend *backend,
>          return;
>      }
>      CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_SOCKET))->chr_open(
> -        chr, be, be_opened, errp);
> +        chr, be, errp);
>  }
>
>  static void
> diff --git a/ui/gtk.c b/ui/gtk.c
> index b5498a7ce3..3eeb5baa11 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -1963,10 +1963,7 @@ static void gd_vc_chr_set_echo(Chardev *chr, bool
> echo)
>
>  static int nb_vcs;
>  static Chardev *vcs[MAX_VCS];
> -static void gd_vc_chr_open(Chardev *chr,
> -                       ChardevBackend *backend,
> -                       bool *be_opened,
> -                       Error **errp)
> +static void gd_vc_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      if (nb_vcs == MAX_VCS) {
>          error_setg(errp, "Maximum number of consoles reached");
> @@ -1975,10 +1972,10 @@ static void gd_vc_chr_open(Chardev *chr,
>
>      vcs[nb_vcs++] = chr;
>
> -    /* console/chardev init sometimes completes elsewhere in a 2nd
> +    /*
> +     * console/chardev init sometimes completes elsewhere in a 2nd
>       * stage, so defer OPENED events until they are fully initialized
>       */
> -    *be_opened = false;
>  }
>
>  static void char_gd_vc_class_init(ObjectClass *oc, const void *data)
> diff --git a/ui/spice-app.c b/ui/spice-app.c
> index ea0b62a22b..7ac9ae4e78 100644
> --- a/ui/spice-app.c
> +++ b/ui/spice-app.c
> @@ -49,8 +49,7 @@ struct VCChardev {
>
>  struct VCChardevClass {
>      ChardevClass parent;
> -    void (*parent_open)(Chardev *chr, ChardevBackend *backend,
> -                        bool *be_opened, Error **errp);
> +    void (*parent_open)(Chardev *chr, ChardevBackend *backend, Error
> **errp);
>  };
>
>  #define TYPE_CHARDEV_VC "chardev-vc"
> @@ -67,10 +66,7 @@ chr_spice_backend_new(void)
>      return be;
>  }
>
> -static void vc_chr_open(Chardev *chr,
> -                        ChardevBackend *backend,
> -                        bool *be_opened,
> -                        Error **errp)
> +static void vc_chr_open(Chardev *chr, ChardevBackend *backend, Error
> **errp)
>  {
>      VCChardevClass *vc = CHARDEV_VC_GET_CLASS(chr);
>      ChardevBackend *be;
> @@ -87,7 +83,7 @@ static void vc_chr_open(Chardev *chr,
>      be = chr_spice_backend_new();
>      be->u.spiceport.data->fqdn = fqdn ?
>          g_strdup(fqdn) : g_strdup_printf("org.qemu.console.%s",
> chr->label);
> -    vc->parent_open(chr, be, be_opened, errp);
> +    vc->parent_open(chr, be, errp);
>      qapi_free_ChardevBackend(be);
>  }
>
> diff --git a/ui/vdagent.c b/ui/vdagent.c
> index 9972a9c476..3becc6c076 100644
> --- a/ui/vdagent.c
> +++ b/ui/vdagent.c
> @@ -662,7 +662,6 @@ static void vdagent_chr_recv_clipboard(VDAgentChardev
> *vd, VDAgentMessage *msg)
>
>  static void vdagent_chr_open(Chardev *chr,
>                               ChardevBackend *backend,
> -                             bool *be_opened,
>                               Error **errp)
>  {
>      VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
> @@ -692,7 +691,7 @@ static void vdagent_chr_open(Chardev *chr,
>
> &vdagent_mouse_handler);
>      }
>
> -    *be_opened = true;
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void vdagent_clipboard_peer_register(VDAgentChardev *vd)
> --
> 2.48.1
>
>

[-- Attachment #2: Type: text/html, Size: 34238 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH for-11.0 0/8] chardev: cleanup
  2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
                   ` (7 preceding siblings ...)
  2025-11-29 13:43 ` [PATCH 8/8] chardev/char: qemu_char_open(): add return value Vladimir Sementsov-Ogievskiy
@ 2025-12-01 13:00 ` Marc-André Lureau
  8 siblings, 0 replies; 15+ messages in thread
From: Marc-André Lureau @ 2025-12-01 13:00 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy; +Cc: pbonzini, qemu-devel, d-tatianin

[-- Attachment #1: Type: text/plain, Size: 3045 bytes --]

Hi

On Sat, Nov 29, 2025 at 5:44 PM Vladimir Sementsov-Ogievskiy <
vsementsov@yandex-team.ru> wrote:

> Hi all.
>
> Here is a cleanup for chardev code:
>
>  - improve naming
>  - add boolean return for some errp-functions
>  - simplify open() API
>
> Vladimir Sementsov-Ogievskiy (8):
>   chardev: ChardevClass: consistent naming for handlers
>   chardev: consistent naming for ChardevClass handlers implementations
>   chardev: .chr_open(): drop be_opened parameter
>   chardev: .chr_open(): add boolean return value
>   chardev/char-pty: store pty_name into PtyChardev state
>   chardev: introduce .chr_get_pty_name() handler
>   chardev: rework filename handling
>   chardev/char: qemu_char_open(): add return value
>

Except 3rd patch, lgtm. (it conflicts a bit with "[PATCH v3 00/10] chardev:
Improve @docstring and clarify qemu_chr_write() uses
<https://patchew.org/QEMU/20251112134143.27194-1-philmd@linaro.org/>"
though, I guess I will handle that)


>
>  chardev/baum.c                                | 12 ++--
>  chardev/char-console.c                        | 10 ++--
>  chardev/char-fe.c                             |  8 +--
>  chardev/char-file.c                           | 26 ++++----
>  chardev/char-hub.c                            | 27 ++++-----
>  chardev/char-mux.c                            | 30 ++++++----
>  chardev/char-null.c                           |  9 +--
>  chardev/char-parallel.c                       | 41 ++++++-------
>  chardev/char-pipe.c                           | 30 +++++-----
>  chardev/char-pty.c                            | 52 ++++++++--------
>  chardev/char-ringbuf.c                        | 20 ++++---
>  chardev/char-serial.c                         | 39 ++++++------
>  chardev/char-socket.c                         | 59 +++++++++----------
>  chardev/char-stdio.c                          | 30 +++++-----
>  chardev/char-udp.c                            | 16 ++---
>  chardev/char-win-stdio.c                      | 25 ++++----
>  chardev/char.c                                | 51 ++++++++--------
>  chardev/msmouse.c                             | 13 ++--
>  chardev/spice.c                               | 50 ++++++++--------
>  chardev/wctablet.c                            | 10 ++--
>  gdbstub/system.c                              | 12 ++--
>  hw/char/xen_console.c                         |  7 ++-
>  hw/misc/ivshmem-pci.c                         |  4 +-
>  include/chardev/char.h                        | 37 +++++++++---
>  .../codeconverter/test_regexps.py             |  2 +-
>  ui/console-vc.c                               | 12 ++--
>  ui/dbus-chardev.c                             | 16 +++--
>  ui/dbus.c                                     |  4 +-
>  ui/gtk.c                                      | 14 ++---
>  ui/spice-app.c                                | 18 +++---
>  ui/vdagent.c                                  | 17 +++---
>  31 files changed, 354 insertions(+), 347 deletions(-)
>
> --
> 2.48.1
>
>

[-- Attachment #2: Type: text/html, Size: 4245 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter
  2025-12-01 12:57   ` Marc-André Lureau
@ 2025-12-04 13:34     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2025-12-04 13:34 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: pbonzini, qemu-devel, d-tatianin, Samuel Thibault,
	Alex Bennée, Philippe Mathieu-Daudé

On 01.12.25 15:57, Marc-André Lureau wrote:
>       {
>           ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
>     @@ -277,19 +275,17 @@ static void spice_vmc_chr_open(Chardev *chr,
>               return;
>           }
> 
>     -    *be_opened = false;
>       #if SPICE_SERVER_VERSION < 0x000e02
>           /* Spice < 0.14.2 doesn't explicitly open smartcard chardev */
>           if (strcmp(type, "smartcard") == 0) {
>     -        *be_opened = true;
>     +        chr_open(chr, type);
>     +        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>           }
>       #endi
> 
> 
> Can you add a preliminary patch to drop support for spice < 0.15 ?
> According to repology:
> debian_13: 0.15.2
> fedora_42: 0.15.1
> opensuse_leap_15_4: 0.15.0
> ubuntu_22_04: 0.15.0


Will do. Thanks for reviewing!

-- 
Best regards,
Vladimir


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-12-04 13:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-29 13:43 [PATCH for-11.0 0/8] chardev: cleanup Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 1/8] chardev: ChardevClass: consistent naming for handlers Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 2/8] chardev: consistent naming for ChardevClass handlers implementations Vladimir Sementsov-Ogievskiy
2025-11-29 14:07   ` Philippe Mathieu-Daudé
2025-11-29 13:43 ` [PATCH 3/8] chardev: .chr_open(): drop be_opened parameter Vladimir Sementsov-Ogievskiy
2025-12-01 12:57   ` Marc-André Lureau
2025-12-04 13:34     ` Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 4/8] chardev: .chr_open(): add boolean return value Vladimir Sementsov-Ogievskiy
2025-11-29 14:08   ` Philippe Mathieu-Daudé
2025-11-29 13:43 ` [PATCH 5/8] chardev/char-pty: store pty_name into PtyChardev state Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 6/8] chardev: introduce .chr_get_pty_name() handler Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 7/8] chardev: rework filename handling Vladimir Sementsov-Ogievskiy
2025-11-29 13:43 ` [PATCH 8/8] chardev/char: qemu_char_open(): add return value Vladimir Sementsov-Ogievskiy
2025-11-29 14:17   ` Philippe Mathieu-Daudé
2025-12-01 13:00 ` [PATCH for-11.0 0/8] chardev: cleanup Marc-André Lureau

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).