}
}
-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;
brlapi_strerror(brlapi_error_location()));
g_free(handle);
baum->brlapi = NULL;
- return;
+ return false;
}
baum->deferred_init = 0;
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)
#include "chardev/char-win.h"
#include "qemu/module.h"
-static void console_chr_open(Chardev *chr, ChardevBackend *backend,
+static bool 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);
+ return true;
}
static void char_console_class_init(ObjectClass *oc, const void *data)
#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
if (file->in) {
error_setg(errp, "input file not supported");
- return;
+ return false;
}
if (file->has_append && file->append) {
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);
out = qmp_chardev_open_file_source(file->out, flags, errp);
if (out < 0) {
- return;
+ return false;
}
if (file->in) {
in = qmp_chardev_open_file_source(file->in, flags, errp);
if (in < 0) {
qemu_close(out);
- return;
+ return false;
}
}
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,
}
}
-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);
if (list == NULL) {
error_setg(errp, "hub: 'chardevs' list is not defined");
- return;
+ return false;
}
while (list) {
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;
}
* 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)
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;
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;
}
/*
if (muxes_opened) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
+
+ return true;
}
static void mux_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
#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)
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);
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__ */
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)
{
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,
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;
);
if (fd_in < 0) {
error_setg_file_open(errp, errno, filename);
- return;
+ return false;
}
}
if (fd_out != fd_in) {
close(fd_out);
}
- return;
+ return false;
}
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
#endif /* !_WIN32 */
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;
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);
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)
g_free(d->cbuf);
}
-static void ringbuf_chr_open(Chardev *chr,
+static bool ringbuf_chr_open(Chardev *chr,
ChardevBackend *backend,
Error **errp)
{
/* 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;
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,
#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__) \
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;
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__ */
}
-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;
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,
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,
? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
: QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
errp)) {
- return;
+ return false;
}
}
s->tls_authz = g_strdup(sock->tls_authz);
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);
*/
if (!chr->handover_yank_instance) {
if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
- return;
+ return false;
}
}
s->registered_yank = true;
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)
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;
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);
stdio_chr_set_echo(chr, false);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
#endif
}
}
-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);
qapi_free_SocketAddress(remote_addr);
if (ret < 0) {
object_unref(OBJECT(sioc));
- return;
+ return false;
}
name = g_strdup_printf("chardev-udp-%s", chr->label);
s->ioc = QIO_CHANNEL(sioc);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
static void char_udp_class_init(ObjectClass *oc, const void *data)
}
}
-static void win_stdio_chr_open(Chardev *chr,
+static bool win_stdio_chr_open(Chardev *chr,
ChardevBackend *backend,
Error **errp)
{
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;
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);
CloseHandle(stdio->hInputDoneEvent);
err1:
qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
+ return false;
}
static void char_win_stdio_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)
{
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)
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;
subtypes);
g_free(subtypes);
- return;
+ return false;
}
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;
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");
s->sin.portname = g_strdup(name);
vmc_register_interface(s);
+ return true;
}
static void spice_vmc_chr_parse(QemuOpts *opts, ChardevBackend *backend,
}
}
-static void wctablet_chr_open(Chardev *chr,
+static bool wctablet_chr_open(Chardev *chr,
ChardevBackend *backend,
Error **errp)
{
&wctablet_handler);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
static void wctablet_chr_class_init(ObjectClass *oc, const void *data)
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)
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);
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);
}
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
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();
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);
}
static int nb_vcs;
static Chardev *vcs[MAX_VCS];
-static void gd_vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
+static bool 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;
* 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)
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"
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";
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)
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;
/* ------------------------------------------------------------------ */
/* 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);
* 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;
}
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+ return true;
}
static void vdagent_clipboard_peer_register(VDAgentChardev *vd)
}
};
-static void vdagent_chr_init(Object *obj)
+static void vdagent_chr_instance_init(Object *obj)
{
VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj);
.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,
};