Use a single allocation for CharDriverState, this avoids extra allocations & pointers, and is a step towards more object-oriented CharDriver.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- backends/baum.c | 23 ++--- backends/msmouse.c | 16 +-- backends/testdev.c | 22 ++-- gdbstub.c | 1 + hw/bt/hci-csr.c | 10 +- qemu-char.c | 275 ++++++++++++++++++++++++++------------------------ spice-qemu-char.c | 39 +++---- ui/console.c | 21 ++-- ui/gtk.c | 11 +- include/sysemu/char.h | 2 +- include/ui/gtk.h | 3 + 11 files changed, 215 insertions(+), 208 deletions(-) diff --git a/backends/baum.c b/backends/baum.c index b2d4719..45a6fd4 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -87,7 +87,7 @@ #define BUF_SIZE 256 typedef struct { - CharDriverState *chr; + CharDriverState parent; brlapi_handle_t *brlapi; int brlapi_fd; @@ -219,7 +219,7 @@ static const uint8_t nabcc_translation[256] = { /* The serial port can receive more of our data */ static void baum_accept_input(struct CharDriverState *chr) { - BaumDriverState *baum = chr->opaque; + BaumDriverState *baum = (BaumDriverState *)chr; int room, first; if (!baum->out_buf_used) @@ -245,22 +245,23 @@ static void baum_accept_input(struct CharDriverState *chr) /* We want to send a packet */ static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len) { + CharDriverState *chr = (CharDriverState *)baum; uint8_t io_buf[1 + 2 * len], *cur = io_buf; int room; *cur++ = ESC; while (len--) if ((*cur++ = *buf++) == ESC) *cur++ = ESC; - room = qemu_chr_be_can_write(baum->chr); + room = qemu_chr_be_can_write(chr); len = cur - io_buf; if (len <= room) { /* Fits */ - qemu_chr_be_write(baum->chr, io_buf, len); + qemu_chr_be_write(chr, io_buf, len); } else { int first; uint8_t out; /* Can't fit all, send what can be, and store the rest. */ - qemu_chr_be_write(baum->chr, io_buf, room); + qemu_chr_be_write(chr, io_buf, room); len -= room; cur = io_buf + room; if (len > BUF_SIZE - baum->out_buf_used) { @@ -433,7 +434,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len) /* The other end is writing some data. Store it and try to interpret */ static int baum_write(CharDriverState *chr, const uint8_t *buf, int len) { - BaumDriverState *baum = chr->opaque; + BaumDriverState *baum = (BaumDriverState *)chr; int tocopy, cur, eaten, orig_len = len; if (!len) @@ -553,14 +554,13 @@ static void baum_chr_read(void *opaque) static void baum_free(struct CharDriverState *chr) { - BaumDriverState *baum = chr->opaque; + BaumDriverState *baum = (BaumDriverState *)chr; timer_free(baum->cellCount_timer); if (baum->brlapi) { brlapi__closeConnection(baum->brlapi); g_free(baum->brlapi); } - g_free(baum); } static CharDriverState *chr_baum_init(const CharDriver *driver, @@ -585,10 +585,7 @@ static CharDriverState *chr_baum_init(const CharDriver *driver, if (!chr) { return NULL; } - baum = g_malloc0(sizeof(BaumDriverState)); - baum->chr = chr; - - chr->opaque = baum; + baum = (BaumDriverState *)chr; handle = g_malloc0(brlapi_getHandleSize()); baum->brlapi = handle; @@ -635,7 +632,6 @@ fail: fail_handle: g_free(handle); g_free(chr); - g_free(baum); return NULL; } @@ -643,6 +639,7 @@ static void register_types(void) { static const CharDriver driver = { { "braille" }, CHARDEV_BACKEND_KIND_BRAILLE, NULL, chr_baum_init, + sizeof(BaumDriverState), .chr_write = baum_write, .chr_accept_input = baum_accept_input, .chr_free = baum_free, diff --git a/backends/msmouse.c b/backends/msmouse.c index f71aab0..37e7b82 100644 --- a/backends/msmouse.c +++ b/backends/msmouse.c @@ -31,7 +31,8 @@ #define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6) typedef struct { - CharDriverState *chr; + CharDriverState parent; + QemuInputHandlerState *hs; int axis[INPUT_AXIS__MAX]; bool btns[INPUT_BUTTON__MAX]; @@ -42,7 +43,7 @@ typedef struct { static void msmouse_chr_accept_input(CharDriverState *chr) { - MouseState *mouse = chr->opaque; + MouseState *mouse = (MouseState *)chr; int len; len = qemu_chr_be_can_write(chr); @@ -122,9 +123,10 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src, static void msmouse_input_sync(DeviceState *dev) { MouseState *mouse = (MouseState *)dev; + CharDriverState *chr = (CharDriverState *)dev; msmouse_queue_event(mouse); - msmouse_chr_accept_input(mouse->chr); + msmouse_chr_accept_input(chr); } static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) @@ -135,10 +137,9 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int static void msmouse_chr_free(struct CharDriverState *chr) { - MouseState *mouse = chr->opaque; + MouseState *mouse = (MouseState *)chr; qemu_input_handler_unregister(mouse->hs); - g_free(mouse); } static QemuInputHandler msmouse_handler = { @@ -165,12 +166,10 @@ static CharDriverState *qemu_chr_open_msmouse(const CharDriver *driver, } *be_opened = false; - mouse = g_new0(MouseState, 1); + mouse = (MouseState *)chr; mouse->hs = qemu_input_handler_register((DeviceState *)mouse, &msmouse_handler); - mouse->chr = chr; - chr->opaque = mouse; return chr; } @@ -180,6 +179,7 @@ static void register_types(void) static const CharDriver driver = { { "msmouse" }, CHARDEV_BACKEND_KIND_MSMOUSE, NULL, qemu_chr_open_msmouse, + sizeof(MouseState), .chr_write = msmouse_chr_write, .chr_accept_input = msmouse_chr_accept_input, .chr_free = msmouse_chr_free, diff --git a/backends/testdev.c b/backends/testdev.c index 774cd47..4b1953b 100644 --- a/backends/testdev.c +++ b/backends/testdev.c @@ -30,7 +30,8 @@ #define BUF_SIZE 32 typedef struct { - CharDriverState *chr; + CharDriverState parent; + uint8_t in_buf[32]; int in_buf_used; } TestdevCharState; @@ -79,7 +80,7 @@ static int testdev_eat_packet(TestdevCharState *testdev) /* The other end is writing some data. Store it and try to interpret */ static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len) { - TestdevCharState *testdev = chr->opaque; + TestdevCharState *testdev = (TestdevCharState *)chr; int tocopy, eaten, orig_len = len; while (len) { @@ -102,13 +103,6 @@ static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len) return orig_len; } -static void testdev_free(struct CharDriverState *chr) -{ - TestdevCharState *testdev = chr->opaque; - - g_free(testdev); -} - static CharDriverState *chr_testdev_init(const CharDriver *driver, const char *id, ChardevBackend *backend, @@ -116,14 +110,10 @@ static CharDriverState *chr_testdev_init(const CharDriver *driver, bool *be_opened, Error **errp) { - TestdevCharState *testdev; - CharDriverState *chr; - - testdev = g_new0(TestdevCharState, 1); - testdev->chr = chr = g_new0(CharDriverState, 1); + TestdevCharState *testdev = g_new0(TestdevCharState, 1);; + CharDriverState *chr = (CharDriverState *)testdev; chr->driver = driver; - chr->opaque = testdev; return chr; } @@ -132,8 +122,8 @@ static void register_types(void) { static const CharDriver driver = { { "testdev" }, CHARDEV_BACKEND_KIND_TESTDEV, NULL, chr_testdev_init, + sizeof(TestdevCharState), .chr_write = testdev_write, - .chr_free = testdev_free, }; register_char_driver(&driver); } diff --git a/gdbstub.c b/gdbstub.c index 8e43836..3a9f857 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1732,6 +1732,7 @@ int gdbserver_start(const char *device) CharDriverState *mon_chr; ChardevCommon common = { 0 }; static const CharDriver driver = { + .instance_size = sizeof(CharDriverState), .kind = -1, .chr_write = gdb_monitor_write }; diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 9c3fb3c..bf2deb0 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -28,11 +28,11 @@ #include "hw/bt.h" struct csrhci_s { + CharDriverState chr; int enable; qemu_irq *pins; int pin_state; int modem_state; - CharDriverState chr; #define FIFO_LEN 4096 int out_start; int out_len; @@ -314,7 +314,7 @@ static void csrhci_ready_for_next_inpkt(struct csrhci_s *s) static int csrhci_write(struct CharDriverState *chr, const uint8_t *buf, int len) { - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; + struct csrhci_s *s = (struct csrhci_s *)chr; int total = 0; if (!s->enable) @@ -387,7 +387,7 @@ static void csrhci_out_hci_packet_acl(void *opaque, static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg) { QEMUSerialSetParams *ssp; - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; + struct csrhci_s *s = (struct csrhci_s *) chr; int prev_state = s->modem_state; switch (cmd) { @@ -455,7 +455,7 @@ static void csrhci_pins(void *opaque, int line, int level) qemu_irq *csrhci_pins_get(CharDriverState *chr) { - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; + struct csrhci_s *s = (struct csrhci_s *) chr; return s->pins; } @@ -463,6 +463,7 @@ qemu_irq *csrhci_pins_get(CharDriverState *chr) CharDriverState *uart_hci_init(void) { static const CharDriver hci_driver = { + .instance_size = sizeof(struct csrhci_s), .kind = -1, .chr_write = csrhci_write, .chr_ioctl = csrhci_ioctl, @@ -470,7 +471,6 @@ CharDriverState *uart_hci_init(void) struct csrhci_s *s = (struct csrhci_s *) g_malloc0(sizeof(struct csrhci_s)); - s->chr.opaque = s; s->chr.driver = &hci_driver; s->hci = qemu_next_hci(); diff --git a/qemu-char.c b/qemu-char.c index fe8f717..1da7244 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -165,12 +165,14 @@ static void qemu_chr_free_common(CharDriverState *chr); CharDriverState *qemu_chr_alloc(const CharDriver *driver, ChardevCommon *backend, Error **errp) { - CharDriverState *chr = g_malloc0(sizeof(CharDriverState)); - qemu_mutex_init(&chr->chr_write_lock); + CharDriverState *chr; assert(driver); assert(driver->chr_write); + assert(driver->instance_size >= sizeof(CharDriverState)); + chr = g_malloc0(driver->instance_size); + qemu_mutex_init(&chr->chr_write_lock); if (backend->has_logfile) { int flags = O_WRONLY | O_CREAT; if (backend->has_logappend && @@ -537,6 +539,7 @@ static CharDriverState *qemu_chr_open_null(const CharDriver *driver, static const CharDriver null_driver = { { "null" }, CHARDEV_BACKEND_KIND_NULL, NULL, qemu_chr_open_null, + sizeof(CharDriverState), .chr_write = null_chr_write }; @@ -545,6 +548,7 @@ static const CharDriver null_driver = { #define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */ #define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1) struct MuxDriver { + CharDriverState parent; CharBackend *backends[MAX_MUX]; CharBackend chr; int focus; @@ -567,7 +571,7 @@ struct MuxDriver { /* Called with chr_write_lock held. */ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - MuxDriver *d = chr->opaque; + MuxDriver *d = (MuxDriver *)chr; int ret; if (!d->timestamps) { ret = qemu_chr_fe_write(&d->chr, buf, len); @@ -701,7 +705,7 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) static void mux_chr_accept_input(CharDriverState *chr) { - MuxDriver *d = chr->opaque; + MuxDriver *d = (MuxDriver *)chr; int m = d->focus; CharBackend *be = d->backends[m]; @@ -714,8 +718,7 @@ static void mux_chr_accept_input(CharDriverState *chr) static int mux_chr_can_read(void *opaque) { - CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; + MuxDriver *d = opaque; int m = d->focus; CharBackend *be = d->backends[m]; @@ -733,7 +736,7 @@ static int mux_chr_can_read(void *opaque) static void mux_chr_read(void *opaque, const uint8_t *buf, int size) { CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; + MuxDriver *d = opaque; int m = d->focus; CharBackend *be = d->backends[m]; int i; @@ -753,8 +756,7 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) static void mux_chr_event(void *opaque, int event) { - CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; + MuxDriver *d = opaque; int i; /* Send the event to all registered listeners */ @@ -782,7 +784,7 @@ static void muxes_realize_done(Notifier *notifier, void *unused) QTAILQ_FOREACH(chr, &chardevs, next) { if (qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_MUX) { - MuxDriver *d = chr->opaque; + MuxDriver *d = (MuxDriver *)chr; int i; /* send OPENED to all already-attached FEs */ @@ -804,7 +806,7 @@ static Notifier muxes_realize_notify = { static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) { - MuxDriver *d = s->opaque; + MuxDriver *d = (MuxDriver *)s; CharDriverState *chr = qemu_chr_fe_get_driver(&d->chr); if (!chr->driver->chr_add_watch) { @@ -816,7 +818,7 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) static void mux_chr_free(struct CharDriverState *chr) { - MuxDriver *d = chr->opaque; + MuxDriver *d = (MuxDriver *)chr; int i; for (i = 0; i < d->mux_cnt; i++) { @@ -826,12 +828,11 @@ static void mux_chr_free(struct CharDriverState *chr) } } qemu_chr_fe_deinit(&d->chr); - g_free(d); } static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context) { - MuxDriver *d = chr->opaque; + MuxDriver *d = (MuxDriver *)chr; /* Fix up the real driver with mux routines */ qemu_chr_fe_set_handlers(&d->chr, @@ -877,9 +878,7 @@ static CharDriverState *qemu_chr_open_mux(const CharDriver *driver, if (!chr) { return NULL; } - d = g_new0(MuxDriver, 1); - - chr->opaque = d; + d = (MuxDriver *)chr; d->focus = -1; /* only default to opened state if we've realized the initial * set of muxes @@ -908,7 +907,7 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp) assert(s); if (qemu_chr_get_kind(s) == CHARDEV_BACKEND_KIND_MUX) { - MuxDriver *d = s->opaque; + MuxDriver *d = (MuxDriver *)s; if (d->mux_cnt >= MAX_MUX) { goto unavailable; @@ -940,7 +939,7 @@ void qemu_chr_fe_deinit(CharBackend *b) qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL, true); b->chr->be = NULL; if (qemu_chr_get_kind(b->chr) == CHARDEV_BACKEND_KIND_MUX) { - MuxDriver *d = b->chr->opaque; + MuxDriver *d = (MuxDriver *)b->chr; d->backends[b->tag] = NULL; } b->chr = NULL; @@ -1006,7 +1005,7 @@ void qemu_chr_fe_take_focus(CharBackend *b) } if (qemu_chr_get_kind(b->chr) == CHARDEV_BACKEND_KIND_MUX) { - mux_set_focus(b->chr->opaque, b->tag); + mux_set_focus((MuxDriver *)b->chr, b->tag); } } @@ -1178,6 +1177,7 @@ static int io_channel_send(QIOChannel *ioc, const void *buf, size_t len) typedef struct FDCharDriver { + CharDriverState parent; CharDriverState *chr; QIOChannel *ioc_in, *ioc_out; int max_size; @@ -1186,15 +1186,15 @@ typedef struct FDCharDriver { /* Called with chr_write_lock held. */ static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - FDCharDriver *s = chr->opaque; - + FDCharDriver *s = (FDCharDriver *)chr; + return io_channel_send(s->ioc_out, buf, len); } static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; - FDCharDriver *s = chr->opaque; + FDCharDriver *s = opaque; int len; uint8_t buf[READ_BUF_LEN]; ssize_t ret; @@ -1224,7 +1224,7 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) static int fd_chr_read_poll(void *opaque) { CharDriverState *chr = opaque; - FDCharDriver *s = chr->opaque; + FDCharDriver *s = opaque; s->max_size = qemu_chr_be_can_write(chr); return s->max_size; @@ -1232,14 +1232,14 @@ static int fd_chr_read_poll(void *opaque) static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond) { - FDCharDriver *s = chr->opaque; + FDCharDriver *s = (FDCharDriver *)chr; return qio_channel_create_watch(s->ioc_out, cond); } static void fd_chr_update_read_handler(CharDriverState *chr, GMainContext *context) { - FDCharDriver *s = chr->opaque; + FDCharDriver *s = (FDCharDriver *)chr; remove_fd_in_watch(chr); if (s->ioc_in) { @@ -1252,7 +1252,7 @@ static void fd_chr_update_read_handler(CharDriverState *chr, static void fd_chr_free(struct CharDriverState *chr) { - FDCharDriver *s = chr->opaque; + FDCharDriver *s = (FDCharDriver *)chr; remove_fd_in_watch(chr); if (s->ioc_in) { @@ -1262,7 +1262,6 @@ static void fd_chr_free(struct CharDriverState *chr) object_unref(OBJECT(s->ioc_out)); } - g_free(s); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1278,12 +1277,11 @@ static CharDriverState *qemu_chr_open_fd(const CharDriver *driver, if (!chr) { return NULL; } - s = g_new0(FDCharDriver, 1); + s = (FDCharDriver *)chr; s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in)); s->ioc_out = QIO_CHANNEL(qio_channel_file_new_fd(fd_out)); qemu_set_nonblock(fd_out); s->chr = chr; - chr->opaque = s; return chr; } @@ -1424,6 +1422,7 @@ static CharDriverState *qemu_chr_open_stdio(const CharDriver *driver, #define HAVE_CHARDEV_PTY 1 typedef struct { + CharDriverState parent; QIOChannel *ioc; int read_bytes; @@ -1439,7 +1438,7 @@ static void pty_chr_state(CharDriverState *chr, int connected); static gboolean pty_chr_timer(gpointer opaque) { struct CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = opaque; qemu_mutex_lock(&chr->chr_write_lock); s->timer_tag = 0; @@ -1455,7 +1454,7 @@ static gboolean pty_chr_timer(gpointer opaque) /* Called with chr_write_lock held. */ static void pty_chr_rearm_timer(CharDriverState *chr, int ms) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; if (s->timer_tag) { g_source_remove(s->timer_tag); @@ -1472,7 +1471,7 @@ static void pty_chr_rearm_timer(CharDriverState *chr, int ms) /* Called with chr_write_lock held. */ static void pty_chr_update_read_handler_locked(CharDriverState *chr) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; GPollFD pfd; int rc; QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc); @@ -1503,7 +1502,7 @@ static void pty_chr_update_read_handler(CharDriverState *chr, /* Called with chr_write_lock held. */ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; if (!s->connected) { /* guest sends data, check for (re-)connect */ @@ -1517,7 +1516,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; if (!s->connected) { return NULL; } @@ -1527,7 +1526,7 @@ static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond) static int pty_chr_read_poll(void *opaque) { CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = opaque; s->read_bytes = qemu_chr_be_can_write(chr); return s->read_bytes; @@ -1536,7 +1535,7 @@ static int pty_chr_read_poll(void *opaque) static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = opaque; gsize len; uint8_t buf[READ_BUF_LEN]; ssize_t ret; @@ -1561,7 +1560,7 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) static gboolean qemu_chr_be_generic_open_func(gpointer opaque) { CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = opaque; s->open_tag = 0; qemu_chr_be_generic_open(chr); @@ -1571,7 +1570,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque) /* Called with chr_write_lock held. */ static void pty_chr_state(CharDriverState *chr, int connected) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; if (!connected) { if (s->open_tag) { @@ -1605,7 +1604,7 @@ static void pty_chr_state(CharDriverState *chr, int connected) static void pty_chr_free(struct CharDriverState *chr) { - PtyCharDriver *s = chr->opaque; + PtyCharDriver *s = (PtyCharDriver *)chr; qemu_mutex_lock(&chr->chr_write_lock); pty_chr_state(chr, 0); @@ -1615,7 +1614,6 @@ static void pty_chr_free(struct CharDriverState *chr) s->timer_tag = 0; } qemu_mutex_unlock(&chr->chr_write_lock); - g_free(s); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1654,18 +1652,17 @@ static CharDriverState *qemu_chr_open_pty(const CharDriver *driver, fprintf(stderr, "char device redirected to %s (label %s)\n", pty_name, id); - s = g_new0(PtyCharDriver, 1); - chr->opaque = s; - *be_opened = false; - + s = (PtyCharDriver *)chr; s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd)); s->timer_tag = 0; + *be_opened = false; return chr; } static const CharDriver pty_driver = { { "pty" }, CHARDEV_BACKEND_KIND_PTY, NULL, qemu_chr_open_pty, + sizeof(PtyCharDriver), .chr_write = pty_chr_write, .chr_update_read_handler = pty_chr_update_read_handler, .chr_add_watch = pty_chr_add_watch, @@ -1789,7 +1786,7 @@ static void tty_serial_init(int fd, int speed, static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) { - FDCharDriver *s = chr->opaque; + FDCharDriver *s = (FDCharDriver *)chr; QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in); switch(cmd) { @@ -1868,6 +1865,7 @@ static void qemu_chr_free_tty(CharDriverState *chr) #define HAVE_CHARDEV_PARPORT 1 typedef struct { + CharDriverState parent; int fd; int mode; } ParallelCharDriver; @@ -1885,7 +1883,7 @@ static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode) static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) { - ParallelCharDriver *drv = chr->opaque; + ParallelCharDriver *drv = (ParallelCharDriver *)chr; int fd = drv->fd; uint8_t b; @@ -1966,13 +1964,12 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) static void pp_free(CharDriverState *chr) { - ParallelCharDriver *drv = chr->opaque; + ParallelCharDriver *drv = (ParallelCharDriver *)chr; int fd = drv->fd; pp_hw_mode(drv, IEEE1284_MODE_COMPAT); ioctl(fd, PPRELEASE); close(fd); - g_free(drv); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1996,9 +1993,7 @@ static CharDriverState *qemu_chr_open_pp_fd(const CharDriver *driver, return NULL; } - drv = g_new0(ParallelCharDriver, 1); - chr->opaque = drv; - + drv = (ParallelCharDriver *)chr; drv->fd = fd; drv->mode = IEEE1284_MODE_COMPAT; @@ -2010,35 +2005,45 @@ static CharDriverState *qemu_chr_open_pp_fd(const CharDriver *driver, #define HAVE_CHARDEV_PARPORT 1 +typedef struct { + CharDriverState parent; + int fd; +} ParallelCharDriver; + static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) { - int fd = (int)(intptr_t)chr->opaque; + ParallelCharDriver *drv = (ParallelCharDriver *)chr; uint8_t b; - switch(cmd) { + switch (cmd) { case CHR_IOCTL_PP_READ_DATA: - if (ioctl(fd, PPIGDATA, &b) < 0) + if (ioctl(drv->fd, PPIGDATA, &b) < 0) { return -ENOTSUP; + } *(uint8_t *)arg = b; break; case CHR_IOCTL_PP_WRITE_DATA: b = *(uint8_t *)arg; - if (ioctl(fd, PPISDATA, &b) < 0) + if (ioctl(drv->fd, PPISDATA, &b) < 0) { return -ENOTSUP; + } break; case CHR_IOCTL_PP_READ_CONTROL: - if (ioctl(fd, PPIGCTRL, &b) < 0) + if (ioctl(drv->fd, PPIGCTRL, &b) < 0) { return -ENOTSUP; + } *(uint8_t *)arg = b; break; case CHR_IOCTL_PP_WRITE_CONTROL: b = *(uint8_t *)arg; - if (ioctl(fd, PPISCTRL, &b) < 0) + if (ioctl(drv->fd, PPISCTRL, &b) < 0) { return -ENOTSUP; + } break; case CHR_IOCTL_PP_READ_STATUS: - if (ioctl(fd, PPIGSTATUS, &b) < 0) + if (ioctl(drv->fd, PPIGSTATUS, &b) < 0) { return -ENOTSUP; + } *(uint8_t *)arg = b; break; default: @@ -2054,12 +2059,14 @@ static CharDriverState *qemu_chr_open_pp_fd(const CharDriver *driver, Error **errp) { CharDriverState *chr; + ParallelCharDriver *drv; chr = qemu_chr_alloc(driver, backend, errp); if (!chr) { return NULL; } - chr->opaque = (void *)(intptr_t)fd; + drv = (ParallelCharDriver *)chr; + drv->fd = fd; *be_opened = false; return chr; } @@ -2070,6 +2077,7 @@ static CharDriverState *qemu_chr_open_pp_fd(const CharDriver *driver, #define HAVE_CHARDEV_SERIAL 1 typedef struct { + CharDriverState parent; int max_size; HANDLE hcom, hrecv, hsend; OVERLAPPED orecv; @@ -2081,6 +2089,7 @@ typedef struct { } WinCharState; typedef struct { + CharDriverState parent; HANDLE hStdIn; HANDLE hInputReadyEvent; HANDLE hInputDoneEvent; @@ -2098,7 +2107,7 @@ static int win_chr_pipe_poll(void *opaque); static void win_chr_free(CharDriverState *chr) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; if (s->hsend) { CloseHandle(s->hsend); @@ -2122,7 +2131,7 @@ static void win_chr_free(CharDriverState *chr) static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; COMMCONFIG comcfg; COMMTIMEOUTS cto = { 0, 0, 0, 0, 0}; COMSTAT comstat; @@ -2190,7 +2199,7 @@ static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp /* Called with chr_write_lock held. */ static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; DWORD len, ret, size, err; len = len1; @@ -2224,7 +2233,7 @@ static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1) static int win_chr_read_poll(CharDriverState *chr) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; s->max_size = qemu_chr_be_can_write(chr); return s->max_size; @@ -2232,7 +2241,7 @@ static int win_chr_read_poll(CharDriverState *chr) static void win_chr_readfile(CharDriverState *chr) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; int ret, err; uint8_t buf[READ_BUF_LEN]; DWORD size; @@ -2254,7 +2263,7 @@ static void win_chr_readfile(CharDriverState *chr) static void win_chr_read(CharDriverState *chr) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; if (s->len > s->max_size) s->len = s->max_size; @@ -2267,7 +2276,7 @@ static void win_chr_read(CharDriverState *chr) static int win_chr_poll(void *opaque) { CharDriverState *chr = opaque; - WinCharState *s = chr->opaque; + WinCharState *s = opaque; COMSTAT status; DWORD comerr; @@ -2284,7 +2293,7 @@ static int win_chr_poll(void *opaque) static int win_chr_pipe_poll(void *opaque) { CharDriverState *chr = opaque; - WinCharState *s = chr->opaque; + WinCharState *s = opaque; DWORD size; PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL); @@ -2300,7 +2309,7 @@ static int win_chr_pipe_poll(void *opaque) static int win_chr_pipe_init(CharDriverState *chr, const char *filename, Error **errp) { - WinCharState *s = chr->opaque; + WinCharState *s = (WinCharState *)chr; OVERLAPPED ov; int ret; DWORD size; @@ -2372,18 +2381,14 @@ static CharDriverState *qemu_chr_open_pipe(const CharDriver *driver, ChardevHostdev *opts = backend->u.pipe.data; const char *filename = opts->device; CharDriverState *chr; - WinCharState *s; ChardevCommon *common = qapi_ChardevHostdev_base(opts); chr = qemu_chr_alloc(driver, common, errp); if (!chr) { return NULL; } - s = g_new0(WinCharState, 1); - chr->opaque = s; if (win_chr_pipe_init(chr, filename, errp) < 0) { - g_free(s); qemu_chr_free_common(chr); return NULL; } @@ -2402,9 +2407,8 @@ static CharDriverState *qemu_chr_open_win_file(const CharDriver *driver, if (!chr) { return NULL; } - s = g_new0(WinCharState, 1); + s = (WinCharState *)chr; s->hcom = fd_out; - chr->opaque = s; return chr; } @@ -2423,6 +2427,7 @@ static CharDriverState *qemu_chr_open_win_con(const CharDriver *driver, static const CharDriver console_driver = { { "console" }, CHARDEV_BACKEND_KIND_CONSOLE, NULL, qemu_chr_open_win_con, + sizeof(WinCharState), .chr_write = win_chr_write, }; @@ -2448,7 +2453,7 @@ static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len) static void win_stdio_wait_func(void *opaque) { CharDriverState *chr = opaque; - WinStdioCharState *stdio = chr->opaque; + WinStdioCharState *stdio = opaque; INPUT_RECORD buf[4]; int ret; DWORD dwSize; @@ -2481,8 +2486,7 @@ static void win_stdio_wait_func(void *opaque) static DWORD WINAPI win_stdio_thread(LPVOID param) { - CharDriverState *chr = param; - WinStdioCharState *stdio = chr->opaque; + WinStdioCharState *stdio = param; int ret; DWORD dwSize; @@ -2521,7 +2525,7 @@ static DWORD WINAPI win_stdio_thread(LPVOID param) static void win_stdio_thread_wait_func(void *opaque) { CharDriverState *chr = opaque; - WinStdioCharState *stdio = chr->opaque; + WinStdioCharState *stdio = opaque; if (qemu_chr_be_can_write(chr)) { qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); @@ -2532,7 +2536,7 @@ static void win_stdio_thread_wait_func(void *opaque) static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) { - WinStdioCharState *stdio = chr->opaque; + WinStdioCharState *stdio = (WinStdioCharState *)chr; DWORD dwMode = 0; GetConsoleMode(stdio->hStdIn, &dwMode); @@ -2546,7 +2550,7 @@ static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) static void win_stdio_free(CharDriverState *chr) { - WinStdioCharState *stdio = chr->opaque; + WinStdioCharState *stdio = (WinStdioCharState *)chr; if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { CloseHandle(stdio->hInputReadyEvent); @@ -2557,8 +2561,6 @@ static void win_stdio_free(CharDriverState *chr) if (stdio->hInputThread != INVALID_HANDLE_VALUE) { TerminateThread(stdio->hInputThread, 0); } - - g_free(chr->opaque); } static CharDriverState *qemu_chr_open_stdio(const CharDriver *driver, @@ -2578,7 +2580,7 @@ static CharDriverState *qemu_chr_open_stdio(const CharDriver *driver, if (!chr) { return NULL; } - stdio = g_new0(WinStdioCharState, 1); + stdio = (WinStdioCharState *)chr; stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (stdio->hStdIn == INVALID_HANDLE_VALUE) { @@ -2588,8 +2590,6 @@ static CharDriverState *qemu_chr_open_stdio(const CharDriver *driver, is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; - chr->opaque = stdio; - if (is_console) { if (qemu_add_wait_object(stdio->hStdIn, win_stdio_wait_func, chr)) { @@ -2649,6 +2649,7 @@ err1: /* UDP Net console */ typedef struct { + CharDriverState parent; QIOChannel *ioc; uint8_t buf[READ_BUF_LEN]; int bufcnt; @@ -2659,7 +2660,7 @@ typedef struct { /* Called with chr_write_lock held. */ static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - NetCharDriver *s = chr->opaque; + NetCharDriver *s = (NetCharDriver *)chr; return qio_channel_write( s->ioc, (const char *)buf, len, NULL); @@ -2668,7 +2669,7 @@ static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int udp_chr_read_poll(void *opaque) { CharDriverState *chr = opaque; - NetCharDriver *s = chr->opaque; + NetCharDriver *s = opaque; s->max_size = qemu_chr_be_can_write(chr); @@ -2686,7 +2687,7 @@ static int udp_chr_read_poll(void *opaque) static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; - NetCharDriver *s = chr->opaque; + NetCharDriver *s = opaque; ssize_t ret; if (s->max_size == 0) { @@ -2713,7 +2714,7 @@ static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) static void udp_chr_update_read_handler(CharDriverState *chr, GMainContext *context) { - NetCharDriver *s = chr->opaque; + NetCharDriver *s = (NetCharDriver *)chr; remove_fd_in_watch(chr); if (s->ioc) { @@ -2726,13 +2727,12 @@ static void udp_chr_update_read_handler(CharDriverState *chr, static void udp_chr_free(CharDriverState *chr) { - NetCharDriver *s = chr->opaque; + NetCharDriver *s = (NetCharDriver *)chr; remove_fd_in_watch(chr); if (s->ioc) { object_unref(OBJECT(s->ioc)); } - g_free(s); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -2740,6 +2740,7 @@ static void udp_chr_free(CharDriverState *chr) /* TCP Net console */ typedef struct { + CharDriverState parent; QIOChannel *ioc; /* Client I/O channel */ QIOChannelSocket *sioc; /* Client master channel */ QIOChannelSocket *listen_ioc; @@ -2768,7 +2769,7 @@ static gboolean socket_reconnect_timeout(gpointer opaque); static void qemu_chr_socket_restart_timer(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; assert(s->connected == 0); s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time, socket_reconnect_timeout, chr); @@ -2777,7 +2778,7 @@ static void qemu_chr_socket_restart_timer(CharDriverState *chr) static void check_report_connect_error(CharDriverState *chr, Error *err) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; if (!s->connect_err_reported) { error_report("Unable to connect character device %s: %s", @@ -2794,7 +2795,8 @@ static gboolean tcp_chr_accept(QIOChannel *chan, /* Called with chr_write_lock held. */ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; + if (s->connected) { int ret = io_channel_send_full(s->ioc, buf, len, s->write_msgfds, @@ -2817,7 +2819,7 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int tcp_chr_read_poll(void *opaque) { CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = opaque; if (!s->connected) return 0; s->max_size = qemu_chr_be_can_write(chr); @@ -2876,7 +2878,8 @@ static void tcp_chr_process_IAC_bytes(CharDriverState *chr, static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; + int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; assert(num <= TCP_MAX_FDS); @@ -2901,7 +2904,7 @@ static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; /* clear old pending fd array */ g_free(s->write_msgfds); @@ -2926,7 +2929,7 @@ static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; struct iovec iov = { .iov_base = buf, .iov_len = len }; int ret; size_t i; @@ -2983,13 +2986,13 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; return qio_channel_create_watch(s->ioc, cond); } static void tcp_chr_free_connection(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; int i; if (!s->connected) { @@ -3018,7 +3021,7 @@ static void tcp_chr_free_connection(CharDriverState *chr) static void tcp_chr_disconnect(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; if (!s->connected) { return; @@ -3041,7 +3044,7 @@ static void tcp_chr_disconnect(CharDriverState *chr) static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = opaque; uint8_t buf[READ_BUF_LEN]; int len, size; @@ -3067,7 +3070,7 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; int size; if (!s->connected) { @@ -3086,7 +3089,7 @@ static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) static void tcp_chr_connect(void *opaque) { CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = opaque; g_free(chr->filename); chr->filename = sockaddr_to_str( @@ -3107,7 +3110,7 @@ static void tcp_chr_connect(void *opaque) static void tcp_chr_update_read_handler(CharDriverState *chr, GMainContext *context) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; if (!s->connected) { return; @@ -3158,7 +3161,7 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc, static void tcp_chr_telnet_init(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; TCPCharDriverTelnetInit *init = g_new0(TCPCharDriverTelnetInit, 1); size_t n = 0; @@ -3194,7 +3197,7 @@ static void tcp_chr_tls_handshake(Object *source, gpointer user_data) { CharDriverState *chr = user_data; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = user_data; if (err) { tcp_chr_disconnect(chr); @@ -3210,7 +3213,7 @@ static void tcp_chr_tls_handshake(Object *source, static void tcp_chr_tls_init(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; QIOChannelTLS *tioc; Error *err = NULL; @@ -3242,7 +3245,8 @@ static void tcp_chr_tls_init(CharDriverState *chr) static int tcp_chr_new_client(CharDriverState *chr, QIOChannelSocket *sioc) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; + if (s->ioc != NULL) { return -1; } @@ -3312,7 +3316,7 @@ static gboolean tcp_chr_accept(QIOChannel *channel, static int tcp_chr_wait_connected(CharDriverState *chr, Error **errp) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; QIOChannelSocket *sioc; /* It can't wait on s->connected, since it is set asynchronously @@ -3359,7 +3363,7 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp) static void tcp_chr_free(CharDriverState *chr) { - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; tcp_chr_free_connection(chr); @@ -3378,7 +3382,7 @@ static void tcp_chr_free(CharDriverState *chr) if (s->tls_creds) { object_unref(OBJECT(s->tls_creds)); } - g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -3387,7 +3391,7 @@ static void qemu_chr_socket_connected(Object *src, Error *err, void *opaque) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(src); CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = (TCPCharDriver *)chr; if (err) { check_report_connect_error(chr, err); @@ -3405,6 +3409,7 @@ static void qemu_chr_socket_connected(Object *src, Error *err, void *opaque) /* Ring buffer chardev */ typedef struct { + CharDriverState parent; size_t size; size_t prod; size_t cons; @@ -3413,7 +3418,7 @@ typedef struct { static size_t ringbuf_count(const CharDriverState *chr) { - const RingBufCharDriver *d = chr->opaque; + const RingBufCharDriver *d = (RingBufCharDriver *)chr; return d->prod - d->cons; } @@ -3421,7 +3426,7 @@ static size_t ringbuf_count(const CharDriverState *chr) /* Called with chr_write_lock held. */ static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - RingBufCharDriver *d = chr->opaque; + RingBufCharDriver *d = (RingBufCharDriver *)chr; int i; if (!buf || (len < 0)) { @@ -3440,7 +3445,7 @@ static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) { - RingBufCharDriver *d = chr->opaque; + RingBufCharDriver *d = (RingBufCharDriver *)chr; int i; qemu_mutex_lock(&chr->chr_write_lock); @@ -3454,11 +3459,9 @@ static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) static void ringbuf_chr_free(struct CharDriverState *chr) { - RingBufCharDriver *d = chr->opaque; + RingBufCharDriver *d = (RingBufCharDriver *)chr; g_free(d->cbuf); - g_free(d); - chr->opaque = NULL; } static CharDriverState *qemu_chr_open_ringbuf(const CharDriver *driver, @@ -3477,7 +3480,7 @@ static CharDriverState *qemu_chr_open_ringbuf(const CharDriver *driver, if (!chr) { return NULL; } - d = g_malloc(sizeof(*d)); + d = (RingBufCharDriver *)chr; d->size = opts->has_size ? opts->size : 65536; @@ -3491,12 +3494,9 @@ static CharDriverState *qemu_chr_open_ringbuf(const CharDriver *driver, d->cons = 0; d->cbuf = g_malloc0(d->size); - chr->opaque = d; - return chr; fail: - g_free(d); qemu_chr_free_common(chr); return NULL; } @@ -3786,10 +3786,12 @@ static const CharDriver stdio_driver = { { "stdio" }, CHARDEV_BACKEND_KIND_STDIO, qemu_chr_parse_stdio, qemu_chr_open_stdio, #ifdef _WIN32 + sizeof(WinStdioCharState), .chr_write = win_stdio_write, .chr_set_echo = qemu_chr_set_echo_win_stdio, .chr_free = win_stdio_free, #else + sizeof(FDCharDriver), .chr_add_watch = fd_chr_add_watch, .chr_write = fd_chr_write, .chr_update_read_handler = fd_chr_update_read_handler, @@ -3851,9 +3853,11 @@ static const CharDriver pipe_driver = { { "pipe" }, CHARDEV_BACKEND_KIND_PIPE, qemu_chr_parse_pipe, qemu_chr_open_pipe, #ifdef _WIN32 + sizeof(WinCharState), .chr_write = win_chr_write, .chr_free = win_chr_free, #else + sizeof(FDCharDriver), .chr_add_watch = fd_chr_add_watch, .chr_write = fd_chr_write, .chr_update_read_handler = fd_chr_update_read_handler, @@ -3880,6 +3884,7 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, static const CharDriver ringbuf_driver = { { "ringbuf" }, CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf, + sizeof(RingBufCharDriver), .chr_write = ringbuf_chr_write, .chr_free = ringbuf_chr_free, }; @@ -3888,6 +3893,7 @@ static const CharDriver ringbuf_driver = { static const CharDriver memory_driver = { { "memory" }, CHARDEV_BACKEND_KIND_MEMORY, qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf, + sizeof(RingBufCharDriver), .chr_write = ringbuf_chr_write, .chr_free = ringbuf_chr_free, }; @@ -3909,6 +3915,7 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, static const CharDriver mux_driver = { { "mux" }, CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, qemu_chr_open_mux, + sizeof(MuxDriver), .chr_free = mux_chr_free, .chr_write = mux_chr_write, .chr_accept_input = mux_chr_accept_input, @@ -4489,17 +4496,13 @@ static CharDriverState *qmp_chardev_open_serial(const CharDriver *driver, ChardevHostdev *serial = backend->u.serial.data; ChardevCommon *common = qapi_ChardevHostdev_base(serial); CharDriverState *chr; - WinCharState *s; chr = qemu_chr_alloc(driver, common, errp); if (!chr) { return NULL; } - s = g_new0(WinCharState, 1); - chr->opaque = s; if (win_chr_init(chr, serial->device, errp) < 0) { - g_free(s); qemu_chr_free_common(chr); return NULL; } @@ -4601,6 +4604,7 @@ static CharDriverState *qmp_chardev_open_parallel(const CharDriver *driver, static const CharDriver parallel_driver = { { "parallel", "parport" }, CHARDEV_BACKEND_KIND_PARALLEL, qemu_chr_parse_parallel, qmp_chardev_open_parallel, + sizeof(ParallelCharDriver), #if defined(__linux__) .chr_write = null_chr_write, .chr_ioctl = pp_ioctl, @@ -4618,8 +4622,10 @@ static const CharDriver file_driver = { { "file" }, CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file, #ifdef _WIN32 + sizeof(WinCharState), .chr_write = win_chr_write, #else + sizeof(FDCharDriver), .chr_add_watch = fd_chr_add_watch, .chr_write = fd_chr_write, .chr_update_read_handler = fd_chr_update_read_handler, @@ -4632,9 +4638,11 @@ static const CharDriver serial_driver = { { "serial", "tty" }, CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial, #ifdef _WIN32 + sizeof(WinCharState), .chr_write = win_chr_write, .chr_free = win_chr_free, #else + sizeof(FDCharDriver), .chr_add_watch = fd_chr_add_watch, .chr_write = fd_chr_write, .chr_update_read_handler = fd_chr_update_read_handler, @@ -4647,7 +4655,7 @@ static const CharDriver serial_driver = { static gboolean socket_reconnect_timeout(gpointer opaque) { CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; + TCPCharDriver *s = opaque; QIOChannelSocket *sioc; s->reconnect_timer = 0; @@ -4687,7 +4695,7 @@ static CharDriverState *qmp_chardev_open_socket(const CharDriver *driver, if (!chr) { return NULL; } - s = g_new0(TCPCharDriver, 1); + s = (TCPCharDriver *)chr; s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX; s->is_listen = is_listen; @@ -4733,7 +4741,6 @@ static CharDriverState *qmp_chardev_open_socket(const CharDriver *driver, qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); } - chr->opaque = s; /* be isn't opened until we get a connection */ *be_opened = false; @@ -4783,7 +4790,6 @@ static CharDriverState *qmp_chardev_open_socket(const CharDriver *driver, if (s->tls_creds) { object_unref(OBJECT(s->tls_creds)); } - g_free(s); qemu_chr_free_common(chr); return NULL; } @@ -4791,6 +4797,7 @@ static CharDriverState *qmp_chardev_open_socket(const CharDriver *driver, static const CharDriver socket_driver = { { "socket" }, CHARDEV_BACKEND_KIND_SOCKET, qemu_chr_parse_socket, qmp_chardev_open_socket, + sizeof(TCPCharDriver), .chr_wait_connected = tcp_chr_wait_connected, .chr_write = tcp_chr_write, .chr_sync_read = tcp_chr_sync_read, @@ -4828,11 +4835,10 @@ static CharDriverState *qmp_chardev_open_udp(const CharDriver *driver, return NULL; } - s = g_new0(NetCharDriver, 1); + s = (NetCharDriver *)chr; s->ioc = QIO_CHANNEL(sioc); s->bufcnt = 0; s->bufptr = 0; - chr->opaque = s; /* be isn't opened until we get a connection */ *be_opened = false; @@ -4842,6 +4848,7 @@ static CharDriverState *qmp_chardev_open_udp(const CharDriver *driver, static const CharDriver udp_driver = { { "udp" }, CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, qmp_chardev_open_udp, + sizeof(NetCharDriver), .chr_write = udp_chr_write, .chr_update_read_handler = udp_chr_update_read_handler, .chr_free = udp_chr_free, diff --git a/spice-qemu-char.c b/spice-qemu-char.c index 14afd4a..bd8b898 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -7,7 +7,8 @@ typedef struct SpiceCharDriver { - CharDriverState* chr; + CharDriverState parent; + SpiceCharDeviceInstance sin; bool active; bool blocked; @@ -27,17 +28,18 @@ static QLIST_HEAD(, SpiceCharDriver) spice_chars = static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) { SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); + CharDriverState *chr = (CharDriverState *)scd; ssize_t out = 0; ssize_t last_out; uint8_t* p = (uint8_t*)buf; while (len > 0) { - int can_write = qemu_chr_be_can_write(scd->chr); + int can_write = qemu_chr_be_can_write(chr); last_out = MIN(len, can_write); if (last_out <= 0) { break; } - qemu_chr_be_write(scd->chr, p, last_out); + qemu_chr_be_write(chr, p, last_out); out += last_out; len -= last_out; p += last_out; @@ -70,6 +72,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event) { SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); + CharDriverState *chr = (CharDriverState *)scd; int chr_event; switch (event) { @@ -81,20 +84,21 @@ static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event) } trace_spice_vmc_event(chr_event); - qemu_chr_be_event(scd->chr, chr_event); + qemu_chr_be_event(chr, chr_event); } #endif static void vmc_state(SpiceCharDeviceInstance *sin, int connected) { SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); + CharDriverState *chr = (CharDriverState *)scd; - if ((scd->chr->be_open && connected) || - (!scd->chr->be_open && !connected)) { + if ((chr->be_open && connected) || + (!chr->be_open && !connected)) { return; } - qemu_chr_be_event(scd->chr, + qemu_chr_be_event(chr, connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED); } @@ -168,7 +172,7 @@ static GSourceFuncs SpiceCharSourceFuncs = { static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond) { - SpiceCharDriver *scd = chr->opaque; + SpiceCharDriver *scd = (SpiceCharDriver *)chr; SpiceCharSource *src; assert(cond & G_IO_OUT); @@ -182,7 +186,7 @@ static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond) static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - SpiceCharDriver *s = chr->opaque; + SpiceCharDriver *s = (SpiceCharDriver *)chr; int read_bytes; assert(s->datalen == 0); @@ -201,7 +205,7 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static void spice_chr_free(struct CharDriverState *chr) { - SpiceCharDriver *s = chr->opaque; + SpiceCharDriver *s = (SpiceCharDriver *)chr; vmc_unregister_interface(s); QLIST_REMOVE(s, next); @@ -210,12 +214,11 @@ static void spice_chr_free(struct CharDriverState *chr) #if SPICE_SERVER_VERSION >= 0x000c02 g_free((char *)s->sin.portname); #endif - g_free(s); } static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open) { - SpiceCharDriver *s = chr->opaque; + SpiceCharDriver *s = (SpiceCharDriver *)chr; if (fe_open) { vmc_register_interface(s); } else { @@ -226,7 +229,7 @@ static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open) static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open) { #if SPICE_SERVER_VERSION >= 0x000c02 - SpiceCharDriver *s = chr->opaque; + SpiceCharDriver *s = (SpiceCharDriver *)chr; if (fe_open) { spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED); @@ -255,7 +258,7 @@ static void print_allowed_subtypes(void) static void spice_chr_accept_input(struct CharDriverState *chr) { - SpiceCharDriver *s = chr->opaque; + SpiceCharDriver *s = (SpiceCharDriver *)chr; spice_server_char_device_wakeup(&s->sin); } @@ -272,11 +275,9 @@ static CharDriverState *chr_open(const CharDriver *driver, if (!chr) { return NULL; } - s = g_malloc0(sizeof(SpiceCharDriver)); - s->chr = chr; + s = (SpiceCharDriver *)chr; s->active = false; s->sin.subtype = g_strdup(subtype); - chr->opaque = s; QLIST_INSERT_HEAD(&spice_chars, s, next); @@ -334,7 +335,7 @@ static CharDriverState *qemu_chr_open_spice_port(const CharDriver *driver, return NULL; } *be_opened = false; - s = chr->opaque; + s = (SpiceCharDriver *)chr; s->sin.portname = g_strdup(name); return chr; @@ -388,6 +389,7 @@ static void register_types(void) static const CharDriver vmc_driver = { { "spicevmc" }, CHARDEV_BACKEND_KIND_SPICEVMC, qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc, + sizeof(SpiceCharDriver), .chr_write = spice_chr_write, .chr_add_watch = spice_chr_add_watch, .chr_set_fe_open = spice_vmc_set_fe_open, @@ -397,6 +399,7 @@ static void register_types(void) static const CharDriver port_driver = { { "spiceport" }, CHARDEV_BACKEND_KIND_SPICEPORT, qemu_chr_parse_spice_port, qemu_chr_open_spice_port, + sizeof(SpiceCharDriver), .chr_write = spice_chr_write, .chr_add_watch = spice_chr_add_watch, .chr_set_fe_open = spice_port_set_fe_open, diff --git a/ui/console.c b/ui/console.c index 2944d22..b8c6328 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1035,9 +1035,15 @@ void console_select(unsigned int index) } } +typedef struct VCDriverState { + CharDriverState parent; + QemuConsole *console; +} VCDriverState; + static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) { - QemuConsole *s = chr->opaque; + VCDriverState *drv = (VCDriverState *)chr; + QemuConsole *s = drv->console; int i; s->update_x0 = s->width * FONT_WIDTH; @@ -1943,7 +1949,8 @@ int qemu_console_get_height(QemuConsole *con, int fallback) static void text_console_set_echo(CharDriverState *chr, bool echo) { - QemuConsole *s = chr->opaque; + VCDriverState *drv = (VCDriverState *)chr; + QemuConsole *s = drv->console; s->echo = echo; } @@ -1983,12 +1990,11 @@ static const GraphicHwOps text_console_ops = { static void text_console_do_init(CharDriverState *chr, DisplayState *ds) { - QemuConsole *s; + VCDriverState *drv = (VCDriverState *)chr; + QemuConsole *s = drv->console; int g_width = 80 * FONT_WIDTH; int g_height = 24 * FONT_HEIGHT; - s = chr->opaque; - s->out_fifo.buf = s->out_fifo_buf; s->out_fifo.buf_size = sizeof(s->out_fifo_buf); s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s); @@ -2041,6 +2047,7 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) { ChardevCommon *common = qapi_ChardevVC_base(vc); CharDriverState *chr; + VCDriverState *drv; QemuConsole *s; unsigned width = 0; unsigned height = 0; @@ -2077,7 +2084,8 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) } s->chr = chr; - chr->opaque = s; + drv = (VCDriverState *)chr; + drv->console = s; if (display_state) { text_console_do_init(chr, display_state); @@ -2182,6 +2190,7 @@ static const TypeInfo qemu_console_info = { static const CharDriver vc_driver = { { "vc" }, CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc, vc_init, + sizeof(VCDriverState), .chr_write = console_puts, .chr_set_echo = text_console_set_echo, }; diff --git a/ui/gtk.c b/ui/gtk.c index 1566faa..03281da 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1653,7 +1653,7 @@ static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque) static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - VirtualConsole *vc = chr->opaque; + VirtualConsole *vc = (VirtualConsole *)chr; vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len); return len; @@ -1661,7 +1661,7 @@ static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo) { - VirtualConsole *vc = chr->opaque; + VirtualConsole *vc = (VirtualConsole *)chr; vc->vte.echo = echo; } @@ -1673,6 +1673,7 @@ static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp) { static const CharDriver gd_vc_driver = { { "vc" }, CHARDEV_BACKEND_KIND_VC, + .instance_size = sizeof(VirtualConsole), .chr_write = gd_vc_chr_write, .chr_set_echo = gd_vc_chr_set_echo, }; @@ -1685,9 +1686,6 @@ static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp) return NULL; } - /* Temporary, until gd_vc_vte_init runs. */ - chr->opaque = g_new0(VirtualConsole, 1); - vcs[nb_vcs++] = chr; return chr; @@ -1728,13 +1726,12 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc, GtkWidget *box; GtkWidget *scrollbar; GtkAdjustment *vadjustment; - VirtualConsole *tmp_vc = chr->opaque; + VirtualConsole *tmp_vc = (VirtualConsole *)chr; vc->s = s; vc->vte.echo = tmp_vc->vte.echo; vc->vte.chr = chr; - chr->opaque = vc; g_free(tmp_vc); snprintf(buffer, sizeof(buffer), "vc%d", idx); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 96b464a..a072edc 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -93,7 +93,6 @@ struct CharDriverState { const CharDriver *driver; QemuMutex chr_write_lock; CharBackend *be; - void *opaque; char *label; char *filename; int logfd; @@ -482,6 +481,7 @@ struct CharDriver { ChardevBackend *backend, ChardevReturn *ret, bool *be_opened, Error **errp); + size_t instance_size; int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); int (*chr_sync_read)(struct CharDriverState *s, diff --git a/include/ui/gtk.h b/include/ui/gtk.h index 42ca0fe..6fec03f 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -23,6 +23,8 @@ #include "ui/egl-context.h" #endif +#include "sysemu/char.h" + /* Compatibility define to let us build on both Gtk2 and Gtk3 */ #if GTK_CHECK_VERSION(3, 0, 0) static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh) @@ -71,6 +73,7 @@ typedef enum VirtualConsoleType { } VirtualConsoleType; typedef struct VirtualConsole { + CharDriverState parent; GtkDisplayState *s; char *label; GtkWidget *window; -- 2.10.0