/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu-common.h"
#include "monitor/monitor.h"
#include "ui/console.h"
#include "sysemu/sysemu.h"
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "hw/usb.h"
#include "qmp-commands.h"

#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/time.h>
#include <zlib.h>

#ifndef _WIN32
#include <sys/times.h>
#include <sys/wait.h>
#include <termios.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
#include <sys/select.h>
#ifdef CONFIG_BSD
#include <sys/stat.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
#elif defined(__DragonFly__)
#include <dev/misc/ppi/ppi.h>
#include <bus/ppbus/ppbconf.h>
#endif
#else
#ifdef __linux__
#include <linux/ppdev.h>
#include <linux/parport.h>
#endif
#ifdef __sun__
#include <sys/stat.h>
#include <sys/ethernet.h>
#include <sys/sockio.h>
#include <netinet/arp.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h> // must come after ip.h
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <syslog.h>
#endif
#endif
#endif

#include "qemu/sockets.h"
#include "ui/qemu-spice.h"

#define READ_BUF_LEN 4096

/***********************************************************/
/* character device */

static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
    QTAILQ_HEAD_INITIALIZER(chardevs);

void qemu_chr_be_event(CharDriverState *s, int event)
{
    /* Keep track if the char device is open */
    switch (event) {
        case CHR_EVENT_OPENED:
            s->be_open = 1;
            break;
        case CHR_EVENT_CLOSED:
            s->be_open = 0;
            break;
    }

    if (!s->chr_event)
        return;
    s->chr_event(s->handler_opaque, event);
}

void qemu_chr_be_generic_open(CharDriverState *s)
{
    qemu_chr_be_event(s, CHR_EVENT_OPENED);
}

int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
{
    return s->chr_write(s, buf, len);
}

int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
{
    int offset = 0;
    int res;

    while (offset < len) {
        do {
            res = s->chr_write(s, buf + offset, len - offset);
            if (res == -1 && errno == EAGAIN) {
                g_usleep(100);
            }
        } while (res == -1 && errno == EAGAIN);

        if (res == 0) {
            break;
        }

        if (res < 0) {
            return res;
        }

        offset += res;
    }

    return offset;
}

int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
{
    if (!s->chr_ioctl)
        return -ENOTSUP;
    return s->chr_ioctl(s, cmd, arg);
}

int qemu_chr_be_can_write(CharDriverState *s)
{
    if (!s->chr_can_read)
        return 0;
    return s->chr_can_read(s->handler_opaque);
}

void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
{
    if (s->chr_read) {
        s->chr_read(s->handler_opaque, buf, len);
    }
}

int qemu_chr_fe_get_msgfd(CharDriverState *s)
{
    return s->get_msgfd ? s->get_msgfd(s) : -1;
}

int qemu_chr_add_client(CharDriverState *s, int fd)
{
    return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
}

void qemu_chr_accept_input(CharDriverState *s)
{
    if (s->chr_accept_input)
        s->chr_accept_input(s);
    qemu_notify_event();
}

void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
{
    char buf[READ_BUF_LEN];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
    va_end(ap);
}

void qemu_chr_add_handlers(CharDriverState *s,
                           IOCanReadHandler *fd_can_read,
                           IOReadHandler *fd_read,
                           IOEventHandler *fd_event,
                           void *opaque)
{
    int fe_open;

    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
        fe_open = 0;
    } else {
        fe_open = 1;
    }
    s->chr_can_read = fd_can_read;
    s->chr_read = fd_read;
    s->chr_event = fd_event;
    s->handler_opaque = opaque;
    if (s->chr_update_read_handler)
        s->chr_update_read_handler(s);

    if (!s->explicit_fe_open) {
        qemu_chr_fe_set_open(s, fe_open);
    }

    /* We're connecting to an already opened device, so let's make sure we
       also get the open event */
    if (fe_open && s->be_open) {
        qemu_chr_be_generic_open(s);
    }
}

static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    return len;
}

static CharDriverState *qemu_chr_open_null(void)
{
    CharDriverState *chr;

    chr = g_malloc0(sizeof(CharDriverState));
    chr->chr_write = null_chr_write;
    chr->explicit_be_open = true;
    return chr;
}

/* MUX driver for serial I/O splitting */
#define MAX_MUX 4
#define MUX_BUFFER_SIZE 32	/* Must be a power of 2.  */
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
typedef struct {
    IOCanReadHandler *chr_can_read[MAX_MUX];
    IOReadHandler *chr_read[MAX_MUX];
    IOEventHandler *chr_event[MAX_MUX];
    void *ext_opaque[MAX_MUX];
    CharDriverState *drv;
    int focus;
    int mux_cnt;
    int term_got_escape;
    int max_size;
    /* Intermediate input buffer allows to catch escape sequences even if the
       currently active device is not accepting any input - but only until it
       is full as well. */
    unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
    int prod[MAX_MUX];
    int cons[MAX_MUX];
    int timestamps;
    int linestart;
    int64_t timestamps_start;
} MuxDriver;


static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    MuxDriver *d = chr->opaque;
    int ret;
    if (!d->timestamps) {
        ret = d->drv->chr_write(d->drv, buf, len);
    } else {
        int i;

        ret = 0;
        for (i = 0; i < len; i++) {
            if (d->linestart) {
                char buf1[64];
                int64_t ti;
                int secs;

                ti = qemu_get_clock_ms(rt_clock);
                if (d->timestamps_start == -1)
                    d->timestamps_start = ti;
                ti -= d->timestamps_start;
                secs = ti / 1000;
                snprintf(buf1, sizeof(buf1),
                         "[%02d:%02d:%02d.%03d] ",
                         secs / 3600,
                         (secs / 60) % 60,
                         secs % 60,
                         (int)(ti % 1000));
                d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
                d->linestart = 0;
            }
            ret += d->drv->chr_write(d->drv, buf+i, 1);
            if (buf[i] == '\n') {
                d->linestart = 1;
            }
        }
    }
    return ret;
}

static const char * const mux_help[] = {
    "% h    print this help\n\r",
    "% x    exit emulator\n\r",
    "% s    save disk data back to file (if -snapshot)\n\r",
    "% t    toggle console timestamps\n\r"
    "% b    send break (magic sysrq)\n\r",
    "% c    switch between console and monitor\n\r",
    "% %  sends %\n\r",
    NULL
};

int term_escape_char = 0x01; /* ctrl-a is used for escape */
static void mux_print_help(CharDriverState *chr)
{
    int i, j;
    char ebuf[15] = "Escape-Char";
    char cbuf[50] = "\n\r";

    if (term_escape_char > 0 && term_escape_char < 26) {
        snprintf(cbuf, sizeof(cbuf), "\n\r");
        snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
    } else {
        snprintf(cbuf, sizeof(cbuf),
                 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
                 term_escape_char);
    }
    chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
    for (i = 0; mux_help[i] != NULL; i++) {
        for (j=0; mux_help[i][j] != '\0'; j++) {
            if (mux_help[i][j] == '%')
                chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
            else
                chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
        }
    }
}

static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
{
    if (d->chr_event[mux_nr])
        d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
}

static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
{
    if (d->term_got_escape) {
        d->term_got_escape = 0;
        if (ch == term_escape_char)
            goto send_char;
        switch(ch) {
        case '?':
        case 'h':
            mux_print_help(chr);
            break;
        case 'x':
            {
                 const char *term =  "QEMU: Terminated\n\r";
                 chr->chr_write(chr,(uint8_t *)term,strlen(term));
                 exit(0);
                 break;
            }
        case 's':
            bdrv_commit_all();
            break;
        case 'b':
            qemu_chr_be_event(chr, CHR_EVENT_BREAK);
            break;
        case 'c':
            /* Switch to the next registered device */
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
            d->focus++;
            if (d->focus >= d->mux_cnt)
                d->focus = 0;
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
            break;
        case 't':
            d->timestamps = !d->timestamps;
            d->timestamps_start = -1;
            d->linestart = 0;
            break;
        }
    } else if (ch == term_escape_char) {
        d->term_got_escape = 1;
    } else {
    send_char:
        return 1;
    }
    return 0;
}

static void mux_chr_accept_input(CharDriverState *chr)
{
    MuxDriver *d = chr->opaque;
    int m = d->focus;

    while (d->prod[m] != d->cons[m] &&
           d->chr_can_read[m] &&
           d->chr_can_read[m](d->ext_opaque[m])) {
        d->chr_read[m](d->ext_opaque[m],
                       &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
    }
}

static int mux_chr_can_read(void *opaque)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
    int m = d->focus;

    if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
        return 1;
    if (d->chr_can_read[m])
        return d->chr_can_read[m](d->ext_opaque[m]);
    return 0;
}

static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
    int m = d->focus;
    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] &&
                d->chr_can_read[m] &&
                d->chr_can_read[m](d->ext_opaque[m]))
                d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
            else
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
        }
}

static void mux_chr_event(void *opaque, int event)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
    int i;

    /* Send the event to all registered listeners */
    for (i = 0; i < d->mux_cnt; i++)
        mux_chr_send_event(d, i, event);
}

static void mux_chr_update_read_handler(CharDriverState *chr)
{
    MuxDriver *d = chr->opaque;

    if (d->mux_cnt >= MAX_MUX) {
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
        return;
    }
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
    d->chr_read[d->mux_cnt] = chr->chr_read;
    d->chr_event[d->mux_cnt] = chr->chr_event;
    /* Fix up the real driver with mux routines */
    if (d->mux_cnt == 0) {
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
                              mux_chr_event, chr);
    }
    if (d->focus != -1) {
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
    }
    d->focus = d->mux_cnt;
    d->mux_cnt++;
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
}

static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
{
    CharDriverState *chr;
    MuxDriver *d;

    chr = g_malloc0(sizeof(CharDriverState));
    d = g_malloc0(sizeof(MuxDriver));

    chr->opaque = d;
    d->drv = drv;
    d->focus = -1;
    chr->chr_write = mux_chr_write;
    chr->chr_update_read_handler = mux_chr_update_read_handler;
    chr->chr_accept_input = mux_chr_accept_input;
    /* Frontend guest-open / -close notification is not support with muxes */
    chr->chr_set_fe_open = NULL;

    return chr;
}


#ifdef _WIN32
int send_all(int fd, const void *buf, int len1)
{
    int ret, len;

    len = len1;
    while (len > 0) {
        ret = send(fd, buf, len, 0);
        if (ret < 0) {
            errno = WSAGetLastError();
            if (errno != WSAEWOULDBLOCK) {
                return -1;
            }
        } else if (ret == 0) {
            break;
        } else {
            buf += ret;
            len -= ret;
        }
    }
    return len1 - len;
}

