* tcpfying x25_accept Signed-off-by: Aristeu Sergio Rozanski Filho Index: net/x25/x25_proto.c =================================================================== --- net/x25/x25_proto.c (revision 70) +++ net/x25/x25_proto.c (revision 71) @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -127,11 +128,73 @@ return rc; } +static int x25_wait_for_data(struct sock *sk, int timeout) +{ + DECLARE_WAITQUEUE(wait, current); + int rc = 0; + + add_wait_queue_exclusive(sk->sk_sleep, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + if (sk->sk_shutdown & RCV_SHUTDOWN) + break; + rc = -ERESTARTSYS; + if (signal_pending(current)) + break; + rc = -EAGAIN; + if (!timeout) + break; + rc = 0; + if (skb_queue_empty(&sk->sk_receive_queue)) { + release_sock(sk); + timeout = schedule_timeout(timeout); + lock_sock(sk); + } else + break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk->sk_sleep, &wait); + return rc; +} + +static struct sock *x25_proto_accept(struct sock *sk, int flags, int *error) +{ + struct sk_buff *skb; + struct sock *newsk = NULL; + + lock_sock(sk); + + if (sk->sk_state != TCP_LISTEN) + goto out; + + if (sk->sk_type != SOCK_SEQPACKET) + goto out; + + if (x25_wait_for_data(sk, sk->sk_rcvtimeo)) + goto out; + + skb = skb_dequeue(&sk->sk_receive_queue); + if (!skb->sk) + goto out2; + + newsk = skb->sk; + sk->sk_ack_backlog--; + +out2: + skb->sk = NULL; + kfree_skb(skb); + +out: + release_sock(sk); + return newsk; +} + struct proto x25_prot = { .name = "X25", .setsockopt = x25_proto_setsockopt, .getsockopt = x25_proto_getsockopt, .connect = x25_proto_connect, + .accept = x25_proto_accept, }; EXPORT_SYMBOL(x25_prot); Index: net/x25/af_x25.c =================================================================== --- net/x25/af_x25.c (revision 70) +++ net/x25/af_x25.c (revision 71) @@ -552,75 +552,6 @@ return 0; } -static int x25_wait_for_data(struct sock *sk, int timeout) -{ - DECLARE_WAITQUEUE(wait, current); - int rc = 0; - - add_wait_queue_exclusive(sk->sk_sleep, &wait); - for (;;) { - __set_current_state(TASK_INTERRUPTIBLE); - if (sk->sk_shutdown & RCV_SHUTDOWN) - break; - rc = -ERESTARTSYS; - if (signal_pending(current)) - break; - rc = -EAGAIN; - if (!timeout) - break; - rc = 0; - if (skb_queue_empty(&sk->sk_receive_queue)) { - release_sock(sk); - timeout = schedule_timeout(timeout); - lock_sock(sk); - } else - break; - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(sk->sk_sleep, &wait); - return rc; -} - -static int x25_accept(struct socket *sock, struct socket *newsock, int flags) -{ - struct sock *sk = sock->sk; - struct sock *newsk; - struct sk_buff *skb; - int rc = -EINVAL; - - if (!sk || sk->sk_state != TCP_LISTEN) - goto out; - - rc = -EOPNOTSUPP; - if (sk->sk_type != SOCK_SEQPACKET) - goto out; - - lock_sock(sk); - rc = x25_wait_for_data(sk, sk->sk_rcvtimeo); - if (rc) - goto out2; - skb = skb_dequeue(&sk->sk_receive_queue); - rc = -EINVAL; - if (!skb->sk) - goto out2; - newsk = skb->sk; - newsk->sk_pair = NULL; - newsk->sk_socket = newsock; - newsk->sk_sleep = &newsock->wait; - - /* Now attach up the new socket */ - skb->sk = NULL; - kfree_skb(skb); - sk->sk_ack_backlog--; - newsock->sk = newsk; - newsock->state = SS_CONNECTED; - rc = 0; -out2: - release_sock(sk); -out: - return rc; -} - static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { @@ -1162,7 +1093,7 @@ .bind = x25_bind, .connect = inet_stream_connect, .socketpair = sock_no_socketpair, - .accept = x25_accept, + .accept = inet_accept, .getname = x25_getname, .poll = datagram_poll, .ioctl = x25_ioctl,