]> granicus.if.org Git - transmission/commitdiff
(trunk) #3311 "MingW build of Transmission" -- apply more of rb07's diffs, though...
authorCharles Kerr <charles@transmissionbt.com>
Wed, 30 Jun 2010 21:24:36 +0000 (21:24 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Wed, 30 Jun 2010 21:24:36 +0000 (21:24 +0000)
configure.ac
libtransmission/net.c
libtransmission/net.h
libtransmission/peer-io.c
libtransmission/tr-dht.c
libtransmission/tr-lpd.c
libtransmission/trevent.c
libtransmission/web.c
third-party/dht/dht.c
third-party/miniupnp/miniupnpc.c

index 43af6efc4238e1c1f95eef63ba58565da6463e56..bb85c4a3214b42452af65072f75c285666d5f412 100644 (file)
@@ -85,7 +85,7 @@ AC_PROG_CXX
 AC_C_INLINE
 if test "x$GCC" = "xyes" ; then
 
-    CFLAGS="$CFLAGS -std=gnu99 -ggdb3 -Wall -W -Wpointer-arith -Wformat-security -Wcast-align -Wundef -Wcast-align -Wstrict-prototypes -Wmissing-declarations -Wmissing-format-attribute -Wredundant-decls -Wnested-externs -Wunused-parameter -Wwrite-strings"
+    CFLAGS="$CFLAGS -std=gnu99 -ggdb3 -Wall -W -Wpointer-arith -Wformat-security -Wcast-align -Wundef -Wcast-align -Wstrict-prototypes -Wmissing-declarations -Wmissing-format-attribute -Wredundant-decls -Wnested-externs -Wunused-parameter -Wwrite-strings -Wvariadic-macros -Waggregate-return -Wvla -Winline -Wfloat-equal"
 
     dnl figure out gcc version
     AC_MSG_CHECKING([gcc version])
index 0e244c6ee5063bab823fcd046ac4fb5924441823..d28e96cd5478a9e4cc24af6ef29de5dc99de4003 100644 (file)
@@ -147,6 +147,18 @@ tr_netInit( void )
     }
 }
 
