diff mbox

[1/6] qemu-char: add qemu_chr_remove_clients()

Message ID 1354281947-20227-2-git-send-email-marcandre.lureau@redhat.com
State New
Headers show

Commit Message

Marc-André Lureau Nov. 30, 2012, 1:25 p.m. UTC
Make it possible for chardev user to disconnect all the clients.

The spiceport will remove associated chardev clients when the spice
client is disconnected.

(since qemu-char could have several clients implementation later, as
chr_add_client() name suggests, I chose to have generic name and
behaviour that could apply to a single or many clients implementation)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qemu-char.c | 28 ++++++++++++++++++++++++----
 qemu-char.h |  2 ++
 2 files changed, 26 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/qemu-char.c b/qemu-char.c
index 242b799..1414ca1 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -176,6 +176,11 @@  int qemu_chr_add_client(CharDriverState *s, int fd)
     return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
 }
 
+int qemu_chr_remove_clients(CharDriverState *s)
+{
+    return s->chr_remove_clients ? s->chr_remove_clients(s) : -1;
+}
+
 void qemu_chr_accept_input(CharDriverState *s)
 {
     if (s->chr_accept_input)
@@ -2378,6 +2383,22 @@  static int tcp_chr_add_client(CharDriverState *chr, int fd)
     return 0;
 }
 
+static int tcp_chr_remove_clients(CharDriverState *chr)
+{
+    TCPCharDriver *s = chr->opaque;
+
+    if (s->fd >= 0) {
+        qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+        closesocket(s->fd);
+        s->fd = -1;
+    }
+
+    /* listen for new clients */
+    qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
+
+    return 0;
+}
+
 static void tcp_chr_accept(void *opaque)
 {
     CharDriverState *chr = opaque;
@@ -2417,10 +2438,8 @@  static void tcp_chr_accept(void *opaque)
 static void tcp_chr_close(CharDriverState *chr)
 {
     TCPCharDriver *s = chr->opaque;
-    if (s->fd >= 0) {
-        qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-        closesocket(s->fd);
-    }
+
+    tcp_chr_remove_clients(chr);
     if (s->listen_fd >= 0) {
         qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
         closesocket(s->listen_fd);
@@ -2484,6 +2503,7 @@  static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
     chr->chr_close = tcp_chr_close;
     chr->get_msgfd = tcp_get_msgfd;
     chr->chr_add_client = tcp_chr_add_client;
+    chr->chr_remove_clients = tcp_chr_remove_clients;
 
     if (is_listen) {
         s->listen_fd = fd;
diff --git a/qemu-char.h b/qemu-char.h
index a121e04..b01c45c 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -60,6 +60,7 @@  struct CharDriverState {
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
     int (*get_msgfd)(struct CharDriverState *s);
     int (*chr_add_client)(struct CharDriverState *chr, int fd);
+    int (*chr_remove_clients)(struct CharDriverState *chr);
     IOEventHandler *chr_event;
     IOCanReadHandler *chr_can_read;
     IOReadHandler *chr_read;
@@ -232,6 +233,7 @@  void qemu_chr_add_handlers(CharDriverState *s,
 void qemu_chr_generic_open(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
+int qemu_chr_remove_clients(CharDriverState *s);
 void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
 void qemu_chr_info(Monitor *mon, QObject **ret_data);
 CharDriverState *qemu_chr_find(const char *name);