mount.nfs: get_socket() may clobber errno, but preserves .re_errno
authorChuck Lever <chuck.lever@oracle.com>
Fri, 3 Aug 2007 17:24:00 +0000 (13:24 -0400)
committerNeil Brown <neilb@suse.de>
Fri, 3 Aug 2007 22:27:40 +0000 (08:27 +1000)
get_socket() guarantees that rpc_createerr.cf_error.re_errno is set
correctly after an error, but it can wipe errno if it has to print an error
message.  Make sure that clnt_ping() checks the correct error code when
get_socket() returns.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Neil Brown <neilb@suse.de>
utils/mount/network.c

index 132ff1e..5a56c23 100644 (file)
@@ -310,19 +310,11 @@ static unsigned short getport(struct sockaddr_in *saddr,
 
        saddr->sin_port = htons(PMAPPORT);
 
-       /*
-        * Try to get a socket with a non-privileged port.
-        * clnt*create() will create one anyway if this
-        * fails.
-        */
        socket = get_socket(saddr, proto, PMAP_TIMEOUT, FALSE, FALSE);
        if (socket == RPC_ANYSOCK) {
-               if (proto == IPPROTO_TCP && errno == ETIMEDOUT) {
-                       /*
-                        * TCP SYN timed out, so exit now.
-                        */
+               if (proto == IPPROTO_TCP &&
+                   rpc_createerr.cf_error.re_errno == ETIMEDOUT)
                        rpc_createerr.cf_stat = RPC_TIMEDOUT;
-               }
                return 0;
        }
 
@@ -660,10 +652,10 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
        static char clnt_res;
        struct sockaddr dissolve;
 
-       rpc_createerr.cf_stat = stat = errno = 0;
+       rpc_createerr.cf_stat = stat = 0;
        sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
        if (sock == RPC_ANYSOCK) {
-               if (errno == ETIMEDOUT) {
+               if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
                        /*
                         * TCP timeout. Bubble up the error to see 
                         * how it should be handled.