aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c56
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:
197 return err; 197 return err;
198} 198}
199 199
200static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
201{
202 DECLARE_WAITQUEUE(wait, current);
203 struct sock *sk = sock->sk, *nsk;
204 long timeo;
205 int err = 0;
206
207 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
208
209 if (sk->sk_state != BT_LISTEN) {
210 err = -EBADFD;
211 goto done;
212 }
213
214 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
215
216 BT_DBG("sk %p timeo %ld", sk, timeo);
217
218 /* Wait for an incoming connection. (wake-one). */
219 add_wait_queue_exclusive(sk_sleep(sk), &wait);
220 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
221 set_current_state(TASK_INTERRUPTIBLE);
222 if (!timeo) {
223 err = -EAGAIN;
224 break;
225 }
226
227 release_sock(sk);
228 timeo = schedule_timeout(timeo);
229 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
230
231 if (sk->sk_state != BT_LISTEN) {
232 err = -EBADFD;
233 break;
234 }
235
236 if (signal_pending(current)) {
237 err = sock_intr_errno(timeo);
238 break;
239 }
240 }
241 set_current_state(TASK_RUNNING);
242 remove_wait_queue(sk_sleep(sk), &wait);
243
244 if (err)
245 goto done;
246
247 newsock->state = SS_CONNECTED;
248
249 BT_DBG("new socket %p", nsk);
250
251done:
252 release_sock(sk);
253 return err;
254}
255
200static int l2cap_sock_release(struct socket *sock) 256static int l2cap_sock_release(struct socket *sock)
201{ 257{
202 struct sock *sk = sock->sk; 258 struct sock *sk = sock->sk;