From 27906878d9a9a3daebc84d72c6b20496da22c0a2 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Jul 2010 14:15:50 +0300 Subject: [PATCH] obexd: Fix not closing socket when connection attempt fails When connection attempt fails the socket were left opened as it is not assigned to the session, also when the connection does succeed the socket is closed twice when the session is removed. To fix those issues session now holds a reference to the GIOChannel returned bt bt_io_connect so that the connection can properly close when releasing, in addiction to that it also is marked to not close the socket when the connection succeeds so that when removing the session it doesn't close the socket twice. Thanks for Vitja Makarov for reporting this. --- obexd/client/session.c | 39 +++++++++++++++++++++++++-------------- obexd/client/session.h | 2 +- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/obexd/client/session.c b/obexd/client/session.c index 334ade410..d761bfb7e 100644 --- a/obexd/client/session.c +++ b/obexd/client/session.c @@ -173,8 +173,10 @@ static void session_free(struct session_data *session) if (session->obex != NULL) gw_obex_close(session->obex); - if (session->sock > 2) - close(session->sock); + if (session->io != NULL) { + g_io_channel_shutdown(session->io, TRUE, NULL); + g_io_channel_unref(session->io); + } if (session->path) session_unregistered(session); @@ -215,13 +217,17 @@ static void rfcomm_callback(GIOChannel *io, GError *err, gpointer user_data) goto done; } + /* do not close when gw_obex is using the fd */ + g_io_channel_set_close_on_unref(session->io, FALSE); + g_io_channel_unref(session->io); + session->io = NULL; + fd = g_io_channel_unix_get_fd(io); obex = gw_obex_setup_fd(fd, session->target, session->target_len, NULL, NULL); - callback->session->sock = fd; - callback->session->obex = obex; + session->obex = obex; done: callback->func(callback->session, callback->data); @@ -231,9 +237,9 @@ done: g_free(callback); } -static int rfcomm_connect(const bdaddr_t *src, - const bdaddr_t *dst, uint8_t channel, - BtIOConnect function, gpointer user_data) +static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, + uint8_t channel, BtIOConnect function, + gpointer user_data) { GIOChannel *io; GError *err = NULL; @@ -245,11 +251,11 @@ static int rfcomm_connect(const bdaddr_t *src, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, BT_IO_OPT_INVALID); if (io != NULL) - return 0; + return io; error("%s", err->message); g_error_free(err); - return -EIO; + return NULL; } static void search_callback(uint8_t type, uint16_t status, @@ -309,8 +315,11 @@ static void search_callback(uint8_t type, uint16_t status, callback->session->channel = channel; - if (rfcomm_connect(&callback->session->src, &callback->session->dst, - channel, rfcomm_callback, callback) == 0) { + callback->session->io = rfcomm_connect(&callback->session->src, + &callback->session->dst, + channel, rfcomm_callback, + callback); + if (callback->session->io != NULL) { sdp_close(callback->sdp); return; } @@ -418,7 +427,6 @@ struct session_data *session_create(const char *source, return NULL; session->refcount = 1; - session->sock = -1; session->channel = channel; session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL); @@ -465,8 +473,11 @@ struct session_data *session_create(const char *source, callback->data = user_data; if (session->channel > 0) { - err = rfcomm_connect(&session->src, &session->dst, - session->channel, rfcomm_callback, callback); + session->io = rfcomm_connect(&session->src, &session->dst, + session->channel, + rfcomm_callback, + callback); + err = (session->io == NULL) ? -EINVAL : 0; } else { callback->sdp = service_connect(&session->src, &session->dst, service_callback, callback); diff --git a/obexd/client/session.h b/obexd/client/session.h index 73337cd7e..9451c25a1 100644 --- a/obexd/client/session.h +++ b/obexd/client/session.h @@ -40,10 +40,10 @@ struct session_data { int target_len; uuid_t uuid; /* Bluetooth Service Class */ gchar *path; /* Session path */ - int sock; DBusConnection *conn; DBusMessage *msg; GwObex *obex; + GIOChannel *io; struct agent_data *agent; struct session_callback *callback; gchar *owner; /* Session owner */ -- 2.47.3