#else

int send_all(int fd, const void *_buf, int len1)
{
    int ret, len;
    const uint8_t *buf = _buf;

    len = len1;
    while (len > 0) {
        ret = write(fd, buf, len);
        if (ret < 0) {
            if (errno != EINTR && errno != EAGAIN)
                return -1;
        } else if (ret == 0) {
            break;
        } else {
            buf += ret;
            len -= ret;
        }
    }
    return len1 - len;
}

int recv_all(int fd, void *_buf, int len1, bool single_read)
{
    int ret, len;
    uint8_t *buf = _buf;

    len = len1;
    while ((len > 0) && (ret = read(fd, buf, len)) != 0) {
        if (ret < 0) {
            if (errno != EINTR && errno != EAGAIN) {
                return -1;
            }
            continue;
        } else {
            if (single_read) {
                return ret;
            }
            buf += ret;
            len -= ret;
        }
    }
    return len1 - len;
}

#endif /* !_WIN32 */

typedef struct IOWatchPoll
{
    GSource parent;

    GIOChannel *channel;
    GSource *src;

    IOCanReadHandler *fd_can_read;
    GSourceFunc fd_read;
    void *opaque;
} IOWatchPoll;

static IOWatchPoll *io_watch_poll_from_source(GSource *source)
{
    return container_of(source, IOWatchPoll, parent);
}

static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
{
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
    bool was_active = iwp->src != NULL;
    if (was_active == now_active) {
        return FALSE;
    }

    if (now_active) {
        iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
        g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
        g_source_attach(iwp->src, NULL);
    } else {
        g_source_destroy(iwp->src);
        g_source_unref(iwp->src);
        iwp->src = NULL;
    }
    return FALSE;
}

static gboolean io_watch_poll_check(GSource *source)
{
    return FALSE;
}

static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
                                       gpointer user_data)
{
    abort();
}

static void io_watch_poll_finalize(GSource *source)
{
    /* Due to a glib bug, removing the last reference to a source
     * inside a finalize callback causes recursive locking (and a
     * deadlock).  This is not a problem inside other callbacks,
     * including dispatch callbacks, so we call io_remove_watch_poll
     * to remove this source.  At this point, iwp->src must
     * be NULL, or we would leak it.
     *
     * This would be solved much more elegantly by child sources,
     * but we support older glib versions that do not have them.
     */
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
    assert(iwp->src == NULL);
}

static GSourceFuncs io_watch_poll_funcs = {
    .prepare = io_watch_poll_prepare,
    .check = io_watch_poll_check,
    .dispatch = io_watch_poll_dispatch,
    .finalize = io_watch_poll_finalize,
};

/* Can only be used for read */
static guint io_add_watch_poll(GIOChannel *channel,
                               IOCanReadHandler *fd_can_read,
                               GIOFunc fd_read,
                               gpointer user_data)
{
    IOWatchPoll *iwp;
    int tag;

    iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll));
    iwp->fd_can_read = fd_can_read;
    iwp->opaque = user_data;
    iwp->channel = channel;
    iwp->fd_read = (GSourceFunc) fd_read;
    iwp->src = NULL;

    tag = g_source_attach(&iwp->parent, NULL);
    g_source_unref(&iwp->parent);
    return tag;
}

static void io_remove_watch_poll(guint tag)
{
    GSource *source;
    IOWatchPoll *iwp;

    g_return_if_fail (tag > 0);

    source = g_main_context_find_source_by_id(NULL, tag);
    g_return_if_fail (source != NULL);

    iwp = io_watch_poll_from_source(source);
    if (iwp->src) {
        g_source_destroy(iwp->src);
        g_source_unref(iwp->src);
        iwp->src = NULL;
    }
    g_source_destroy(&iwp->parent);
}

#ifndef _WIN32
static GIOChannel *io_channel_from_fd(int fd)
{
    GIOChannel *chan;

    if (fd == -1) {
        return NULL;
    }

    chan = g_io_channel_unix_new(fd);

    g_io_channel_set_encoding(chan, NULL, NULL);
    g_io_channel_set_buffered(chan, FALSE);

    return chan;
}
#endif

static GIOChannel *io_channel_from_socket(int fd)
{
    GIOChannel *chan;

    if (fd == -1) {
        return NULL;
    }

#ifdef _WIN32
    chan = g_io_channel_win32_new_socket(fd);
#else
    chan = g_io_channel_unix_new(fd);
#endif

    g_io_channel_set_encoding(chan, NULL, NULL);
    g_io_channel_set_buffered(chan, FALSE);

    return chan;
}

static int io_channel_send(GIOChannel *fd, const void *buf, size_t len)
{
    GIOStatus status;
    size_t offset;

    offset = 0;
    while (offset < len) {
        gsize bytes_written;

        status = g_io_channel_write_chars(fd, buf + offset, len - offset,
                                          &bytes_written, NULL);
        if (status != G_IO_STATUS_NORMAL) {
            if (status == G_IO_STATUS_AGAIN) {
                /* If we've written any data, return a partial write. */
                if (offset) {
                    break;
                }
                errno = EAGAIN;
            } else {
                errno = EINVAL;
            }

            return -1;
        } else if (status == G_IO_STATUS_EOF) {
            break;
        }

        offset += bytes_written;
    }

    return offset;
}

#ifndef _WIN32

typedef struct FDCharDriver {
    CharDriverState *chr;
    GIOChannel *fd_in, *fd_out;
    guint fd_in_tag;
    int max_size;
    QTAILQ_ENTRY(FDCharDriver) node;
} FDCharDriver;

static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    FDCharDriver *s = chr->opaque;
    
    return io_channel_send(s->fd_out, buf, len);
}

static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
    CharDriverState *chr = opaque;
    FDCharDriver *s = chr->opaque;
    int len;
    uint8_t buf[READ_BUF_LEN];
    GIOStatus status;
    gsize bytes_read;

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

    status = g_io_channel_read_chars(chan, (gchar *)buf,
                                     len, &bytes_read, NULL);
    if (status == G_IO_STATUS_EOF) {
        if (s->fd_in_tag) {
            io_remove_watch_poll(s->fd_in_tag);
            s->fd_in_tag = 0;
        }
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
        return FALSE;
    }
    if (status == G_IO_STATUS_NORMAL) {
        qemu_chr_be_write(chr, buf, bytes_read);
    }

    return TRUE;
}

static int fd_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    FDCharDriver *s = chr->opaque;

    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}

static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    FDCharDriver *s = chr->opaque;
    return g_io_create_watch(s->fd_out, cond);
}

static void fd_chr_update_read_handler(CharDriverState *chr)
{
    FDCharDriver *s = chr->opaque;

    if (s->fd_in_tag) {
        io_remove_watch_poll(s->fd_in_tag);
        s->fd_in_tag = 0;
    }

    if (s->fd_in) {
        s->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, fd_chr_read, chr);
    }
}

static void fd_chr_close(struct CharDriverState *chr)
{
    FDCharDriver *s = chr->opaque;

    if (s->fd_in_tag) {
        io_remove_watch_poll(s->fd_in_tag);
        s->fd_in_tag = 0;
    }

    if (s->fd_in) {
        g_io_channel_unref(s->fd_in);
    }
    if (s->fd_out) {
        g_io_channel_unref(s->fd_out);
    }

    g_free(s);
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

/* open a character device to a unix fd */
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
{
    CharDriverState *chr;
    FDCharDriver *s;

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(FDCharDriver));
    s->fd_in = io_channel_from_fd(fd_in);
    s->fd_out = io_channel_from_fd(fd_out);
    fcntl(fd_out, F_SETFL, O_NONBLOCK);
    s->chr = chr;
    chr->opaque = s;
    chr->chr_add_watch = fd_chr_add_watch;
    chr->chr_write = fd_chr_write;
    chr->chr_update_read_handler = fd_chr_update_read_handler;
    chr->chr_close = fd_chr_close;

    return chr;
}

static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
{
    int fd_in, fd_out;
    char filename_in[256], filename_out[256];
    const char *filename = opts->device;

    if (filename == NULL) {
        fprintf(stderr, "chardev: pipe: no filename given\n");
        return NULL;
    }

    snprintf(filename_in, 256, "%s.in", filename);
    snprintf(filename_out, 256, "%s.out", filename);
    TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
    TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
    if (fd_in < 0 || fd_out < 0) {
	if (fd_in >= 0)
	    close(fd_in);
	if (fd_out >= 0)
	    close(fd_out);
        TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
        if (fd_in < 0) {
            return NULL;
        }
    }
    return qemu_chr_open_fd(fd_in, fd_out);
}

/* init terminal so that we can grab keys */
static struct termios oldtty;
static int old_fd0_flags;
static bool stdio_allow_signal;

static void term_exit(void)
{
    tcsetattr (0, TCSANOW, &oldtty);
    fcntl(0, F_SETFL, old_fd0_flags);
}

static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
{
    struct termios tty;

    tty = oldtty;
    if (!echo) {
        tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                          |INLCR|IGNCR|ICRNL|IXON);
        tty.c_oflag |= OPOST;
        tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
        tty.c_cflag &= ~(CSIZE|PARENB);
        tty.c_cflag |= CS8;
        tty.c_cc[VMIN] = 1;
        tty.c_cc[VTIME] = 0;
    }
    /* if graphical mode, we allow Ctrl-C handling */
    if (!stdio_allow_signal)
        tty.c_lflag &= ~ISIG;

    tcsetattr (0, TCSANOW, &tty);
}

static void qemu_chr_close_stdio(struct CharDriverState *chr)
{
    term_exit();
    fd_chr_close(chr);
}

static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
{
    CharDriverState *chr;

    if (is_daemonized()) {
        error_report("cannot use stdio with -daemonize");
        return NULL;
    }
    old_fd0_flags = fcntl(0, F_GETFL);
    tcgetattr (0, &oldtty);
    fcntl(0, F_SETFL, O_NONBLOCK);
    atexit(term_exit);

    chr = qemu_chr_open_fd(0, 1);
    chr->chr_close = qemu_chr_close_stdio;
    chr->chr_set_echo = qemu_chr_set_echo_stdio;
    stdio_allow_signal = display_type != DT_NOGRAPHIC;
    if (opts->has_signal) {
        stdio_allow_signal = opts->signal;
    }
    qemu_chr_fe_set_echo(chr, false);

    return chr;
}

#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
    || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
    || defined(__GLIBC__)

