summaryrefslogtreecommitdiffstats
path: root/support/nfs/rpc_socket.c
diff options
context:
space:
mode:
authorOlga Kornievskaia <kolga@netapp.com>2016-01-16 12:25:46 -0500
committerSteve Dickson <steved@redhat.com>2016-01-16 12:30:13 -0500
commita69fe66a504e60e6ef7133f9bee4408da2ee7455 (patch)
tree4520b4cee2c443ecd21eb2faea1946ac03da5fff /support/nfs/rpc_socket.c
parent2f8f24e617b9d3c20fe798fa00f268364e0aa7cc (diff)
downloadnfs-utils-a69fe66a504e60e6ef7133f9bee4408da2ee7455.tar.gz
nfs-utils-a69fe66a504e60e6ef7133f9bee4408da2ee7455.tar.xz
nfs-utils-a69fe66a504e60e6ef7133f9bee4408da2ee7455.zip
nfs_connect_nb: handle EINTR during connection establishment
both connect() and select() can receive EINTR signals that we need to recover from. In Unix Network Programming, volume 1, section 5.9, W. Richard Stevens states: What we are doing [?] is restarting the interrupted system call ourself. This is fine for accept, along with the functions such as read, write, select and open. But there is one function that we cannot restart ourself: connect. If this function returns EINTR, we cannot call it again, as doing so will return an immediate error. When connect is interrupted by a caught signal and is not automatically restarted, we must call select to wait for the connection to complete, Thus for connect() treat both EINPROGRESS and EINTR the same -- call select(). For select(), it should be re-tried again upon receiving EINTR. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'support/nfs/rpc_socket.c')
-rw-r--r--support/nfs/rpc_socket.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/support/nfs/rpc_socket.c b/support/nfs/rpc_socket.c
index 2900d18..bdf6d2f 100644
--- a/support/nfs/rpc_socket.c
+++ b/support/nfs/rpc_socket.c
@@ -185,7 +185,7 @@ static int nfs_connect_nb(const int fd, const struct sockaddr *sap,
* use it later.
*/
ret = connect(fd, sap, salen);
- if (ret < 0 && errno != EINPROGRESS) {
+ if (ret < 0 && errno != EINPROGRESS && errno != EINTR) {
ret = -1;
goto done;
}
@@ -197,10 +197,16 @@ static int nfs_connect_nb(const int fd, const struct sockaddr *sap,
FD_ZERO(&rset);
FD_SET(fd, &rset);
- ret = select(fd + 1, NULL, &rset, NULL, timeout);
- if (ret <= 0) {
- if (ret == 0)
- errno = ETIMEDOUT;
+ while ((ret = select(fd + 1, NULL, &rset, NULL, timeout)) < 0) {
+ if (errno != EINTR) {
+ ret = -1;
+ goto done;
+ } else {
+ continue;
+ }
+ }
+ if (ret == 0) {
+ errno = ETIMEDOUT;
ret = -1;
goto done;
}