示例#1
0
文件: char.c 项目: mdroth/qemu
/**
 * Called after processing of default and command-line-specified
 * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
 * to a mux chardev. This is done here to ensure that
 * output/prompts/banners are only displayed for the FE that has
 * focus when initial command-line processing/machine init is
 * completed.
 *
 * After this point, any new FE attached to any new or existing
 * mux will receive CHR_EVENT_OPENED notifications for the BE
 * immediately.
 */
static int open_muxes(Object *child, void *opaque)
{
    if (CHARDEV_IS_MUX(child)) {
        /* send OPENED to all already-attached FEs */
        mux_chr_send_all_event(CHARDEV(child), CHR_EVENT_OPENED);
        /* mark mux as OPENED so any new FEs will immediately receive
         * OPENED event
         */
        qemu_chr_be_event(CHARDEV(child), CHR_EVENT_OPENED);
    }

    return 0;
}
示例#2
0
static void char_socket_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    SocketChardev *s = SOCKET_CHARDEV(obj);

    tcp_chr_free_connection(chr);

    if (s->reconnect_timer) {
        g_source_remove(s->reconnect_timer);
        s->reconnect_timer = 0;
    }
    qapi_free_SocketAddress(s->addr);
    if (s->listen_tag) {
        g_source_remove(s->listen_tag);
        s->listen_tag = 0;
    }
    if (s->listen_ioc) {
        object_unref(OBJECT(s->listen_ioc));
    }
    if (s->tls_creds) {
        object_unref(OBJECT(s->tls_creds));
    }

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
示例#3
0
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);
    uint8_t buf[CHR_READ_BUF_LEN];
    int len, size;

    if (!s->connected || s->max_size <= 0) {
        return TRUE;
    }
    len = sizeof(buf);
    if (len > s->max_size) {
        len = s->max_size;
    }
    size = tcp_chr_recv(chr, (void *)buf, len);
    if (size == 0 || size == -1) {
        /* connection closed */
        tcp_chr_disconnect(chr);
    } else if (size > 0) {
        if (s->do_telnetopt) {
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
        }
        if (size > 0) {
            qemu_chr_be_write(chr, buf, size);
        }
    }

    return TRUE;
}
示例#4
0
文件: char-pty.c 项目: pfliu/qemu
static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    PtyChardev *s = PTY_CHARDEV(opaque);
    gsize len;
    uint8_t buf[CHR_READ_BUF_LEN];
    ssize_t ret;

    len = sizeof(buf);
    if (len > s->read_bytes) {
        len = s->read_bytes;
    }
    if (len == 0) {
        return TRUE;
    }
    ret = qio_channel_read(s->ioc, (char *)buf, len, NULL);
    if (ret <= 0) {
        pty_chr_state(chr, 0);
        return FALSE;
    } else {
        pty_chr_state(chr, 1);
        qemu_chr_be_write(chr, buf, ret);
    }
    return TRUE;
}
示例#5
0
文件: char.c 项目: mdroth/qemu
static void char_init(Object *obj)
{
    Chardev *chr = CHARDEV(obj);

    chr->logfd = -1;
    qemu_mutex_init(&chr->chr_write_lock);
}
示例#6
0
文件: char-fd.c 项目: mdroth/qemu
static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    FDChardev *s = FD_CHARDEV(opaque);
    int len;
    uint8_t buf[CHR_READ_BUF_LEN];
    ssize_t ret;

    len = sizeof(buf);
    if (len > s->max_size) {
        len = s->max_size;
    }
    if (len == 0) {
        return TRUE;
    }

    ret = qio_channel_read(
        chan, (gchar *)buf, len, NULL);
    if (ret == 0) {
        remove_fd_in_watch(chr);
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
        return FALSE;
    }
    if (ret > 0) {
        qemu_chr_be_write(chr, buf, ret);
    }

    return TRUE;
}
示例#7
0
文件: char-fd.c 项目: mdroth/qemu
static int fd_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    FDChardev *s = FD_CHARDEV(opaque);

    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}
示例#8
0
文件: char-pty.c 项目: pfliu/qemu
static int pty_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    PtyChardev *s = PTY_CHARDEV(opaque);

    s->read_bytes = qemu_chr_be_can_write(chr);
    return s->read_bytes;
}
示例#9
0
static void update_disconnected_filename(SocketChardev *s)
{
    Chardev *chr = CHARDEV(s);

    g_free(chr->filename);
    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
                                         s->is_listen, s->is_telnet);
}
示例#10
0
文件: char-pty.c 项目: pfliu/qemu
static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
{
    Chardev *chr = CHARDEV(opaque);
    PtyChardev *s = PTY_CHARDEV(opaque);

    s->open_source = NULL;
    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
    return FALSE;
}
示例#11
0
static int tcp_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);
    if (!s->connected) {
        return 0;
    }
    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}