#define HAVE_CHARDEV_TTY 1

typedef struct {
    GIOChannel *fd;
    guint fd_tag;
    int connected;
    int read_bytes;
    guint timer_tag;
} PtyCharDriver;

static void pty_chr_update_read_handler(CharDriverState *chr);
static void pty_chr_state(CharDriverState *chr, int connected);

static gboolean pty_chr_timer(gpointer opaque)
{
    struct CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;

    if (s->connected) {
        goto out;
    }

    /* Next poll ... */
    pty_chr_update_read_handler(chr);

out:
    s->timer_tag = 0;
    return FALSE;
}

static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
{
    PtyCharDriver *s = chr->opaque;

    if (s->timer_tag) {
        g_source_remove(s->timer_tag);
        s->timer_tag = 0;
    }

    if (ms == 1000) {
        s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
    } else {
        s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
    }
}

static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    PtyCharDriver *s = chr->opaque;

    if (!s->connected) {
        /* guest sends data, check for (re-)connect */
        pty_chr_update_read_handler(chr);
        return 0;
    }
    return io_channel_send(s->fd, buf, len);
}

static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    PtyCharDriver *s = chr->opaque;
    return g_io_create_watch(s->fd, cond);
}

static int pty_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;

    s->read_bytes = qemu_chr_be_can_write(chr);
    return s->read_bytes;
}

static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
    CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;
    gsize size, len;
    uint8_t buf[READ_BUF_LEN];
    GIOStatus status;

    len = sizeof(buf);
    if (len > s->read_bytes)
        len = s->read_bytes;
    if (len == 0) {
        return TRUE;
    }
    status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL);
    if (status != G_IO_STATUS_NORMAL) {
        pty_chr_state(chr, 0);
        return FALSE;
    } else {
        pty_chr_state(chr, 1);
        qemu_chr_be_write(chr, buf, size);
    }
    return TRUE;
}

static void pty_chr_update_read_handler(CharDriverState *chr)
{
    PtyCharDriver *s = chr->opaque;
    GPollFD pfd;

    pfd.fd = g_io_channel_unix_get_fd(s->fd);
    pfd.events = G_IO_OUT;
    pfd.revents = 0;
    g_poll(&pfd, 1, 0);
    if (pfd.revents & G_IO_HUP) {
        pty_chr_state(chr, 0);
    } else {
        pty_chr_state(chr, 1);
    }
}

static void pty_chr_state(CharDriverState *chr, int connected)
{
    PtyCharDriver *s = chr->opaque;

    if (!connected) {
        if (s->fd_tag) {
            io_remove_watch_poll(s->fd_tag);
            s->fd_tag = 0;
        }
        s->connected = 0;
        /* (re-)connect poll interval for idle guests: once per second.
         * We check more frequently in case the guests sends data to
         * the virtual device linked to our pty. */
        pty_chr_rearm_timer(chr, 1000);
    } else {
        if (s->timer_tag) {
            g_source_remove(s->timer_tag);
            s->timer_tag = 0;
        }
        if (!s->connected) {
            qemu_chr_be_generic_open(chr);
            s->connected = 1;
            s->fd_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, pty_chr_read, chr);
        }
    }
}


static void pty_chr_close(struct CharDriverState *chr)
{
    PtyCharDriver *s = chr->opaque;
    int fd;

    if (s->fd_tag) {
        io_remove_watch_poll(s->fd_tag);
        s->fd_tag = 0;
    }
    fd = g_io_channel_unix_get_fd(s->fd);
    g_io_channel_unref(s->fd);
    close(fd);
    if (s->timer_tag) {
        g_source_remove(s->timer_tag);
        s->timer_tag = 0;
    }
    g_free(s);
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

static CharDriverState *qemu_chr_open_pty(const char *id,
                                          ChardevReturn *ret)
{
    CharDriverState *chr;
    PtyCharDriver *s;
    int master_fd, slave_fd;
    char pty_name[PATH_MAX];

    master_fd = qemu_openpty_raw(&slave_fd, pty_name);
    if (master_fd < 0) {
        return NULL;
    }

    close(slave_fd);

    chr = g_malloc0(sizeof(CharDriverState));

    chr->filename = g_strdup_printf("pty:%s", pty_name);
    ret->pty = g_strdup(pty_name);
    ret->has_pty = true;

    fprintf(stderr, "char device redirected to %s (label %s)\n",
            pty_name, id);

    s = g_malloc0(sizeof(PtyCharDriver));
    chr->opaque = s;
    chr->chr_write = pty_chr_write;
    chr->chr_update_read_handler = pty_chr_update_read_handler;
    chr->chr_close = pty_chr_close;
    chr->chr_add_watch = pty_chr_add_watch;
    chr->explicit_be_open = true;

    s->fd = io_channel_from_fd(master_fd);
    s->timer_tag = 0;

    return chr;
}

static void tty_serial_init(int fd, int speed,
                            int parity, int data_bits, int stop_bits)
{
    struct termios tty;
    speed_t spd;

#if 0
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
           speed, parity, data_bits, stop_bits);
#endif
    tcgetattr (fd, &tty);

#define check_speed(val) if (speed <= val) { spd = B##val; break; }
    speed = speed * 10 / 11;
    do {
        check_speed(50);
        check_speed(75);
        check_speed(110);
        check_speed(134);
        check_speed(150);
        check_speed(200);
        check_speed(300);
        check_speed(600);
        check_speed(1200);
        check_speed(1800);
        check_speed(2400);
        check_speed(4800);
        check_speed(9600);
        check_speed(19200);
        check_speed(38400);
        /* Non-Posix values follow. They may be unsupported on some systems. */
        check_speed(57600);
        check_speed(115200);
#ifdef B230400
        check_speed(230400);
#endif
#ifdef B460800
        check_speed(460800);
#endif
#ifdef B500000
        check_speed(500000);
#endif
#ifdef B576000
        check_speed(576000);
#endif
#ifdef B921600
        check_speed(921600);
#endif
#ifdef B1000000
        check_speed(1000000);
#endif
#ifdef B1152000
        check_speed(1152000);
#endif
#ifdef B1500000
        check_speed(1500000);
#endif
#ifdef B2000000
        check_speed(2000000);
#endif
#ifdef B2500000
        check_speed(2500000);
#endif
#ifdef B3000000
        check_speed(3000000);
#endif
#ifdef B3500000
        check_speed(3500000);
#endif
#ifdef B4000000
        check_speed(4000000);
#endif
        spd = B115200;
    } while (0);

    cfsetispeed(&tty, spd);
    cfsetospeed(&tty, spd);

    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                          |INLCR|IGNCR|ICRNL|IXON);
    tty.c_oflag |= OPOST;
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
    switch(data_bits) {
    default:
    case 8:
        tty.c_cflag |= CS8;
        break;
    case 7:
        tty.c_cflag |= CS7;
        break;
    case 6:
        tty.c_cflag |= CS6;
        break;
    case 5:
        tty.c_cflag |= CS5;
        break;
    }
    switch(parity) {
    default:
    case 'N':
        break;
    case 'E':
        tty.c_cflag |= PARENB;
        break;
    case 'O':
        tty.c_cflag |= PARENB | PARODD;
        break;
    }
    if (stop_bits == 2)
        tty.c_cflag |= CSTOPB;

    tcsetattr (fd, TCSANOW, &tty);
}

static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
{
    FDCharDriver *s = chr->opaque;

    switch(cmd) {
    case CHR_IOCTL_SERIAL_SET_PARAMS:
        {
            QEMUSerialSetParams *ssp = arg;
            tty_serial_init(g_io_channel_unix_get_fd(s->fd_in),
                            ssp->speed, ssp->parity,
                            ssp->data_bits, ssp->stop_bits);
        }
        break;
    case CHR_IOCTL_SERIAL_SET_BREAK:
        {
            int enable = *(int *)arg;
            if (enable) {
                tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1);
            }
        }
        break;
    case CHR_IOCTL_SERIAL_GET_TIOCM:
        {
            int sarg = 0;
            int *targ = (int *)arg;
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg);
            *targ = 0;
            if (sarg & TIOCM_CTS)
                *targ |= CHR_TIOCM_CTS;
            if (sarg & TIOCM_CAR)
                *targ |= CHR_TIOCM_CAR;
            if (sarg & TIOCM_DSR)
                *targ |= CHR_TIOCM_DSR;
            if (sarg & TIOCM_RI)
                *targ |= CHR_TIOCM_RI;
            if (sarg & TIOCM_DTR)
                *targ |= CHR_TIOCM_DTR;
            if (sarg & TIOCM_RTS)
                *targ |= CHR_TIOCM_RTS;
        }
        break;
    case CHR_IOCTL_SERIAL_SET_TIOCM:
        {
            int sarg = *(int *)arg;
            int targ = 0;
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ);
            targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
                     | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
            if (sarg & CHR_TIOCM_CTS)
                targ |= TIOCM_CTS;
            if (sarg & CHR_TIOCM_CAR)
                targ |= TIOCM_CAR;
            if (sarg & CHR_TIOCM_DSR)
                targ |= TIOCM_DSR;
            if (sarg & CHR_TIOCM_RI)
                targ |= TIOCM_RI;
            if (sarg & CHR_TIOCM_DTR)
                targ |= TIOCM_DTR;
            if (sarg & CHR_TIOCM_RTS)
                targ |= TIOCM_RTS;
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ);
        }
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

static void qemu_chr_close_tty(CharDriverState *chr)
{
    FDCharDriver *s = chr->opaque;
    int fd = -1;

    if (s) {
        fd = g_io_channel_unix_get_fd(s->fd_in);
    }

    fd_chr_close(chr);

    if (fd >= 0) {
        close(fd);
    }
}

static CharDriverState *qemu_chr_open_tty_fd(int fd)
{
    CharDriverState *chr;

    tty_serial_init(fd, 115200, 'N', 8, 1);
    chr = qemu_chr_open_fd(fd, fd);
    chr->chr_ioctl = tty_serial_ioctl;
    chr->chr_close = qemu_chr_close_tty;
    return chr;
}
#endif /* __linux__ || __sun__ */

#if defined(__linux__)

#define HAVE_CHARDEV_PARPORT 1

typedef struct {
    int fd;
    int mode;
} ParallelCharDriver;

static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
{
    if (s->mode != mode) {
	int m = mode;
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
            return 0;
	s->mode = mode;
    }
    return 1;
}

