mirror of
https://github.com/qemu/qemu.git
synced 2025-01-19 12:03:51 +08:00
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: Corey Minyard <cminyard@mvista.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
43ded1a0d2
commit
cfb429cb1a
65
qemu-char.c
65
qemu-char.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user