示例#12
0
static void char_pty_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    PtyChardev *s = PTY_CHARDEV(obj);

    pty_chr_state(chr, 0);
    object_unref(OBJECT(s->ioc));
    pty_chr_timer_cancel(s);
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
示例#13
0
static void wctablet_queue_output(TabletChardev *tablet, uint8_t *buf, int count)
{
    if (tablet->outlen + count > sizeof(tablet->outbuf)) {
        return;
    }

    memcpy(tablet->outbuf + tablet->outlen, buf, count);
    tablet->outlen += count;
    wctablet_chr_accept_input(CHARDEV(tablet));
}
示例#14
0
static void char_udp_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    UdpChardev *s = UDP_CHARDEV(obj);

    remove_fd_in_watch(chr);
    if (s->ioc) {
        object_unref(OBJECT(s->ioc));
    }
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
示例#15
0
static void udp_chr_flush_buffer(UdpChardev *s)
{
    Chardev *chr = CHARDEV(s);

    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
        int n = MIN(s->max_size, s->bufcnt - s->bufptr);
        qemu_chr_be_write(chr, &s->buf[s->bufptr], n);
        s->bufptr += n;
        s->max_size = qemu_chr_be_can_write(chr);
    }
}
示例#16
0
static gboolean pty_chr_timer(gpointer opaque)
{
    struct Chardev *chr = CHARDEV(opaque);
    PtyChardev *s = PTY_CHARDEV(opaque);

    pty_chr_timer_cancel(s);
    if (!s->connected) {
        /* Next poll ... */
        qemu_chr_be_update_read_handlers(chr, chr->gcontext);
    }
    return FALSE;
}
示例#17
0
文件: char.c 项目: mdroth/qemu
static void char_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);

    if (chr->be) {
        chr->be->chr = NULL;
    }
    g_free(chr->filename);
    g_free(chr->label);
    if (chr->logfd != -1) {
        close(chr->logfd);
    }
    qemu_mutex_destroy(&chr->chr_write_lock);
}
示例#18
0
static int udp_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    UdpChardev *s = UDP_CHARDEV(opaque);

    s->max_size = qemu_chr_be_can_write(chr);

    /* If there were any stray characters in the queue process them
     * first
     */
    udp_chr_flush_buffer(s);

    return s->max_size;
}
示例#19
0
文件: char-fd.c 项目: mdroth/qemu
static void char_fd_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    FDChardev *s = FD_CHARDEV(obj);

    remove_fd_in_watch(chr);
    if (s->ioc_in) {
        object_unref(OBJECT(s->ioc_in));
    }
    if (s->ioc_out) {
        object_unref(OBJECT(s->ioc_out));
    }

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
示例#20
0
文件: char-pty.c 项目: pfliu/qemu
static gboolean pty_chr_timer(gpointer opaque)
{
    struct Chardev *chr = CHARDEV(opaque);
    PtyChardev *s = PTY_CHARDEV(opaque);

    qemu_mutex_lock(&chr->chr_write_lock);
    s->timer_src = NULL;
    g_source_unref(s->open_source);
    s->open_source = NULL;
    if (!s->connected) {
        /* Next poll ... */
        pty_chr_update_read_handler_locked(chr);
    }
    qemu_mutex_unlock(&chr->chr_write_lock);
    return FALSE;
}
示例#21
0
static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
{
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(chr);
    Error *err = NULL;

    if (qio_task_propagate_error(task, &err)) {
        check_report_connect_error(chr, err);
        error_free(err);
        goto cleanup;
    }

    s->connect_err_reported = false;
    tcp_chr_new_client(chr, sioc);

cleanup:
    object_unref(OBJECT(sioc));
}
示例#22
0
static gboolean tcp_chr_accept(QIOChannel *channel,
                               GIOCondition cond,
                               void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    QIOChannelSocket *sioc;

    sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel),
                                     NULL);
    if (!sioc) {
        return TRUE;
    }

    tcp_chr_new_client(chr, sioc);

    object_unref(OBJECT(sioc));

    return TRUE;
}
示例#23
0
static void tcp_chr_connect(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);

    g_free(chr->filename);
    chr->filename = sockaddr_to_str(
        &s->sioc->localAddr, s->sioc->localAddrLen,
        &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
        s->is_listen, s->is_telnet);

    s->connected = 1;
    if (s->ioc) {
        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
                                           tcp_chr_read_poll,
                                           tcp_chr_read,
                                           chr, NULL);
    }
    qemu_chr_be_generic_open(chr);
}
示例#24
0
static gboolean socket_reconnect_timeout(gpointer opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);
    QIOChannelSocket *sioc;

    s->reconnect_timer = 0;

    if (chr->be_open) {
        return false;
    }

    sioc = qio_channel_socket_new();
    tcp_chr_set_client_ioc_name(chr, sioc);
    qio_channel_socket_connect_async(sioc, s->addr,
                                     qemu_chr_socket_connected,
                                     chr, NULL);

    return false;
}
示例#25
0
static void tcp_chr_connect(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);

    g_free(chr->filename);
    chr->filename = sockaddr_to_str(
        &s->sioc->localAddr, s->sioc->localAddrLen,
        &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
        s->is_listen, s->is_telnet);

    s->connected = 1;
    if (s->ioc) {
        chr->gsource = io_add_watch_poll(chr, s->ioc,
                                           tcp_chr_read_poll,
                                           tcp_chr_read,
                                           chr, NULL);
    }
    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
示例#26
0
static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    UdpChardev *s = UDP_CHARDEV(opaque);
    ssize_t ret;

    if (s->max_size == 0) {
        return TRUE;
    }
    ret = qio_channel_read(
        s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
    if (ret <= 0) {
        remove_fd_in_watch(chr);
        return FALSE;
    }
    s->bufcnt = ret;
    s->bufptr = 0;
    udp_chr_flush_buffer(s);

    return TRUE;
}
示例#27
0
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
    Chardev *chr = CHARDEV(opaque);
    MuxChardev *d = MUX_CHARDEV(opaque);
    int m = d->focus;
    CharBackend *be = d->backends[m];
    int i;

    mux_chr_accept_input(opaque);

    for (i = 0; i < size; i++)
        if (mux_proc_byte(chr, d, buf[i])) {
            if (d->prod[m] == d->cons[m] &&
                be && be->chr_can_read &&
                be->chr_can_read(be->opaque)) {
                be->chr_read(be->opaque, &buf[i], 1);
            } else {
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
            }
        }
}
示例#28
0
static void mux_chr_event(void *opaque, int event)
{
    mux_chr_send_all_event(CHARDEV(opaque), event);
}