static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
    ParallelCharDriver *drv = chr->opaque;
    int fd = drv->fd;
    uint8_t b;

    switch(cmd) {
    case CHR_IOCTL_PP_READ_DATA:
        if (ioctl(fd, PPRDATA, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_WRITE_DATA:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPWDATA, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_CONTROL:
        if (ioctl(fd, PPRCONTROL, &b) < 0)
            return -ENOTSUP;
	/* Linux gives only the lowest bits, and no way to know data
	   direction! For better compatibility set the fixed upper
	   bits. */
        *(uint8_t *)arg = b | 0xc0;
        break;
    case CHR_IOCTL_PP_WRITE_CONTROL:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPWCONTROL, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_STATUS:
        if (ioctl(fd, PPRSTATUS, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_DATA_DIR:
        if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_EPP_READ_ADDR:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
	    struct ParallelIOArg *parg = arg;
	    int n = read(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_READ:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
	    struct ParallelIOArg *parg = arg;
	    int n = read(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
	    struct ParallelIOArg *parg = arg;
	    int n = write(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_WRITE:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
	    struct ParallelIOArg *parg = arg;
	    int n = write(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

static void pp_close(CharDriverState *chr)
{
    ParallelCharDriver *drv = chr->opaque;
    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);
}

static CharDriverState *qemu_chr_open_pp_fd(int fd)
{
    CharDriverState *chr;
    ParallelCharDriver *drv;

    if (ioctl(fd, PPCLAIM) < 0) {
        close(fd);
        return NULL;
    }

    drv = g_malloc0(sizeof(ParallelCharDriver));
    drv->fd = fd;
    drv->mode = IEEE1284_MODE_COMPAT;

    chr = g_malloc0(sizeof(CharDriverState));
    chr->chr_write = null_chr_write;
    chr->chr_ioctl = pp_ioctl;
    chr->chr_close = pp_close;
    chr->opaque = drv;

    return chr;
}
#endif /* __linux__ */

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)

#define HAVE_CHARDEV_PARPORT 1

static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
    int fd = (int)(intptr_t)chr->opaque;
    uint8_t b;

    switch(cmd) {
    case CHR_IOCTL_PP_READ_DATA:
        if (ioctl(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)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_CONTROL:
        if (ioctl(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)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_STATUS:
        if (ioctl(fd, PPIGSTATUS, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

static CharDriverState *qemu_chr_open_pp_fd(int fd)
{
    CharDriverState *chr;

    chr = g_malloc0(sizeof(CharDriverState));
    chr->opaque = (void *)(intptr_t)fd;
    chr->chr_write = null_chr_write;
    chr->chr_ioctl = pp_ioctl;
    chr->explicit_be_open = true;
    return chr;
}
#endif

#else /* _WIN32 */

typedef struct {
    int max_size;
    HANDLE hcom, hrecv, hsend;
    OVERLAPPED orecv, osend;
    BOOL fpipe;
    DWORD len;
} WinCharState;

typedef struct {
    HANDLE  hStdIn;
    HANDLE  hInputReadyEvent;
    HANDLE  hInputDoneEvent;
    HANDLE  hInputThread;
    uint8_t win_stdio_buf;
} WinStdioCharState;

#define NSENDBUF 2048
#define NRECVBUF 2048
#define MAXCONNECT 1
#define NTIMEOUT 5000

static int win_chr_poll(void *opaque);
static int win_chr_pipe_poll(void *opaque);

static void win_chr_close(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

    if (s->hsend) {
        CloseHandle(s->hsend);
        s->hsend = NULL;
    }
    if (s->hrecv) {
        CloseHandle(s->hrecv);
        s->hrecv = NULL;
    }
    if (s->hcom) {
        CloseHandle(s->hcom);
        s->hcom = NULL;
    }
    if (s->fpipe)
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
    else
        qemu_del_polling_cb(win_chr_poll, chr);

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

static int win_chr_init(CharDriverState *chr, const char *filename)
{
    WinCharState *s = chr->opaque;
    COMMCONFIG comcfg;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
    COMSTAT comstat;
    DWORD size;
    DWORD err;

    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hsend) {
        fprintf(stderr, "Failed CreateEvent\n");
        goto fail;
    }
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hrecv) {
        fprintf(stderr, "Failed CreateEvent\n");
        goto fail;
    }

    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if (s->hcom == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
        s->hcom = NULL;
        goto fail;
    }

    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
        fprintf(stderr, "Failed SetupComm\n");
        goto fail;
    }

    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
    size = sizeof(COMMCONFIG);
    GetDefaultCommConfig(filename, &comcfg, &size);
    comcfg.dcb.DCBlength = sizeof(DCB);
    CommConfigDialog(filename, NULL, &comcfg);

    if (!SetCommState(s->hcom, &comcfg.dcb)) {
        fprintf(stderr, "Failed SetCommState\n");
        goto fail;
    }

    if (!SetCommMask(s->hcom, EV_ERR)) {
        fprintf(stderr, "Failed SetCommMask\n");
        goto fail;
    }

    cto.ReadIntervalTimeout = MAXDWORD;
    if (!SetCommTimeouts(s->hcom, &cto)) {
        fprintf(stderr, "Failed SetCommTimeouts\n");
        goto fail;
    }

    if (!ClearCommError(s->hcom, &err, &comstat)) {
        fprintf(stderr, "Failed ClearCommError\n");
        goto fail;
    }
    qemu_add_polling_cb(win_chr_poll, chr);
    return 0;

 fail:
    win_chr_close(chr);
    return -1;
}

static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
{
    WinCharState *s = chr->opaque;
    DWORD len, ret, size, err;

    len = len1;
    ZeroMemory(&s->osend, sizeof(s->osend));
    s->osend.hEvent = s->hsend;
    while (len > 0) {
        if (s->hsend)
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
        else
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
        if (!ret) {
            err = GetLastError();
            if (err == ERROR_IO_PENDING) {
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
                if (ret) {
                    buf += size;
                    len -= size;
                } else {
                    break;
                }
            } else {
                break;
            }
        } else {
            buf += size;
            len -= size;
        }
    }
    return len1 - len;
}

static int win_chr_read_poll(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}

static void win_chr_readfile(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;
    int ret, err;
    uint8_t buf[READ_BUF_LEN];
    DWORD size;

    ZeroMemory(&s->orecv, sizeof(s->orecv));
    s->orecv.hEvent = s->hrecv;
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
    if (!ret) {
        err = GetLastError();
        if (err == ERROR_IO_PENDING) {
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
        }
    }

    if (size > 0) {
        qemu_chr_be_write(chr, buf, size);
    }
}

static void win_chr_read(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

    if (s->len > s->max_size)
        s->len = s->max_size;
    if (s->len == 0)
        return;

    win_chr_readfile(chr);
}

static int win_chr_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    WinCharState *s = chr->opaque;
    COMSTAT status;
    DWORD comerr;

    ClearCommError(s->hcom, &comerr, &status);
    if (status.cbInQue > 0) {
        s->len = status.cbInQue;
        win_chr_read_poll(chr);
        win_chr_read(chr);
        return 1;
    }
    return 0;
}

static CharDriverState *qemu_chr_open_win_path(const char *filename)
{
    CharDriverState *chr;
    WinCharState *s;

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(WinCharState));
    chr->opaque = s;
    chr->chr_write = win_chr_write;
    chr->chr_close = win_chr_close;

    if (win_chr_init(chr, filename) < 0) {
        g_free(s);
        g_free(chr);
        return NULL;
    }
    return chr;
}

static int win_chr_pipe_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    WinCharState *s = chr->opaque;
    DWORD size;

    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
    if (size > 0) {
        s->len = size;
        win_chr_read_poll(chr);
        win_chr_read(chr);
        return 1;
    }
    return 0;
}

static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
{
    WinCharState *s = chr->opaque;
    OVERLAPPED ov;
    int ret;
    DWORD size;
    char openname[256];

    s->fpipe = TRUE;

    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hsend) {
        fprintf(stderr, "Failed CreateEvent\n");
        goto fail;
    }
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hrecv) {
        fprintf(stderr, "Failed CreateEvent\n");
        goto fail;
    }

    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
                              PIPE_WAIT,
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
    if (s->hcom == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
        s->hcom = NULL;
        goto fail;
    }

    ZeroMemory(&ov, sizeof(ov));
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    ret = ConnectNamedPipe(s->hcom, &ov);
    if (ret) {
        fprintf(stderr, "Failed ConnectNamedPipe\n");
        goto fail;
    }

    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
    if (!ret) {
        fprintf(stderr, "Failed GetOverlappedResult\n");
        if (ov.hEvent) {
            CloseHandle(ov.hEvent);
            ov.hEvent = NULL;
        }
        goto fail;
    }

    if (ov.hEvent) {
        CloseHandle(ov.hEvent);
        ov.hEvent = NULL;
    }
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
    return 0;

 fail:
    win_chr_close(chr);
    return -1;
}


static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
{
    const char *filename = opts->device;
    CharDriverState *chr;
    WinCharState *s;

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(WinCharState));
    chr->opaque = s;
    chr->chr_write = win_chr_write;
    chr->chr_close = win_chr_close;

    if (win_chr_pipe_init(chr, filename) < 0) {
        g_free(s);
        g_free(chr);
        return NULL;
    }
    return chr;
}

static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
{
    CharDriverState *chr;
    WinCharState *s;

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(WinCharState));
    s->hcom = fd_out;
    chr->opaque = s;
    chr->chr_write = win_chr_write;
    return chr;
}

static CharDriverState *qemu_chr_open_win_con(void)
{
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
}

static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD   dwSize;
    int     len1;

    len1 = len;

    while (len1 > 0) {
        if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
            break;
        }
        buf  += dwSize;
        len1 -= dwSize;
    }

    return len - len1;
}

static void win_stdio_wait_func(void *opaque)
{
    CharDriverState   *chr   = opaque;
    WinStdioCharState *stdio = chr->opaque;
    INPUT_RECORD       buf[4];
    int                ret;
    DWORD              dwSize;
    int                i;

    ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf),
                           &dwSize);

    if (!ret) {
        /* Avoid error storm */
        qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
        return;
    }

    for (i = 0; i < dwSize; i++) {
        KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;

        if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
            int j;
            if (kev->uChar.AsciiChar != 0) {
                for (j = 0; j < kev->wRepeatCount; j++) {
                    if (qemu_chr_be_can_write(chr)) {
                        uint8_t c = kev->uChar.AsciiChar;
                        qemu_chr_be_write(chr, &c, 1);
                    }
                }
            }
        }
    }
}

