summaryrefslogtreecommitdiff
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorErik Hugne <erik.hugne@ericsson.com>2015-03-09 12:43:42 +0300
committerDavid S. Miller <davem@davemloft.net>2015-03-09 22:42:19 +0300
commit143fe22f50a8be855bba77b5b2dc9dd1a5982b1c (patch)
treeff4c064cb226d455ad2273770dec7432a58357ba /net/tipc/socket.c
parent57ad7a0a81f3e9e619540ce9e31d5bd724b59a6e (diff)
downloadlinux-143fe22f50a8be855bba77b5b2dc9dd1a5982b1c.tar.xz
tipc: fix inconsistent signal handling regression
Commit 9bbb4ecc6819 ("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: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Reported-by László Benedek <laszlo.benedek@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 95c514a1d7d9..934947f038b6 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1318,12 +1318,12 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
err = 0;
if (!skb_queue_empty(&sk->sk_receive_queue))
break;
- err = sock_intr_errno(timeo);
- if (signal_pending(current))
- break;
err = -EAGAIN;
if (!timeo)
break;
+ err = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ break;
}
finish_wait(sk_sleep(sk), &wait);
*timeop = timeo;
@@ -2026,12 +2026,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
err = -EINVAL;
if (sock->state != SS_LISTENING)
break;
- err = sock_intr_errno(timeo);
- if (signal_pending(current))
- break;
err = -EAGAIN;
if (!timeo)
break;
+ err = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ break;
}
finish_wait(sk_sleep(sk), &wait);
return err;