diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-04 02:42:23 -0200 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-08 01:43:30 -0200 |
commit | c47b7c724bc7106acf602b2ce99922a2d14ea62b (patch) | |
tree | 28dc23a5a4e3641fa4d55b70bc5d6c8adec30be8 /net/bluetooth/l2cap_sock.c | |
parent | af6bcd8205ac06fa1de98b2b28303157fb9c3dfc (diff) | |
download | lwn-c47b7c724bc7106acf602b2ce99922a2d14ea62b.tar.gz lwn-c47b7c724bc7106acf602b2ce99922a2d14ea62b.zip |
Bluetooth: move l2cap_sock_accept() to l2cap_sock.c
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index ef9a60fda495..b19a386332fc 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -197,6 +197,62 @@ done: return err; } +static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) +{ + DECLARE_WAITQUEUE(wait, current); + struct sock *sk = sock->sk, *nsk; + long timeo; + int err = 0; + + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; + goto done; + } + + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); + + BT_DBG("sk %p timeo %ld", sk, timeo); + + /* Wait for an incoming connection. (wake-one). */ + add_wait_queue_exclusive(sk_sleep(sk), &wait); + while (!(nsk = bt_accept_dequeue(sk, newsock))) { + set_current_state(TASK_INTERRUPTIBLE); + if (!timeo) { + err = -EAGAIN; + break; + } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; + break; + } + + if (signal_pending(current)) { + err = sock_intr_errno(timeo); + break; + } + } + set_current_state(TASK_RUNNING); + remove_wait_queue(sk_sleep(sk), &wait); + + if (err) + goto done; + + newsock->state = SS_CONNECTED; + + BT_DBG("new socket %p", nsk); + +done: + release_sock(sk); + return err; +} + static int l2cap_sock_release(struct socket *sock) { struct sock *sk = sock->sk; |