static DWORD WINAPI win_stdio_thread(LPVOID param)
{
    CharDriverState   *chr   = param;
    WinStdioCharState *stdio = chr->opaque;
    int                ret;
    DWORD              dwSize;

    while (1) {

        /* Wait for one byte */
        ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);

        /* Exit in case of error, continue if nothing read */
        if (!ret) {
            break;
        }
        if (!dwSize) {
            continue;
        }

        /* Some terminal emulator returns \r\n for Enter, just pass \n */
        if (stdio->win_stdio_buf == '\r') {
            continue;
        }

        /* Signal the main thread and wait until the byte was eaten */
        if (!SetEvent(stdio->hInputReadyEvent)) {
            break;
        }
        if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
            != WAIT_OBJECT_0) {
            break;
        }
    }

    qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
    return 0;
}

static void win_stdio_thread_wait_func(void *opaque)
{
    CharDriverState   *chr   = opaque;
    WinStdioCharState *stdio = chr->opaque;

    if (qemu_chr_be_can_write(chr)) {
        qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
    }

    SetEvent(stdio->hInputDoneEvent);
}

static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
{
    WinStdioCharState *stdio  = chr->opaque;
    DWORD              dwMode = 0;

    GetConsoleMode(stdio->hStdIn, &dwMode);

    if (echo) {
        SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
    } else {
        SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
    }
}

static void win_stdio_close(CharDriverState *chr)
{
    WinStdioCharState *stdio = chr->opaque;

    if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
        CloseHandle(stdio->hInputReadyEvent);
    }
    if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
        CloseHandle(stdio->hInputDoneEvent);
    }
    if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
        TerminateThread(stdio->hInputThread, 0);
    }

    g_free(chr->opaque);
    g_free(chr);
}

static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
{
    CharDriverState   *chr;
    WinStdioCharState *stdio;
    DWORD              dwMode;
    int                is_console = 0;

    chr   = g_malloc0(sizeof(CharDriverState));
    stdio = g_malloc0(sizeof(WinStdioCharState));

    stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "cannot open stdio: invalid handle\n");
        exit(1);
    }

    is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;

    chr->opaque    = stdio;
    chr->chr_write = win_stdio_write;
    chr->chr_close = win_stdio_close;

    if (is_console) {
        if (qemu_add_wait_object(stdio->hStdIn,
                                 win_stdio_wait_func, chr)) {
            fprintf(stderr, "qemu_add_wait_object: failed\n");
        }
    } else {
        DWORD   dwId;
            
        stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
        stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,
                                               chr, 0, &dwId);

        if (stdio->hInputThread == INVALID_HANDLE_VALUE
            || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
            || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
            fprintf(stderr, "cannot create stdio thread or event\n");
            exit(1);
        }
        if (qemu_add_wait_object(stdio->hInputReadyEvent,
                                 win_stdio_thread_wait_func, chr)) {
            fprintf(stderr, "qemu_add_wait_object: failed\n");
        }
    }

    dwMode |= ENABLE_LINE_INPUT;

    if (is_console) {
        /* set the terminal in raw mode */
        /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
        dwMode |= ENABLE_PROCESSED_INPUT;
    }

    SetConsoleMode(stdio->hStdIn, dwMode);

    chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
    qemu_chr_fe_set_echo(chr, false);

    return chr;
}
#endif /* !_WIN32 */


/***********************************************************/
/* UDP Net console */

typedef struct {
    int fd;
    GIOChannel *chan;
    guint tag;
    uint8_t buf[READ_BUF_LEN];
    int bufcnt;
    int bufptr;
    int max_size;
} NetCharDriver;

static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    NetCharDriver *s = chr->opaque;
    gsize bytes_written;
    GIOStatus status;

    status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL);
    if (status == G_IO_STATUS_EOF) {
        return 0;
    } else if (status != G_IO_STATUS_NORMAL) {
        return -1;
    }

    return bytes_written;
}

static int udp_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    NetCharDriver *s = chr->opaque;

    s->max_size = qemu_chr_be_can_write(chr);

    /* If there were any stray characters in the queue process them
     * first
     */
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
        s->bufptr++;
        s->max_size = qemu_chr_be_can_write(chr);
    }
    return s->max_size;
}

static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
    CharDriverState *chr = opaque;
    NetCharDriver *s = chr->opaque;
    gsize bytes_read = 0;
    GIOStatus status;

    if (s->max_size == 0) {
        return TRUE;
    }
    status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf),
                                     &bytes_read, NULL);
    s->bufcnt = bytes_read;
    s->bufptr = s->bufcnt;
    if (status != G_IO_STATUS_NORMAL) {
        if (s->tag) {
            io_remove_watch_poll(s->tag);
            s->tag = 0;
        }
        return FALSE;
    }

    s->bufptr = 0;
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
        s->bufptr++;
        s->max_size = qemu_chr_be_can_write(chr);
    }

    return TRUE;
}

static void udp_chr_update_read_handler(CharDriverState *chr)
{
    NetCharDriver *s = chr->opaque;

    if (s->tag) {
        io_remove_watch_poll(s->tag);
        s->tag = 0;
    }

    if (s->chan) {
        s->tag = io_add_watch_poll(s->chan, udp_chr_read_poll, udp_chr_read, chr);
    }
}

static void udp_chr_close(CharDriverState *chr)
{
    NetCharDriver *s = chr->opaque;
    if (s->tag) {
        io_remove_watch_poll(s->tag);
        s->tag = 0;
    }
    if (s->chan) {
        g_io_channel_unref(s->chan);
        closesocket(s->fd);
    }
    g_free(s);
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

static CharDriverState *qemu_chr_open_udp_fd(int fd)
{
    CharDriverState *chr = NULL;
    NetCharDriver *s = NULL;

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(NetCharDriver));

    s->fd = fd;
    s->chan = io_channel_from_socket(s->fd);
    s->bufcnt = 0;
    s->bufptr = 0;
    chr->opaque = s;
    chr->chr_write = udp_chr_write;
    chr->chr_update_read_handler = udp_chr_update_read_handler;
    chr->chr_close = udp_chr_close;
    /* be isn't opened until we get a connection */
    chr->explicit_be_open = true;
    return chr;
}

static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
{
    Error *local_err = NULL;
    int fd = -1;

    fd = inet_dgram_opts(opts, &local_err);
    if (fd < 0) {
        return NULL;
    }
    return qemu_chr_open_udp_fd(fd);
}

/***********************************************************/
/* TCP Net console */

typedef struct {

    GIOChannel *chan, *listen_chan;
    guint tag, listen_tag;
    int fd, listen_fd;
    int connected;
    int max_size;
    int do_telnetopt;
    int do_nodelay;
    int is_unix;
    int msgfd;
} TCPCharDriver;

static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);

static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    TCPCharDriver *s = chr->opaque;
    if (s->connected) {
        return io_channel_send(s->chan, buf, len);
    } else {
        /* XXX: indicate an error ? */
        return len;
    }
}

static int tcp_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
    if (!s->connected)
        return 0;
    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}

#define IAC 255
#define IAC_BREAK 243
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
                                      TCPCharDriver *s,
                                      uint8_t *buf, int *size)
{
    /* Handle any telnet client's basic IAC options to satisfy char by
     * char mode with no echo.  All IAC options will be removed from
     * the buf and the do_telnetopt variable will be used to track the
     * state of the width of the IAC information.
     *
     * IAC commands come in sets of 3 bytes with the exception of the
     * "IAC BREAK" command and the double IAC.
     */

    int i;
    int j = 0;

    for (i = 0; i < *size; i++) {
        if (s->do_telnetopt > 1) {
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
                /* Double IAC means send an IAC */
                if (j != i)
                    buf[j] = buf[i];
                j++;
                s->do_telnetopt = 1;
            } else {
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
                    /* Handle IAC break commands by sending a serial break */
                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
                    s->do_telnetopt++;
                }
                s->do_telnetopt++;
            }
            if (s->do_telnetopt >= 4) {
                s->do_telnetopt = 1;
            }
        } else {
            if ((unsigned char)buf[i] == IAC) {
                s->do_telnetopt = 2;
            } else {
                if (j != i)
                    buf[j] = buf[i];
                j++;
            }
        }
    }
    *size = j;
}

static int tcp_get_msgfd(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    int fd = s->msgfd;
    s->msgfd = -1;
    return fd;
}

#ifndef _WIN32
static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
{
    TCPCharDriver *s = chr->opaque;
    struct cmsghdr *cmsg;

    for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
        int fd;

        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
            cmsg->cmsg_level != SOL_SOCKET ||
            cmsg->cmsg_type != SCM_RIGHTS)
            continue;

        fd = *((int *)CMSG_DATA(cmsg));
        if (fd < 0)
            continue;

        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
        qemu_set_block(fd);

#ifndef MSG_CMSG_CLOEXEC
        qemu_set_cloexec(fd);
#endif
        if (s->msgfd != -1)
            close(s->msgfd);
        s->msgfd = fd;
    }
}

static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
{
    TCPCharDriver *s = chr->opaque;
    struct msghdr msg = { NULL, };
    struct iovec iov[1];
    union {
        struct cmsghdr cmsg;
        char control[CMSG_SPACE(sizeof(int))];
    } msg_control;
    int flags = 0;
    ssize_t ret;

    iov[0].iov_base = buf;
    iov[0].iov_len = len;

    msg.msg_iov = iov;
    msg.msg_iovlen = 1;
    msg.msg_control = &msg_control;
    msg.msg_controllen = sizeof(msg_control);

#ifdef MSG_CMSG_CLOEXEC
    flags |= MSG_CMSG_CLOEXEC;
#endif
    ret = recvmsg(s->fd, &msg, flags);
    if (ret > 0 && s->is_unix) {
        unix_process_msgfd(chr, &msg);
    }

    return ret;
}
#else
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
{
    TCPCharDriver *s = chr->opaque;
    return qemu_recv(s->fd, buf, len, 0);
}
#endif

static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    TCPCharDriver *s = chr->opaque;
    return g_io_create_watch(s->chan, cond);
}

static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
    uint8_t buf[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) {
        /* connection closed */
        s->connected = 0;
        if (s->listen_chan) {
            s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
        }
        if (s->tag) {
            io_remove_watch_poll(s->tag);
            s->tag = 0;
        }
        g_io_channel_unref(s->chan);
        s->chan = NULL;
        closesocket(s->fd);
        s->fd = -1;
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
    } 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;
}

#ifndef _WIN32
CharDriverState *qemu_chr_open_eventfd(int eventfd)
{
    return qemu_chr_open_fd(eventfd, eventfd);
}
#endif

