static int qemu_chr_write_buffer(Chardev *s, const uint8_t *buf, int len, int *offset, bool write_all) { ChardevClass *cc = CHARDEV_GET_CLASS(s); int res = 0; *offset = 0; qemu_mutex_lock(&s->chr_write_lock); while (*offset < len) { retry: res = cc->chr_write(s, buf + *offset, len - *offset); if (res < 0 && errno == EAGAIN && write_all) { g_usleep(100); goto retry; } if (res <= 0) { break; } *offset += res; if (!write_all) { break; } } if (*offset > 0) { qemu_chr_write_log(s, buf, *offset); } qemu_mutex_unlock(&s->chr_write_lock); return res; }
static void qemu_char_open(Chardev *chr, ChardevBackend *backend, bool *be_opened, Error **errp) { ChardevClass *cc = CHARDEV_GET_CLASS(chr); /* Any ChardevCommon member would work */ ChardevCommon *common = backend ? backend->u.null.data : NULL; if (common && common->has_logfile) { int flags = O_WRONLY | O_CREAT; if (common->has_logappend && common->logappend) { flags |= O_APPEND; } else { flags |= O_TRUNC; } chr->logfd = qemu_open(common->logfile, flags, 0666); if (chr->logfd < 0) { error_setg_errno(errp, errno, "Unable to open logfile %s", common->logfile); return; } } if (cc->open) { cc->open(chr, backend, be_opened, errp); } }
int qemu_chr_wait_connected(Chardev *chr, Error **errp) { ChardevClass *cc = CHARDEV_GET_CLASS(chr); if (cc->chr_wait_connected) { return cc->chr_wait_connected(chr, errp); } return 0; }
static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond) { MuxChardev *d = MUX_CHARDEV(s); Chardev *chr = qemu_chr_fe_get_driver(&d->chr); ChardevClass *cc = CHARDEV_GET_CLASS(chr); if (!cc->chr_add_watch) { return NULL; } return cc->chr_add_watch(chr, cond); }
int qemu_chr_add_client(Chardev *s, int fd) { return CHARDEV_GET_CLASS(s)->chr_add_client ? CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1; }