(trunk) #3311 "MingW build of Transmission" -- apply more of rb07's diffs, though edited to lessen the inevitable #ifdefs

This commit is contained in:
Charles Kerr 2010-06-30 21:24:36 +00:00
parent 254a1f15cb
commit 954a309d8f
10 changed files with 131 additions and 45 deletions

View 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])

View 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 )
{

View 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)

View File

@ -38,6 +38,13 @@
#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 );

View 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

View 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;
}

View 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:

View 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() */

21
third-party/dht/dht.c vendored
View 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;
}

View 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