static void tcp_chr_connect(void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;

    s->connected = 1;
    if (s->chan) {
        s->tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr);
    }
    qemu_chr_be_generic_open(chr);
}

#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
static void tcp_chr_telnet_init(int fd)
{
    char buf[3];
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
    send(fd, (char *)buf, 3, 0);
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
    send(fd, (char *)buf, 3, 0);
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
    send(fd, (char *)buf, 3, 0);
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
    send(fd, (char *)buf, 3, 0);
}

static int tcp_chr_add_client(CharDriverState *chr, int fd)
{
    TCPCharDriver *s = chr->opaque;
    if (s->fd != -1)
	return -1;

    qemu_set_nonblock(fd);
    if (s->do_nodelay)
        socket_set_nodelay(fd);
    s->fd = fd;
    s->chan = io_channel_from_socket(fd);
    if (s->listen_tag) {
        g_source_remove(s->listen_tag);
        s->listen_tag = 0;
    }
    tcp_chr_connect(chr);

    return 0;
}

static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
    struct sockaddr_in saddr;
#ifndef _WIN32
    struct sockaddr_un uaddr;
#endif
    struct sockaddr *addr;
    socklen_t len;
    int fd;

    for(;;) {
#ifndef _WIN32
	if (s->is_unix) {
	    len = sizeof(uaddr);
	    addr = (struct sockaddr *)&uaddr;
	} else
#endif
	{
	    len = sizeof(saddr);
	    addr = (struct sockaddr *)&saddr;
	}
        fd = qemu_accept(s->listen_fd, addr, &len);
        if (fd < 0 && errno != EINTR) {
            s->listen_tag = 0;
            return FALSE;
        } else if (fd >= 0) {
            if (s->do_telnetopt)
                tcp_chr_telnet_init(fd);
            break;
        }
    }
    if (tcp_chr_add_client(chr, fd) < 0)
	close(fd);

    return TRUE;
}

static void tcp_chr_close(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    if (s->fd >= 0) {
        if (s->tag) {
            io_remove_watch_poll(s->tag);
            s->tag = 0;
        }
        if (s->chan) {
            g_io_channel_unref(s->chan);
        }
        closesocket(s->fd);
    }
    if (s->listen_fd >= 0) {
        if (s->listen_tag) {
            g_source_remove(s->listen_tag);
            s->listen_tag = 0;
        }
        if (s->listen_chan) {
            g_io_channel_unref(s->listen_chan);
        }
        closesocket(s->listen_fd);
    }
    g_free(s);
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
                                                bool is_listen, bool is_telnet,
                                                bool is_waitconnect,
                                                Error **errp)
{
    CharDriverState *chr = NULL;
    TCPCharDriver *s = NULL;
    char host[NI_MAXHOST], serv[NI_MAXSERV];
    const char *left = "", *right = "";
    struct sockaddr_storage ss;
    socklen_t ss_len = sizeof(ss);

    memset(&ss, 0, ss_len);
    if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
        error_setg(errp, "getsockname: %s", strerror(errno));
        return NULL;
    }

    chr = g_malloc0(sizeof(CharDriverState));
    s = g_malloc0(sizeof(TCPCharDriver));

    s->connected = 0;
    s->fd = -1;
    s->listen_fd = -1;
    s->msgfd = -1;

    chr->filename = g_malloc(256);
    switch (ss.ss_family) {
#ifndef _WIN32
    case AF_UNIX:
        s->is_unix = 1;
        snprintf(chr->filename, 256, "unix:%s%s",
                 ((struct sockaddr_un *)(&ss))->sun_path,
                 is_listen ? ",server" : "");
        break;
#endif
    case AF_INET6:
        left  = "[";
        right = "]";
        /* fall through */
    case AF_INET:
        s->do_nodelay = do_nodelay;
        getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
                    serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
        snprintf(chr->filename, 256, "%s:%s%s%s:%s%s",
                 is_telnet ? "telnet" : "tcp",
                 left, host, right, serv,
                 is_listen ? ",server" : "");
        break;
    }

    chr->opaque = s;
    chr->chr_write = tcp_chr_write;
    chr->chr_close = tcp_chr_close;
    chr->get_msgfd = tcp_get_msgfd;
    chr->chr_add_client = tcp_chr_add_client;
    chr->chr_add_watch = tcp_chr_add_watch;
    /* be isn't opened until we get a connection */
    chr->explicit_be_open = true;

    if (is_listen) {
        s->listen_fd = fd;
        s->listen_chan = io_channel_from_socket(s->listen_fd);
        s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
        if (is_telnet) {
            s->do_telnetopt = 1;
        }
    } else {
        s->connected = 1;
        s->fd = fd;
        socket_set_nodelay(fd);
        s->chan = io_channel_from_socket(s->fd);
        tcp_chr_connect(chr);
    }

    if (is_listen && is_waitconnect) {
        printf("QEMU waiting for connection on: %s\n",
               chr->filename);
        tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
        qemu_set_nonblock(s->listen_fd);
    }
    return chr;
}

static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
{
    CharDriverState *chr = NULL;
    Error *local_err = NULL;
    int fd = -1;
    int is_listen;
    int is_waitconnect;
    int do_nodelay;
    int is_unix;
    int is_telnet;

    is_listen      = qemu_opt_get_bool(opts, "server", 0);
    is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
    is_telnet      = qemu_opt_get_bool(opts, "telnet", 0);
    do_nodelay     = !qemu_opt_get_bool(opts, "delay", 1);
    is_unix        = qemu_opt_get(opts, "path") != NULL;
    if (!is_listen)
        is_waitconnect = 0;

    if (is_unix) {
        if (is_listen) {
            fd = unix_listen_opts(opts, &local_err);
        } else {
            fd = unix_connect_opts(opts, &local_err, NULL, NULL);
        }
    } else {
        if (is_listen) {
            fd = inet_listen_opts(opts, 0, &local_err);
        } else {
            fd = inet_connect_opts(opts, &local_err, NULL, NULL);
        }
    }
    if (fd < 0) {
        goto fail;
    }

    if (!is_waitconnect)
        qemu_set_nonblock(fd);

    chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
                                  is_waitconnect, &local_err);
    if (error_is_set(&local_err)) {
        goto fail;
    }
    return chr;


 fail:
    if (local_err) {
        qerror_report_err(local_err);
        error_free(local_err);
    }
    if (fd >= 0) {
        closesocket(fd);
    }
    if (chr) {
        g_free(chr->opaque);
        g_free(chr);
    }
    return NULL;
}

/*********************************************************/
/* Ring buffer chardev */

typedef struct {
    size_t size;
    size_t prod;
    size_t cons;
    uint8_t *cbuf;
} RingBufCharDriver;

static size_t ringbuf_count(const CharDriverState *chr)
{
    const RingBufCharDriver *d = chr->opaque;

    return d->prod - d->cons;
}

static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    RingBufCharDriver *d = chr->opaque;
    int i;

    if (!buf || (len < 0)) {
        return -1;
    }

    for (i = 0; i < len; i++ ) {
        d->cbuf[d->prod++ & (d->size - 1)] = buf[i];
        if (d->prod - d->cons > d->size) {
            d->cons = d->prod - d->size;
        }
    }

    return 0;
}

static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len)
{
    RingBufCharDriver *d = chr->opaque;
    int i;

    for (i = 0; i < len && d->cons != d->prod; i++) {
        buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
    }

    return i;
}

static void ringbuf_chr_close(struct CharDriverState *chr)
{
    RingBufCharDriver *d = chr->opaque;

    g_free(d->cbuf);
    g_free(d);
    chr->opaque = NULL;
}

static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
                                              Error **errp)
{
    CharDriverState *chr;
    RingBufCharDriver *d;

    chr = g_malloc0(sizeof(CharDriverState));
    d = g_malloc(sizeof(*d));

    d->size = opts->has_size ? opts->size : 65536;

    /* 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");
        goto fail;
    }

    d->prod = 0;
    d->cons = 0;
    d->cbuf = g_malloc0(d->size);

    chr->opaque = d;
    chr->chr_write = ringbuf_chr_write;
    chr->chr_close = ringbuf_chr_close;

    return chr;

fail:
    g_free(d);
    g_free(chr);
    return NULL;
}

static bool chr_is_ringbuf(const CharDriverState *chr)
{
    return chr->chr_write == ringbuf_chr_write;
}

void qmp_ringbuf_write(const char *device, const char *data,
                       bool has_format, enum DataFormat format,
                       Error **errp)
{
    CharDriverState *chr;
    const uint8_t *write_data;
    int ret;
    size_t write_count;

    chr = qemu_chr_find(device);
    if (!chr) {
        error_setg(errp, "Device '%s' not found", device);
        return;
    }

    if (!chr_is_ringbuf(chr)) {
        error_setg(errp,"%s is not a ringbuf device", device);
        return;
    }

    if (has_format && (format == DATA_FORMAT_BASE64)) {
        write_data = g_base64_decode(data, &write_count);
    } else {
        write_data = (uint8_t *)data;
        write_count = strlen(data);
    }

    ret = ringbuf_chr_write(chr, write_data, write_count);

    if (write_data != (uint8_t *)data) {
        g_free((void *)write_data);
    }

    if (ret < 0) {
        error_setg(errp, "Failed to write to device %s", device);
        return;
    }
}

char *qmp_ringbuf_read(const char *device, int64_t size,
                       bool has_format, enum DataFormat format,
                       Error **errp)
{
    CharDriverState *chr;
    uint8_t *read_data;
    size_t count;
    char *data;

    chr = qemu_chr_find(device);
    if (!chr) {
        error_setg(errp, "Device '%s' not found", device);
        return NULL;
    }

    if (!chr_is_ringbuf(chr)) {
        error_setg(errp,"%s is not a ringbuf device", device);
        return NULL;
    }

    if (size <= 0) {
        error_setg(errp, "size must be greater than zero");
        return NULL;
    }

    count = ringbuf_count(chr);
    size = size > count ? count : size;
    read_data = g_malloc(size + 1);

    ringbuf_chr_read(chr, read_data, size);

    if (has_format && (format == DATA_FORMAT_BASE64)) {
        data = g_base64_encode(read_data, size);
        g_free(read_data);
    } else {
        /*
         * FIXME should read only complete, valid UTF-8 characters up
         * to @size bytes.  Invalid sequences should be replaced by a
         * suitable replacement character.  Except when (and only
         * when) ring buffer lost characters since last read, initial
         * continuation characters should be dropped.
         */
        read_data[size] = 0;
        data = (char *)read_data;
    }

    return data;
}

QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
    char host[65], port[33], width[8], height[8];
    int pos;
    const char *p;
    QemuOpts *opts;
    Error *local_err = NULL;

    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
    if (error_is_set(&local_err)) {
        qerror_report_err(local_err);
        error_free(local_err);
        return NULL;
    }

    if (strstart(filename, "mon:", &p)) {
        filename = p;
        qemu_opt_set(opts, "mux", "on");
    }

    if (strcmp(filename, "null")    == 0 ||
        strcmp(filename, "pty")     == 0 ||
        strcmp(filename, "msmouse") == 0 ||
        strcmp(filename, "braille") == 0 ||
        strcmp(filename, "stdio")   == 0) {
        qemu_opt_set(opts, "backend", filename);
        return opts;
    }
    if (strstart(filename, "vc", &p)) {
        qemu_opt_set(opts, "backend", "vc");
        if (*p == ':') {
            if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {
                /* pixels */
                qemu_opt_set(opts, "width", width);
                qemu_opt_set(opts, "height", height);
            } else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {
                /* chars */
                qemu_opt_set(opts, "cols", width);
                qemu_opt_set(opts, "rows", height);
            } else {
                goto fail;
            }
        }
        return opts;
    }
    if (strcmp(filename, "con:") == 0) {
        qemu_opt_set(opts, "backend", "console");
        return opts;
    }
    if (strstart(filename, "COM", NULL)) {
        qemu_opt_set(opts, "backend", "serial");
        qemu_opt_set(opts, "path", filename);
        return opts;
    }
    if (strstart(filename, "file:", &p)) {
        qemu_opt_set(opts, "backend", "file");
        qemu_opt_set(opts, "path", p);
        return opts;
    }
    if (strstart(filename, "pipe:", &p)) {
        qemu_opt_set(opts, "backend", "pipe");
        qemu_opt_set(opts, "path", p);
        return opts;
    }
    if (strstart(filename, "tcp:", &p) ||
        strstart(filename, "telnet:", &p)) {
        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
            host[0] = 0;
            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
                goto fail;
        }
        qemu_opt_set(opts, "backend", "socket");
        qemu_opt_set(opts, "host", host);
        qemu_opt_set(opts, "port", port);
        if (p[pos] == ',') {
            if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
                goto fail;
        }
        if (strstart(filename, "telnet:", &p))
            qemu_opt_set(opts, "telnet", "on");
        return opts;
    }
    if (strstart(filename, "udp:", &p)) {
        qemu_opt_set(opts, "backend", "udp");
        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
            host[0] = 0;
            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
                goto fail;
            }
        }
        qemu_opt_set(opts, "host", host);
        qemu_opt_set(opts, "port", port);
        if (p[pos] == '@') {
            p += pos + 1;
            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
                host[0] = 0;
                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
                    goto fail;
                }
            }
            qemu_opt_set(opts, "localaddr", host);
            qemu_opt_set(opts, "localport", port);
        }
        return opts;
    }
    if (strstart(filename, "unix:", &p)) {
        qemu_opt_set(opts, "backend", "socket");
        if (qemu_opts_do_parse(opts, p, "path") != 0)
            goto fail;
        return opts;
    }
    if (strstart(filename, "/dev/parport", NULL) ||
        strstart(filename, "/dev/ppi", NULL)) {
        qemu_opt_set(opts, "backend", "parport");
        qemu_opt_set(opts, "path", filename);
        return opts;
    }
    if (strstart(filename, "/dev/", NULL)) {
        qemu_opt_set(opts, "backend", "tty");
        qemu_opt_set(opts, "path", filename);
        return opts;
    }

fail:
    qemu_opts_del(opts);
    return NULL;
}

static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
                                    Error **errp)
{
    const char *path = qemu_opt_get(opts, "path");

    if (path == NULL) {
        error_setg(errp, "chardev: file: no filename given");
        return;
    }
    backend->file = g_new0(ChardevFile, 1);
    backend->file->out = g_strdup(path);
}

static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
                                 Error **errp)
{
    backend->stdio = g_new0(ChardevStdio, 1);
    backend->stdio->has_signal = true;
    backend->stdio->signal =
        qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC);
}

static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
                                  Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");

    if (device == NULL) {
        error_setg(errp, "chardev: serial/tty: no device path given");
        return;
    }
    backend->serial = g_new0(ChardevHostdev, 1);
    backend->serial->device = g_strdup(device);
}

static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
                                    Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");

    if (device == NULL) {
        error_setg(errp, "chardev: parallel: no device path given");
        return;
    }
    backend->parallel = g_new0(ChardevHostdev, 1);
    backend->parallel->device = g_strdup(device);
}

static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
                                Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");

    if (device == NULL) {
        error_setg(errp, "chardev: pipe: no device path given");
        return;
    }
    backend->pipe = g_new0(ChardevHostdev, 1);
    backend->pipe->device = g_strdup(device);
}

static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
                                   Error **errp)
{
    int val;

    backend->memory = g_new0(ChardevRingbuf, 1);

    val = qemu_opt_get_number(opts, "size", 0);
    if (val != 0) {
        backend->memory->has_size = true;
        backend->memory->size = val;
    }
}

typedef struct CharDriver {
    const char *name;
    /* old, pre qapi */
    CharDriverState *(*open)(QemuOpts *opts);
    /* new, qapi-based */
    int kind;
    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
} CharDriver;

static GSList *backends;

void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *))
{
    CharDriver *s;

    s = g_malloc0(sizeof(*s));
    s->name = g_strdup(name);
    s->open = open;

    backends = g_slist_append(backends, s);
}

void register_char_driver_qapi(const char *name, int kind,
        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
{
    CharDriver *s;

    s = g_malloc0(sizeof(*s));
    s->name = g_strdup(name);
    s->kind = kind;
    s->parse = parse;

    backends = g_slist_append(backends, s);
}

CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                                    void (*init)(struct CharDriverState *s),
                                    Error **errp)
{
    CharDriver *cd;
    CharDriverState *chr;
    GSList *i;

    if (qemu_opts_id(opts) == NULL) {
        error_setg(errp, "chardev: no id specified");
        goto err;
    }

    if (qemu_opt_get(opts, "backend") == NULL) {
        error_setg(errp, "chardev: \"%s\" missing backend",
                   qemu_opts_id(opts));
        goto err;
    }
    for (i = backends; i; i = i->next) {
        cd = i->data;

        if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {
            break;
        }
    }
    if (i == NULL) {
        error_setg(errp, "chardev: backend \"%s\" not found",
                   qemu_opt_get(opts, "backend"));
        return NULL;
    }

    if (!cd->open) {
        /* using new, qapi init */
        ChardevBackend *backend = g_new0(ChardevBackend, 1);
        ChardevReturn *ret = NULL;
        const char *id = qemu_opts_id(opts);
        const char *bid = NULL;

        if (qemu_opt_get_bool(opts, "mux", 0)) {
            bid = g_strdup_printf("%s-base", id);
        }

        chr = NULL;
        backend->kind = cd->kind;
        if (cd->parse) {
            cd->parse(opts, backend, errp);
            if (error_is_set(errp)) {
                goto qapi_out;
            }
        }
        ret = qmp_chardev_add(bid ? bid : id, backend, errp);
        if (error_is_set(errp)) {
            goto qapi_out;
        }

        if (bid) {
            qapi_free_ChardevBackend(backend);
            qapi_free_ChardevReturn(ret);
            backend = g_new0(ChardevBackend, 1);
            backend->mux = g_new0(ChardevMux, 1);
            backend->kind = CHARDEV_BACKEND_KIND_MUX;
            backend->mux->chardev = g_strdup(bid);
            ret = qmp_chardev_add(id, backend, errp);
            if (error_is_set(errp)) {
                goto qapi_out;
            }
        }

        chr = qemu_chr_find(id);

    qapi_out:
        qapi_free_ChardevBackend(backend);
        qapi_free_ChardevReturn(ret);
        return chr;
    }

    chr = cd->open(opts);
    if (!chr) {
        error_setg(errp, "chardev: opening backend \"%s\" failed",
                   qemu_opt_get(opts, "backend"));
        goto err;
    }

    if (!chr->filename)
        chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
    chr->init = init;
    /* if we didn't create the chardev via qmp_chardev_add, we
     * need to send the OPENED event here
     */
    if (!chr->explicit_be_open) {
        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
    }
    QTAILQ_INSERT_TAIL(&chardevs, chr, next);

    if (qemu_opt_get_bool(opts, "mux", 0)) {
        CharDriverState *base = chr;
        int len = strlen(qemu_opts_id(opts)) + 6;
        base->label = g_malloc(len);
        snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
        chr = qemu_chr_open_mux(base);
        chr->filename = base->filename;
        chr->avail_connections = MAX_MUX;
        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
    } else {
        chr->avail_connections = 1;
    }
    chr->label = g_strdup(qemu_opts_id(opts));
    chr->opts = opts;
    return chr;

err:
    qemu_opts_del(opts);
    return NULL;
}

CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
{
    const char *p;
    CharDriverState *chr;
    QemuOpts *opts;
    Error *err = NULL;

    if (strstart(filename, "chardev:", &p)) {
        return qemu_chr_find(p);
    }

    opts = qemu_chr_parse_compat(label, filename);
    if (!opts)
        return NULL;

    chr = qemu_chr_new_from_opts(opts, init, &err);
    if (error_is_set(&err)) {
        fprintf(stderr, "%s\n", error_get_pretty(err));
        error_free(err);
    }
    if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
        qemu_chr_fe_claim_no_fail(chr);
        monitor_init(chr, MONITOR_USE_READLINE);
    }
    return chr;
}

void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
{
    if (chr->chr_set_echo) {
        chr->chr_set_echo(chr, echo);
    }
}

void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open)
{
    if (chr->fe_open == fe_open) {
        return;
    }
    chr->fe_open = fe_open;
    if (chr->chr_set_fe_open) {
        chr->chr_set_fe_open(chr, fe_open);
    }
}

int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
                          GIOFunc func, void *user_data)
{
    GSource *src;
    guint tag;

    if (s->chr_add_watch == NULL) {
        return -ENOSYS;
    }

    src = s->chr_add_watch(s, cond);
    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
    tag = g_source_attach(src, NULL);
    g_source_unref(src);

    return tag;
}

int qemu_chr_fe_claim(CharDriverState *s)
{
    if (s->avail_connections < 1) {
        return -1;
    }
    s->avail_connections--;
    return 0;
}

