From: Ronnie Sahlberg Date: Wed, 19 Sep 2012 00:54:22 +0000 (-0700) Subject: Merge pull request #23 from warped-rudi/master-updates X-Git-Tag: upstream/1.9.6^2~252 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=6e3fe62c50dffa0693101d780362e4bd91898732;hp=c0ebf57b212ffefe83e2a50358499f68e7289e93;p=deb_libnfs.git Merge pull request #23 from warped-rudi/master-updates Merged. Thanks! --- diff --git a/.gitignore b/.gitignore index 98e7bab..7648923 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,14 @@ *.a *.lo *.o +*.obj +*.lib +*.dll +*.ilk +*.pdb +*.ex? *-stamp +libnfs-raw-*.x Makefile examples/nfsclient-raw examples/nfsclient-sync diff --git a/lib/socket.c b/lib/socket.c index ea16d8c..1bb34f0 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -363,8 +363,6 @@ static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_s return -1; } - -#if !defined(WIN32) /* Some systems allow you to set capabilities on an executable * to allow the file to be executed with privilege to bind to * privileged system ports, even if the user is not root. @@ -379,42 +377,43 @@ static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_s * On linux, use * sudo setcap 'cap_net_bind_service=+ep' /path/executable * to make the executable able to bind to a system port. + * + * On Windows, there is no concept of privileged ports. Thus + * binding will usually succeed. */ - if (1) { - static int port = 200; - int i; - int one = 1; - - setsockopt(rpc->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); - - for (i = 0; i < 500; i++) { - struct sockaddr_in sin; - - if(++port > 700) port = 200; - - memset(&sin, 0, sizeof(sin)); - sin.sin_port = htons(port); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = 0; - - if (bind(rpc->fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) != 0 && errno != EACCES) { - /* we didnt get EACCES, so try again */ - continue; + { + struct sockaddr_in sin; + static int portOfs = 0; + const int firstPort = 512; /* >= 512 according to Sun docs */ + const int portCount = IPPORT_RESERVED - firstPort; + int startOfs = portOfs, port, rc; + + do { + rc = -1; + port = htons(firstPort + portOfs); + portOfs = (portOfs + 1) % portCount; + + /* skip well-known ports */ + if (!getservbyport(port, "tcp")) { + memset(&sin, 0, sizeof(sin)); + sin.sin_port = port; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = 0; + + rc = bind(rpc->fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); +#if !defined(WIN32) + /* we got EACCES, so don't try again */ + if (rc != 0 && errno == EACCES) + break; +#endif } - break; - } + } while (rc != 0 && portOfs != startOfs); } -#endif set_nonblocking(rpc->fd); -#if defined(WIN32) - if (connect(rpc->fd, (struct sockaddr *)s, socksize) == 0 && errno != EINPROGRESS ) -#else - if (connect(rpc->fd, (struct sockaddr *)s, socksize) != 0 && errno != EINPROGRESS) -#endif - { - rpc_set_error(rpc, "connect() to server failed. %s(%d)", strerror(errno), errno); + if (connect(rpc->fd, (struct sockaddr *)s, socksize) != 0 && errno != EINPROGRESS) { + rpc_set_error(rpc, "connect() to server failed. %s(%d)", strerror(errno), errno); return -1; } diff --git a/win32/win32_errnowrapper.h b/win32/win32_errnowrapper.h index 4477d3f..ebed01c 100644 --- a/win32/win32_errnowrapper.h +++ b/win32/win32_errnowrapper.h @@ -9,7 +9,8 @@ #undef EINPROGRESS #define EWOULDBLOCK WSAEWOULDBLOCK -#define EAGAIN WSAEWOULDBLOCK //same on windows +#define EAGAIN WSAEWOULDBLOCK //same on windows #define EINTR WSAEINTR -#define EINPROGRESS WSAEINPROGRESS +#define EINPROGRESS WSAEWOULDBLOCK //does not map to WSAEINPROGRESS ! + #endif //WIN32_ERRNOWRAPPER_H_