+char *
+tr_net_strerror( char * buf, size_t buflen, int err )
+{
+    *buf = '\0';
+#ifdef WIN32
+    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, e, 0, buf, buflen, NULL );
+#else
+    tr_strlcpy( buf, tr_strerror( err ), buflen );
+#endif
+    return buf;
+}
+
 const char *
 tr_ntop( const tr_address * src, char * dst, int size )
 {
index 8b1b1fda6f8d8ffd3970aa435ff7b4d6e5daae71..14e5d97f2b28528b30330e70c8b7da3dc426d72b 100644 (file)
@@ -122,6 +122,12 @@ void tr_netCloseSocket( int fd );
 
 void tr_netInit( void );
 
+/**
+ * @brief get a human-representable string representing the network error.
+ * @param err an errno on Unix/Linux and an WSAError on win32)
+ */
+char* tr_net_strerror( char * buf, size_t buflen, int err );
+
 const unsigned char *tr_globalIPv6( void );
 
 #if defined( WIN32) && !defined(QT_DLL)
index 4b312763d9d60879ab0010a1e0937dc4dd1f2d0e..cfe61373fd726e7cbd8837c80d6bfc8bfec9fc72 100644 (file)
 
 #define MAGIC_NUMBER 206745
 
+#ifdef WIN32
+ #define EAGAIN       WSAEWOULDBLOCK
+ #define EINTR        WSAEINTR
+ #define EINPROGRESS  WSAEINPROGRESS
+ #define EPIPE        WSAECONNRESET
+#endif
+
 static size_t
 guessPacketOverhead( size_t d )
 {
@@ -221,9 +228,9 @@ event_read_cb( int fd, short event UNUSED, void * vio )
         return;
     }
 
-    errno = 0;
+    EVUTIL_SET_SOCKET_ERROR( 0 );
     res = evbuffer_read( io->inbuf, fd, howmuch );
-    e = errno;
+    e = EVUTIL_SOCKET_ERROR( );
 
     if( res > 0 )
     {
@@ -234,6 +241,7 @@ event_read_cb( int fd, short event UNUSED, void * vio )
     }
     else
     {
+        char errstr[512];
         short what = EVBUFFER_READ;
 
         if( res == 0 ) /* EOF */
@@ -246,7 +254,8 @@ event_read_cb( int fd, short event UNUSED, void * vio )
             what |= EVBUFFER_ERROR;
         }
 
-        dbgmsg( io, "event_read_cb got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, strerror( e ) );
+        tr_net_strerror( errstr, sizeof( errstr ), e ); 
+        dbgmsg( io, "event_read_cb got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, errstr );
 
         if( io->gotError != NULL )
             io->gotError( io, what, io->userData );
@@ -258,18 +267,19 @@ tr_evbuffer_write( tr_peerIo * io, int fd, size_t howmuch )
 {
     int e;
     int n;
+    char errstr[256];
     struct evbuffer * buffer = io->outbuf;
 
     howmuch = MIN( EVBUFFER_LENGTH( buffer ), howmuch );
 
-    errno = 0;
+    EVUTIL_SET_SOCKET_ERROR( 0 );
 #ifdef WIN32
     n = (int) send(fd, buffer->buffer, howmuch,  0 );
 #else
     n = (int) write(fd, buffer->buffer, howmuch );
 #endif
-    e = errno;
-    dbgmsg( io, "wrote %d to peer (%s)", n, (n==-1?strerror(e):"") );
+    e = EVUTIL_SOCKET_ERROR( );
+    dbgmsg( io, "wrote %d to peer (%s)", n, (n==-1?tr_net_strerror(errstr,sizeof(errstr),e):"") );
 
     if( n > 0 )
         evbuffer_drain( buffer, n );
@@ -310,23 +320,15 @@ event_write_cb( int fd, short event UNUSED, void * vio )
         return;
     }
 
-    errno = 0;
+    EVUTIL_SET_SOCKET_ERROR( 0 );
     res = tr_evbuffer_write( io, fd, howmuch );
-    e = errno;
+    e = EVUTIL_SOCKET_ERROR( );
 
     if (res == -1) {
-#ifndef WIN32
-/*todo. evbuffer uses WriteFile when WIN32 is set. WIN32 system calls do not
- *  *set errno. thus this error checking is not portable*/
         if (e == EAGAIN || e == EINTR || e == EINPROGRESS)
             goto reschedule;
         /* error case */
         what |= EVBUFFER_ERROR;
-
-#else
-        goto reschedule;
-#endif
-
     } else if (res == 0) {
         /* eof case */
         what |= EVBUFFER_EOF;
@@ -878,9 +880,10 @@ tr_peerIoTryRead( tr_peerIo * io, size_t howmuch )
     if(( howmuch = tr_bandwidthClamp( &io->bandwidth, TR_DOWN, howmuch )))
     {
         int e;
-        errno = 0;
+
+        EVUTIL_SET_SOCKET_ERROR( 0 );
         res = evbuffer_read( io->inbuf, io->socket, howmuch );
-        e = errno;
+        e = EVUTIL_SOCKET_ERROR( );
 
         dbgmsg( io, "read %d from peer (%s)", res, (res==-1?strerror(e):"") );
 
@@ -889,10 +892,12 @@ tr_peerIoTryRead( tr_peerIo * io, size_t howmuch )
 
         if( ( res <= 0 ) && ( io->gotError ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
         {
+            char errstr[512];
             short what = EVBUFFER_READ | EVBUFFER_ERROR;
             if( res == 0 )
                 what |= EVBUFFER_EOF;
-            dbgmsg( io, "tr_peerIoTryRead got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, strerror( e ) );
+            tr_net_strerror( errstr, sizeof( errstr ), e ); 
+            dbgmsg( io, "tr_peerIoTryRead got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, errstr );
             io->gotError( io, what, io->userData );
         }
     }
@@ -908,17 +913,20 @@ tr_peerIoTryWrite( tr_peerIo * io, size_t howmuch )
     if(( howmuch = tr_bandwidthClamp( &io->bandwidth, TR_UP, howmuch )))
     {
         int e;
-        errno = 0;
+        EVUTIL_SET_SOCKET_ERROR( 0 );
         n = tr_evbuffer_write( io, io->socket, howmuch );
-        e = errno;
+        e = EVUTIL_SOCKET_ERROR( );
 
         if( n > 0 )
             didWriteWrapper( io, n );
 
         if( ( n < 0 ) && ( io->gotError ) && ( e != EPIPE ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
         {
+            char errstr[512];
             const short what = EVBUFFER_WRITE | EVBUFFER_ERROR;
-            dbgmsg( io, "tr_peerIoTryWrite got an error. res is %d, what is %hd, errno is %d (%s)", n, what, e, strerror( e ) );
+
+            tr_net_strerror( errstr, sizeof( errstr ), e ); 
+            dbgmsg( io, "tr_peerIoTryWrite got an error. res is %d, what is %hd, errno is %d (%s)", n, what, e, errstr );
 
             if( io->gotError != NULL )
                 io->gotError( io, what, io->userData );
index 638c2d5a72261c6802ca0b6d79f569427dedcfec..5f62725b7d8c89a3e1dbb9974554082ff0a6c7df 100644 (file)
@@ -87,12 +87,11 @@ bootstrap_done( tr_session *session, int af )
 }
 
 static void
-nap( int roughly )
+nap( int roughly_sec )
 {
-    struct timeval tv;
-    tv.tv_sec = roughly / 2 + tr_cryptoWeakRandInt( roughly );
-    tv.tv_usec = tr_cryptoWeakRandInt( 1000000 );
-    select( 0, NULL, NULL, NULL, &tv );
+    const int roughly_msec = roughly_sec * 1000;
+    const int msec = roughly_msec/2 + tr_cryptoWeakRandInt(roughly_msec);
+    tr_wait_msec( msec );
 }
 
 static int
index c35bdb6db97e951b41eb6ba010384cd2b59cf5f8..93b215e951867e6b330abdef9b76c159341c40f3 100644 (file)
@@ -25,14 +25,24 @@ THE SOFTWARE.
 #include <stdio.h>
 
 /* posix */
-#include <netinet/in.h> /* sockaddr_in */
 #include <signal.h> /* sig_atomic_t */
 #include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h> /* socket(), bind() */
 #include <unistd.h> /* close() */
 #include <fcntl.h> /* fcntl(), O_NONBLOCK */
 #include <ctype.h> /* toupper() */
+#ifdef WIN32
+  #include <w32api.h>
+  #define WINDOWS  WindowsXP  /* freeaddrinfo(),getaddrinfo(),getnameinfo() */
+  #include <inttypes.h>
+  #include <ws2tcpip.h>
+  typedef uint16_t in_port_t;                  /* all missing */
+  extern int fcntl (int fd, int cmd, ...);
+  #define O_NONBLOCK   04000
+#else
+  #include <sys/types.h>
+  #include <sys/socket.h> /* socket(), bind() */
+  #include <netinet/in.h> /* sockaddr_in */
+#endif
 
 /* third party */
 #include <event.h>
@@ -246,6 +256,14 @@ static int lpd_extractParam( const char* const str, const char* const name, int
 * @brief Configures additional capabilities for a socket */
 static inline int lpd_configureSocket( int sock, int add )
 {
+#ifdef WIN32
+    unsigned long flags = 1;
+
+    if (add != O_NONBLOCK)
+        return -1;             /* not supported */
+    if (ioctlsocket(sock, FIONBIO, &flags) == SOCKET_ERROR)
+        return -1;
+#else
     /* read-modify-write socket flags */
     int flags = fcntl( sock, F_GETFL );
 
@@ -254,6 +272,7 @@ static inline int lpd_configureSocket( int sock, int add )
 
     if( fcntl( sock, F_SETFL, add | flags ) == -1 )
         return -1;
+#endif
 
     return add;
 }
index 5619c97f52b1401668ffa16cf64147aba1efaf3b..29bc5b0ea7392c75b7a323e36772605b634f4323 100644 (file)
@@ -95,10 +95,9 @@ static int
 piperead( int s, char *buf, int len )
 {
     int ret = recv(s, buf, len, 0);
-    int werror = 0;
 
     if (ret < 0) {
-        werror= WSAGetLastError();
+        const int werror= WSAGetLastError();
         switch(werror) {
           /* simplified error mapping (not valid for connect) */
             case WSAEWOULDBLOCK:
index 2e7b7d58634e8d0b069297bcc21f3153a30f8ec0..e9a72fe799e79ea46e0c653180e18f107557291a 100644 (file)
@@ -240,6 +240,38 @@ tr_webRun( tr_session         * session,
     }
 }
 
+/**
+ * Portability wrapper for select().
+ *
+ * http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx
+ * On win32, any two of the parameters, readfds, writefds, or exceptfds,
+ * can be given as null. At least one must be non-null, and any non-null
+ * descriptor set must contain at least one handle to a socket. 
+ */
+static void
+tr_select( int nfds,
+           fd_set * r_fd_set, fd_set * w_fd_set, fd_set * c_fd_set,
+           struct timeval  * t )
+{
+#ifdef WIN32
+    if( !r_fd_set->fd_count && !w_fd_set->fd_count && !c_fd_set->fd_count )
+    {
+        tr_wait_msec( msec );
+    }
+    else if( select( 0, r_fd_set->fd_count ? r_fd_set : NULL,
+                        w_fd_set->fd_count ? w_fd_set : NULL,
+                        c_fd_set->fd_count ? c_fd_set : NULL, t ) < 0 )
+    {
+        char errstr[512];
+        const int e = EVUTIL_SOCKET_ERROR( );
+        tr_net_strerror( errstr, sizeof( errstr ), e );
+        dbgmsg( "Error: select (%d) %s", e, errstr ); 
+    }
+#else
+    select( nfds, r_fd_set, w_fd_set, c_fd_set, t );
+#endif
+}
+
 static void
 tr_webThreadFunc( void * vsession )
 {
@@ -308,17 +340,7 @@ tr_webThreadFunc( void * vsession )
             t.tv_sec =  usec / 1000000;
             t.tv_usec = usec % 1000000;
 
-#ifdef WIN32
-            /* see ticket #3311, comments 16-18 */
-            if( !r_fd_set.fd_count && !w_fd_set.fd_count && !c_fd_set.fd_count )
-                tr_wait_msec( msec );
-            else
-                select( 0, r_fd_set.fd_count ? &r_fd_set : NULL,
-                           w_fd_set.fd_count ? &w_fd_set : NULL,
-                           c_fd_set.fd_count ? &c_fd_set : NULL, &t );
-#else
-            select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t );
-#endif
+            tr_select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t );
         }
 
         /* call curl_multi_perform() */
index b22e68070854daf27e94f347bcc8ba82bba2f759..3a165a721b927c8d60b33aa75796d2f54fe72d8b 100644 (file)
@@ -39,10 +39,19 @@ THE SOFTWARE.
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/time.h>
+#ifndef WIN32
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#else
+#include <w32api.h>
+#define WINVER  WindowsXP       /* freeaddrinfo(),getaddrinfo(),getnameinfo() */
+#include <ws2tcpip.h>
+#define random rand            /* int rand() since no long random() */
+extern const char *inet_ntop(int, const void *, char *, socklen_t); /* from libtransmission (utils.c) */
+#define EAFNOSUPPORT            WSAEAFNOSUPPORT
+#endif
 
 #include "dht.h"
 
@@ -1530,6 +1539,10 @@ int
 dht_init(int s, int s6, const unsigned char *id, const unsigned char *v)
 {
     int rc;
+#ifdef WIN32
+    unsigned long flags = 1;
+#endif
+
 
     if(dht_socket >= 0 || dht_socket6 >= 0 || buckets || buckets6) {
         errno = EBUSY;
@@ -1548,11 +1561,15 @@ dht_init(int s, int s6, const unsigned char *id, const unsigned char *v)
             return -1;
         buckets->af = AF_INET;
 
+#ifndef WIN32
         rc = fcntl(s, F_GETFL, 0);
         if(rc < 0)
             goto fail;
 
         rc = fcntl(s, F_SETFL, (rc | O_NONBLOCK));
+#else
+       rc = ioctlsocket(s, FIONBIO, &flags);
+#endif
         if(rc < 0)
             goto fail;
     }
@@ -1563,11 +1580,15 @@ dht_init(int s, int s6, const unsigned char *id, const unsigned char *v)
             return -1;
         buckets6->af = AF_INET6;
 
+#ifndef WIN32
         rc = fcntl(s6, F_GETFL, 0);
         if(rc < 0)
             goto fail;
 
         rc = fcntl(s6, F_SETFL, (rc | O_NONBLOCK));
+#else
+        rc = ioctlsocket(s6, FIONBIO, &flags);
+#endif
         if(rc < 0)
             goto fail;
     }
index 484a17e7799a20b21560c65f3b77e07b5656317a..c4cdd3c7c76d02e3581fcf100c90087a1e2e907f 100644 (file)
@@ -24,7 +24,7 @@
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <io.h>
-#include <IPHlpApi.h>
+#include <iphlpapi.h>
 #define snprintf _snprintf
 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
 #define strncasecmp _memicmp