summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chardev/char-socket.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 77cdf487eb..a340af6cd3 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -42,6 +42,7 @@ typedef struct {
QIOChannel *ioc; /* Client I/O channel */
QIOChannelSocket *sioc; /* Client master channel */
QIONetListener *listener;
+ GSource *hup_source;
QCryptoTLSCreds *tls_creds;
int connected;
int max_size;
@@ -352,6 +353,12 @@ static void tcp_chr_free_connection(Chardev *chr)
s->read_msgfds_num = 0;
}
+ if (s->hup_source != NULL) {
+ g_source_destroy(s->hup_source);
+ g_source_unref(s->hup_source);
+ s->hup_source = NULL;
+ }
+
tcp_set_msgfds(chr, NULL, 0);
remove_fd_in_watch(chr);
object_unref(OBJECT(s->sioc));
@@ -455,6 +462,15 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
return TRUE;
}
+static gboolean tcp_chr_hup(QIOChannel *channel,
+ GIOCondition cond,
+ void *opaque)
+{
+ Chardev *chr = CHARDEV(opaque);
+ tcp_chr_disconnect(chr);
+ return G_SOURCE_REMOVE;
+}
+
static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
@@ -528,6 +544,12 @@ static void tcp_chr_connect(void *opaque)
tcp_chr_read,
chr, chr->gcontext);
}
+
+ s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
+ g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
+ chr, NULL);
+ g_source_attach(s->hup_source, chr->gcontext);
+
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}