Commit 143fe22f authored by Erik Hugne's avatar Erik Hugne Committed by David S. Miller

tipc: fix inconsistent signal handling regression

Commit 9bbb4ecc ("tipc: standardize recvmsg routine") changed
the sleep/wakeup behaviour for sockets entering recv() or accept().
In this process the order of reporting -EAGAIN/-EINTR was reversed.
This caused problems with wrong errno being reported back if the
timeout expires. The same problem happens if the socket is
nonblocking and recv()/accept() is called when the process have
pending signals. If there is no pending data read or connections to
accept, -EINTR will be returned instead of -EAGAIN.
Signed-off-by: default avatarErik Hugne <erik.hugne@ericsson.com>
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Reviewed-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Reported-by László Benedek <laszlo.benedek@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 57ad7a0a
...@@ -1318,12 +1318,12 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) ...@@ -1318,12 +1318,12 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
err = 0; err = 0;
if (!skb_queue_empty(&sk->sk_receive_queue)) if (!skb_queue_empty(&sk->sk_receive_queue))
break; break;
err = sock_intr_errno(timeo);
if (signal_pending(current))
break;
err = -EAGAIN; err = -EAGAIN;
if (!timeo) if (!timeo)
break; break;
err = sock_intr_errno(timeo);
if (signal_pending(current))
break;
} }
finish_wait(sk_sleep(sk), &wait); finish_wait(sk_sleep(sk), &wait);
*timeop = timeo; *timeop = timeo;
...@@ -2026,12 +2026,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) ...@@ -2026,12 +2026,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
err = -EINVAL; err = -EINVAL;
if (sock->state != SS_LISTENING) if (sock->state != SS_LISTENING)
break; break;
err = sock_intr_errno(timeo);
if (signal_pending(current))
break;
err = -EAGAIN; err = -EAGAIN;
if (!timeo) if (!timeo)
break; break;
err = sock_intr_errno(timeo);
if (signal_pending(current))
break;
} }
finish_wait(sk_sleep(sk), &wait); finish_wait(sk_sleep(sk), &wait);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment