static const ChardevClass *char_get_class(const char *driver, Error **errp) { ObjectClass *oc; const ChardevClass *cc; char *typename = g_strdup_printf("chardev-%s", driver); oc = object_class_by_name(typename); g_free(typename); if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) { error_setg(errp, "'%s' is not a valid char driver name", driver); return NULL; } if (object_class_is_abstract(oc)) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", "abstract device type"); return NULL; } cc = CHARDEV_CLASS(oc); if (cc->internal) { error_setg(errp, "'%s' is not a valid char driver name", driver); return NULL; } return cc; }
static void char_fd_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->chr_add_watch = fd_chr_add_watch; cc->chr_write = fd_chr_write; cc->chr_update_read_handler = fd_chr_update_read_handler; }
static void wctablet_chr_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->open = wctablet_chr_open; cc->chr_write = wctablet_chr_write; cc->chr_ioctl = wctablet_chr_ioctl; cc->chr_accept_input = wctablet_chr_accept_input; }
static void char_pty_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->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; }
static void char_udp_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->parse = qemu_chr_parse_udp; cc->open = qmp_chardev_open_udp; cc->chr_write = udp_chr_write; cc->chr_update_read_handler = udp_chr_update_read_handler; }
static void chardev_class_foreach(ObjectClass *klass, void *opaque) { ChadevClassFE *fe = opaque; assert(g_str_has_prefix(object_class_get_name(klass), "chardev-")); if (CHARDEV_CLASS(klass)->internal) { return; } fe->fn(object_class_get_name(klass) + 8, fe->opaque); }
static void char_mux_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->parse = qemu_chr_parse_mux; cc->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; cc->chr_be_event = mux_chr_be_event; cc->chr_machine_done = open_muxes; }
static void char_socket_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->parse = qemu_chr_parse_socket; cc->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_add_client = tcp_chr_add_client; cc->chr_add_watch = tcp_chr_add_watch; cc->chr_update_read_handler = tcp_chr_update_read_handler; object_class_property_add(oc, "addr", "SocketAddress", char_socket_get_addr, NULL, NULL, NULL, &error_abort); object_class_property_add_bool(oc, "connected", char_socket_get_connected, NULL, &error_abort); }
static void char_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->chr_write = null_chr_write; }
static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, Error **errp) { bool is_listen = qemu_opt_get_bool(opts, "server", false); bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0); const char *path = qemu_opt_get(opts, "path"); const char *host = qemu_opt_get(opts, "host"); const char *port = qemu_opt_get(opts, "port"); const char *tls_creds = qemu_opt_get(opts, "tls-creds"); SocketAddress *addr; ChardevSocket *sock; backend->type = CHARDEV_BACKEND_KIND_SOCKET; if (!path) { if (!host) { error_setg(errp, "chardev: socket: no host given"); return; } if (!port) { error_setg(errp, "chardev: socket: no port given"); return; } } else { if (tls_creds) { error_setg(errp, "TLS can only be used over TCP socket"); return; } } sock = backend->u.socket.data = g_new0(ChardevSocket, 1); qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); sock->has_nodelay = true; sock->nodelay = do_nodelay; sock->has_server = true; sock->server = is_listen; sock->has_telnet = true; sock->telnet = is_telnet; sock->has_wait = true; sock->wait = is_waitconnect; sock->has_reconnect = true; sock->reconnect = reconnect; sock->tls_creds = g_strdup(tls_creds); addr = g_new0(SocketAddress, 1); if (path) { UnixSocketAddress *q_unix; addr->type = SOCKET_ADDRESS_KIND_UNIX; q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); q_unix->path = g_strdup(path); } else { addr->type = SOCKET_ADDRESS_KIND_INET; addr->u.inet.data = g_new(InetSocketAddress, 1); *addr->u.inet.data = (InetSocketAddress) { .host = g_strdup(host), .port = g_strdup(port), .has_to = qemu_opt_get(opts, "to"), .to = qemu_opt_get_number(opts, "to", 0), .has_ipv4 = qemu_opt_get(opts, "ipv4"), .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0), .has_ipv6 = qemu_opt_get(opts, "ipv6"), .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0), }; } sock->addr = addr; } static void char_socket_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->parse = qemu_chr_parse_socket; cc->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_add_client = tcp_chr_add_client; cc->chr_add_watch = tcp_chr_add_watch; cc->chr_update_read_handler = tcp_chr_update_read_handler; }
static void char_null_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); cc->open = null_chr_open; }