Commit cfb429cb authored by Corey Minyard's avatar Corey Minyard Committed by Paolo Bonzini
Browse files

qemu-char: Move some items into TCPCharDriver



This keeps them from having to be passed around and makes them
available for later functions, like printing and reconnecting.

Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 43ded1a0
Loading
Loading
Loading
Loading
+51 −14
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@
#include "sysemu/char.h"
#include "hw/usb.h"
#include "qmp-commands.h"
#include "qapi/qmp-input-visitor.h"
#include "qapi/qmp-output-visitor.h"
#include "qapi-visit.h"

#include <unistd.h>
#include <fcntl.h>
@@ -86,6 +89,34 @@
#define READ_RETRIES 10
#define CHR_MAX_FILENAME_SIZE 256

/***********************************************************/
/* Socket address helpers */
static void qapi_copy_SocketAddress(SocketAddress **p_dest,
                                    SocketAddress *src)
{
    QmpOutputVisitor *qov;
    QmpInputVisitor *qiv;
    Visitor *ov, *iv;
    QObject *obj;

    *p_dest = NULL;

    qov = qmp_output_visitor_new();
    ov = qmp_output_get_visitor(qov);
    visit_type_SocketAddress(ov, &src, NULL, &error_abort);
    obj = qmp_output_get_qobject(qov);
    qmp_output_visitor_cleanup(qov);
    if (!obj) {
        return;
    }

    qiv = qmp_input_visitor_new(obj);
    iv = qmp_input_get_visitor(qiv);
    visit_type_SocketAddress(iv, p_dest, NULL, &error_abort);
    qmp_input_visitor_cleanup(qiv);
    qobject_decref(obj);
}

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

@@ -2412,6 +2443,10 @@ typedef struct {
    int read_msgfds_num;
    int *write_msgfds;
    int write_msgfds_num;

    SocketAddress *addr;
    bool is_listen;
    bool is_telnet;
} TCPCharDriver;

static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
@@ -2861,6 +2896,8 @@ static void tcp_chr_close(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    int i;

    qapi_free_SocketAddress(s->addr);
    if (s->fd >= 0) {
        remove_fd_in_watch(chr);
        if (s->chan) {
@@ -2892,7 +2929,6 @@ static void tcp_chr_close(CharDriverState *chr)
}

static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
                                              bool is_listen, bool is_telnet,
                                              Error **errp)
{
    TCPCharDriver *s = chr->opaque;
@@ -2913,7 +2949,7 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
    case AF_UNIX:
        snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
                 ((struct sockaddr_un *)(&ss))->sun_path,
                 is_listen ? ",server" : "");
                 s->is_listen ? ",server" : "");
        break;
#endif
    case AF_INET6:
@@ -2924,13 +2960,13 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
        getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
                    serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
        snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
                 is_telnet ? "telnet" : "tcp",
                 s->is_telnet ? "telnet" : "tcp",
                 left, host, right, serv,
                 is_listen ? ",server" : "");
                 s->is_listen ? ",server" : "");
        break;
    }

    if (is_listen) {
    if (s->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,
@@ -2946,23 +2982,21 @@ static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
    return true;
}

static bool qemu_chr_open_socket_fd(CharDriverState *chr, SocketAddress *addr,
                                    bool is_listen, bool is_telnet,
                                    Error **errp)
static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
{
    TCPCharDriver *s = chr->opaque;
    int fd;

    if (is_listen) {
        fd = socket_listen(addr, errp);
    if (s->is_listen) {
        fd = socket_listen(s->addr, errp);
    } else  {
        fd = socket_connect(addr, errp, NULL, NULL);
        fd = socket_connect(s->addr, errp, NULL, NULL);
    }
    if (fd < 0) {
        return false;
    }

    return qemu_chr_finish_socket_connection(chr, fd, is_listen, is_telnet,
                                             errp);
    return qemu_chr_finish_socket_connection(chr, fd, errp);
}

/*********************************************************/
@@ -3967,7 +4001,10 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
    s->fd = -1;
    s->listen_fd = -1;
    s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX;
    s->is_listen = is_listen;
    s->is_telnet = is_telnet;
    s->do_nodelay = do_nodelay;
    qapi_copy_SocketAddress(&s->addr, sock->addr);

    chr->opaque = s;
    chr->chr_write = tcp_chr_write;
@@ -3989,7 +4026,7 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
        }
    }

    if (!qemu_chr_open_socket_fd(chr, addr, is_listen, is_telnet, errp)) {
    if (!qemu_chr_open_socket_fd(chr, errp)) {
        g_free(s);
        g_free(chr->filename);
        g_free(chr);