void qemu_chr_fe_claim_no_fail(CharDriverState *s)
{
    if (qemu_chr_fe_claim(s) != 0) {
        fprintf(stderr, "%s: error chardev \"%s\" already used\n",
                __func__, s->label);
        exit(1);
    }
}

void qemu_chr_fe_release(CharDriverState *s)
{
    s->avail_connections++;
}

void qemu_chr_delete(CharDriverState *chr)
{
    QTAILQ_REMOVE(&chardevs, chr, next);
    if (chr->chr_close) {
        chr->chr_close(chr);
    }
    g_free(chr->filename);
    g_free(chr->label);
    if (chr->opts) {
        qemu_opts_del(chr->opts);
    }
    g_free(chr);
}

ChardevInfoList *qmp_query_chardev(Error **errp)
{
    ChardevInfoList *chr_list = NULL;
    CharDriverState *chr;

    QTAILQ_FOREACH(chr, &chardevs, next) {
        ChardevInfoList *info = g_malloc0(sizeof(*info));
        info->value = g_malloc0(sizeof(*info->value));
        info->value->label = g_strdup(chr->label);
        info->value->filename = g_strdup(chr->filename);

        info->next = chr_list;
        chr_list = info;
    }

    return chr_list;
}

CharDriverState *qemu_chr_find(const char *name)
{
    CharDriverState *chr;

    QTAILQ_FOREACH(chr, &chardevs, next) {
        if (strcmp(chr->label, name) != 0)
            continue;
        return chr;
    }
    return NULL;
}

/* Get a character (serial) device interface.  */
CharDriverState *qemu_char_get_next_serial(void)
{
    static int next_serial;
    CharDriverState *chr;

    /* FIXME: This function needs to go away: use chardev properties!  */

    while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
        chr = serial_hds[next_serial++];
        qemu_chr_fe_claim_no_fail(chr);
        return chr;
    }
    return NULL;
}

QemuOptsList qemu_chardev_opts = {
    .name = "chardev",
    .implied_opt_name = "backend",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
    .desc = {
        {
            .name = "backend",
            .type = QEMU_OPT_STRING,
        },{
            .name = "path",
            .type = QEMU_OPT_STRING,
        },{
            .name = "host",
            .type = QEMU_OPT_STRING,
        },{
            .name = "port",
            .type = QEMU_OPT_STRING,
        },{
            .name = "localaddr",
            .type = QEMU_OPT_STRING,
        },{
            .name = "localport",
            .type = QEMU_OPT_STRING,
        },{
            .name = "to",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "ipv4",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "ipv6",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "wait",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "server",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "delay",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "telnet",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "width",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "height",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "cols",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "rows",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "mux",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "signal",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "name",
            .type = QEMU_OPT_STRING,
        },{
            .name = "debug",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "size",
            .type = QEMU_OPT_SIZE,
        },
        { /* end of list */ }
    },
};

#ifdef _WIN32

static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
{
    HANDLE out;

    if (file->in) {
        error_setg(errp, "input file not supported");
        return NULL;
    }

    out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (out == INVALID_HANDLE_VALUE) {
        error_setg(errp, "open %s failed", file->out);
        return NULL;
    }
    return qemu_chr_open_win_file(out);
}

static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
                                                Error **errp)
{
    return qemu_chr_open_win_path(serial->device);
}

static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
                                                  Error **errp)
{
    error_setg(errp, "character device backend type 'parallel' not supported");
    return NULL;
}

#else /* WIN32 */

static int qmp_chardev_open_file_source(char *src, int flags,
                                        Error **errp)
{
    int fd = -1;

    TFR(fd = qemu_open(src, flags, 0666));
    if (fd == -1) {
        error_setg(errp, "open %s: %s", src, strerror(errno));
    }
    return fd;
}

static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
{
    int flags, in = -1, out = -1;

    flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
    out = qmp_chardev_open_file_source(file->out, flags, errp);
    if (error_is_set(errp)) {
        return NULL;
    }

    if (file->in) {
        flags = O_RDONLY;
        in = qmp_chardev_open_file_source(file->in, flags, errp);
        if (error_is_set(errp)) {
            qemu_close(out);
            return NULL;
        }
    }

    return qemu_chr_open_fd(in, out);
}

static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
                                                Error **errp)
{
#ifdef HAVE_CHARDEV_TTY
    int fd;

    fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
    if (error_is_set(errp)) {
        return NULL;
    }
    qemu_set_nonblock(fd);
    return qemu_chr_open_tty_fd(fd);
#else
    error_setg(errp, "character device backend type 'serial' not supported");
    return NULL;
#endif
}

static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
                                                  Error **errp)
{
#ifdef HAVE_CHARDEV_PARPORT
    int fd;

    fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
    if (error_is_set(errp)) {
        return NULL;
    }
    return qemu_chr_open_pp_fd(fd);
#else
    error_setg(errp, "character device backend type 'parallel' not supported");
    return NULL;
#endif
}

#endif /* WIN32 */

static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
                                                Error **errp)
{
    SocketAddress *addr = sock->addr;
    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
    bool is_listen      = sock->has_server  ? sock->server  : true;
    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
    int fd;

    if (is_listen) {
        fd = socket_listen(addr, errp);
    } else {
        fd = socket_connect(addr, errp, NULL, NULL);
    }
    if (error_is_set(errp)) {
        return NULL;
    }
    return qemu_chr_open_socket_fd(fd, do_nodelay, is_listen,
                                   is_telnet, is_waitconnect, errp);
}

static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
                                             Error **errp)
{
    int fd;

    fd = socket_dgram(udp->remote, udp->local, errp);
    if (error_is_set(errp)) {
        return NULL;
    }
    return qemu_chr_open_udp_fd(fd);
}

ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
                               Error **errp)
{
    ChardevReturn *ret = g_new0(ChardevReturn, 1);
    CharDriverState *base, *chr = NULL;

    chr = qemu_chr_find(id);
    if (chr) {
        error_setg(errp, "Chardev '%s' already exists", id);
        g_free(ret);
        return NULL;
    }

    switch (backend->kind) {
    case CHARDEV_BACKEND_KIND_FILE:
        chr = qmp_chardev_open_file(backend->file, errp);
        break;
    case CHARDEV_BACKEND_KIND_SERIAL:
        chr = qmp_chardev_open_serial(backend->serial, errp);
        break;
    case CHARDEV_BACKEND_KIND_PARALLEL:
        chr = qmp_chardev_open_parallel(backend->parallel, errp);
        break;
    case CHARDEV_BACKEND_KIND_PIPE:
        chr = qemu_chr_open_pipe(backend->pipe);
        break;
    case CHARDEV_BACKEND_KIND_SOCKET:
        chr = qmp_chardev_open_socket(backend->socket, errp);
        break;
    case CHARDEV_BACKEND_KIND_UDP:
        chr = qmp_chardev_open_udp(backend->udp, errp);
        break;
#ifdef HAVE_CHARDEV_TTY
    case CHARDEV_BACKEND_KIND_PTY:
        chr = qemu_chr_open_pty(id, ret);
        break;
#endif
    case CHARDEV_BACKEND_KIND_NULL:
        chr = qemu_chr_open_null();
        break;
    case CHARDEV_BACKEND_KIND_MUX:
        base = qemu_chr_find(backend->mux->chardev);
        if (base == NULL) {
            error_setg(errp, "mux: base chardev %s not found",
                       backend->mux->chardev);
            break;
        }
        chr = qemu_chr_open_mux(base);
        break;
    case CHARDEV_BACKEND_KIND_MSMOUSE:
        chr = qemu_chr_open_msmouse();
        break;
#ifdef CONFIG_BRLAPI
    case CHARDEV_BACKEND_KIND_BRAILLE:
        chr = chr_baum_init();
        break;
#endif
    case CHARDEV_BACKEND_KIND_STDIO:
        chr = qemu_chr_open_stdio(backend->stdio);
        break;
#ifdef _WIN32
    case CHARDEV_BACKEND_KIND_CONSOLE:
        chr = qemu_chr_open_win_con();
        break;
#endif
#ifdef CONFIG_SPICE
    case CHARDEV_BACKEND_KIND_SPICEVMC:
        chr = qemu_chr_open_spice_vmc(backend->spicevmc->type);
        break;
    case CHARDEV_BACKEND_KIND_SPICEPORT:
        chr = qemu_chr_open_spice_port(backend->spiceport->fqdn);
        break;
#endif
    case CHARDEV_BACKEND_KIND_VC:
        chr = vc_init(backend->vc);
        break;
    case CHARDEV_BACKEND_KIND_MEMORY:
        chr = qemu_chr_open_ringbuf(backend->memory, errp);
        break;
    default:
        error_setg(errp, "unknown chardev backend (%d)", backend->kind);
        break;
    }

    if (chr == NULL && !error_is_set(errp)) {
        error_setg(errp, "Failed to create chardev");
    }
    if (chr) {
        chr->label = g_strdup(id);
        chr->avail_connections =
            (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
        if (!chr->filename) {
            chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
        }
        if (!chr->explicit_be_open) {
            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
        }
        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
        return ret;
    } else {
        g_free(ret);
        return NULL;
    }
}

void qmp_chardev_remove(const char *id, Error **errp)
{
    CharDriverState *chr;

    chr = qemu_chr_find(id);
    if (NULL == chr) {
        error_setg(errp, "Chardev '%s' not found", id);
        return;
    }
    if (chr->chr_can_read || chr->chr_read ||
        chr->chr_event || chr->handler_opaque) {
        error_setg(errp, "Chardev '%s' is busy", id);
        return;
    }
    qemu_chr_delete(chr);
}

static void register_types(void)
{
    register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL);
    register_char_driver("socket", qemu_chr_open_socket);
    register_char_driver("udp", qemu_chr_open_udp);
    register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
                              qemu_chr_parse_ringbuf);
    register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
                              qemu_chr_parse_file_out);
    register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
                              qemu_chr_parse_stdio);
    register_char_driver_qapi("serial", CHARDEV_BACKEND_KIND_SERIAL,
                              qemu_chr_parse_serial);
    register_char_driver_qapi("tty", CHARDEV_BACKEND_KIND_SERIAL,
                              qemu_chr_parse_serial);
    register_char_driver_qapi("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
                              qemu_chr_parse_parallel);
    register_char_driver_qapi("parport", CHARDEV_BACKEND_KIND_PARALLEL,
                              qemu_chr_parse_parallel);
    register_char_driver_qapi("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
    register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
    register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
                              qemu_chr_parse_pipe);
}

type_init(register_types);
