diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-14 21:05:45 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-14 21:05:45 +0000 |
commit | daea1f31faccd8e5f154a81e7812b4afb4f000b0 (patch) | |
tree | 01aa8444a986493dc5454e23c817bb228cc70200 /serial | |
parent | 55837631c9b06a5853f7252ce90dd853d1803c76 (diff) |
serial: added G_IO_NVAL flag to fix potential busy loop
Diffstat (limited to 'serial')
-rw-r--r-- | serial/manager.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/serial/manager.c b/serial/manager.c index 5f6ad065..2c797191 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -300,6 +300,9 @@ static gboolean rfcomm_disconnect_cb(GIOChannel *io, { debug("RFCOMM node %s was disconnected", node->name); + if (cond & (G_IO_ERR | G_IO_HUP)) + g_io_channel_close(io); + name_listener_remove(node->conn, node->owner, (name_cb_t) connect_service_exited, node); @@ -326,9 +329,8 @@ static int add_rfcomm_node(GIOChannel *io, int id, const char *name, node->owner = g_strdup(owner); node->io = io; - g_io_channel_set_close_on_unref(io, TRUE); - node->io_id = g_io_add_watch(io, G_IO_ERR | G_IO_HUP, - (GIOFunc) rfcomm_disconnect_cb, node); + node->io_id = g_io_add_watch(io, G_IO_ERR | G_IO_NVAL | G_IO_HUP, + (GIOFunc) rfcomm_disconnect_cb, node); connected_nodes = g_slist_append(connected_nodes, node); @@ -401,7 +403,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, char node_name[16]; const char *pname = node_name; struct rfcomm_dev_req req; - int sk, err, fd; + int sk, err, fd, close_chan = 1; if (pc->canceled) { err_connection_canceled(pc->conn, pc->msg); @@ -410,6 +412,13 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, sk = g_io_channel_unix_get_fd(chan); + if (cond & G_IO_NVAL) { + close_chan = 0; + err_connection_failed(pc->conn, pc->msg, + "File descriptor is not open"); + goto fail; + } + if (cond & (G_IO_ERR | G_IO_HUP)) { socklen_t len; int ret; @@ -459,6 +468,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, if (fd < 0) { g_timeout_add(OPEN_WAIT, (GSourceFunc) rfcomm_connect_cb_continue, pc); + g_io_channel_close(chan); return FALSE; } @@ -482,6 +492,9 @@ fail: pending_connects = g_slist_remove(pending_connects, pc); pending_connect_free(pc); + if (close_chan) + g_io_channel_close(chan); + return FALSE; } @@ -507,7 +520,6 @@ static int rfcomm_connect(struct pending_connect *pc) return -errno; io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(io, TRUE); addr.rc_family = AF_BLUETOOTH; str2ba(pc->bda, &addr.rc_bdaddr); @@ -522,8 +534,8 @@ static int rfcomm_connect(struct pending_connect *pc) } debug("Connect in progress"); - g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP, - (GIOFunc) rfcomm_connect_cb, pc); + g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_NVAL | G_IO_HUP, + (GIOFunc) rfcomm_connect_cb, pc); } else { debug("Connect succeeded with first try"); (void) rfcomm_connect_cb(io, G_IO_OUT, pc); |