diff options
author | Luiz Augusto von Dentz <luiz.dentz-von@nokia.com> | 2010-07-29 14:15:50 +0300 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz-von@nokia.com> | 2010-07-29 14:15:50 +0300 |
commit | 667136b55cb3d6bebe0061925c69b6ee5a6dd88a (patch) | |
tree | 863d3439eddeeae7a714dc2485ee8cf5eaed2493 /client | |
parent | 0b6611f0204e2fddc8f35f90b5735bd7e24cece4 (diff) | |
download | obexd-667136b55cb3d6bebe0061925c69b6ee5a6dd88a.tar.gz |
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 <vitja.makarov@gmail.com> for reporting this.
Diffstat (limited to 'client')
-rw-r--r-- | client/session.c | 39 | ||||
-rw-r--r-- | client/session.h | 2 |
2 files changed, 26 insertions, 15 deletions
diff --git a/client/session.c b/client/session.c index 334ade4..d761bfb 100644 --- a/client/session.c +++ b/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/client/session.h b/client/session.h index 73337cd..9451c25 100644 --- a/client/session.h +++ b/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 */ |