diff --git a/libtransmission/trevent.c b/libtransmission/trevent.c index b9748c79f..1502c19d8 100644 --- a/libtransmission/trevent.c +++ b/libtransmission/trevent.c @@ -19,12 +19,92 @@ #include #ifdef WIN32 - #include - #define pipe( f ) _pipe( f, 1000, _O_BINARY ) + +#include + +static int +pgpipe( int handles[2] ) +{ + SOCKET s; + struct sockaddr_in serv_addr; + int len = sizeof( serv_addr ); + + handles[0] = handles[1] = INVALID_SOCKET; + + if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET ) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to create socket: %ui", WSAGetLastError()))); */ + return -1; + } + + memset( &serv_addr, 0, sizeof( serv_addr ) ); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(0); + serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to bind: %ui", WSAGetLastError()))); */ + closesocket(s); + return -1; + } + if (listen(s, 1) == SOCKET_ERROR) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to listen: %ui", WSAGetLastError()))); */ + closesocket(s); + return -1; + } + if (getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to getsockname: %ui", WSAGetLastError()))); */ + closesocket(s); + return -1; + } + if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to create socket 2: %ui", WSAGetLastError()))); */ + closesocket(s); + return -1; + } + + if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to connect socket: %ui", WSAGetLastError()))); */ + closesocket(s); + return -1; + } + if ((handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET) + { +/* ereport(LOG, (errmsg_internal("pgpipe failed to accept socket: %ui", WSAGetLastError()))); */ + closesocket(handles[1]); + handles[1] = INVALID_SOCKET; + closesocket(s); + return -1; + } + closesocket(s); + return 0; +} + +static int +piperead( int s, char *buf, int len ) +{ + int ret = recv(s, buf, len, 0); + + if (ret < 0 && WSAGetLastError() == WSAECONNRESET) + /* EOF on the pipe! (win32 socket based implementation) */ + ret = 0; + return ret; +} + +#define pipe(a) pgpipe(a) +#define pipewrite(a,b,c) send(a,b,c,0) + #else - #include +#define piperead(a,b,c) read(a,b,c) +#define pipewrite(a,b,c) write(a,b,c) #endif +#include + #include #include "transmission.h" @@ -83,7 +163,7 @@ readFromPipe( int fd, ch = '\0'; do { - ret = read( fd, &ch, 1 ); + ret = piperead( fd, &ch, 1 ); } while( !eh->die && ret < 0 && errno == EAGAIN ); @@ -95,7 +175,7 @@ readFromPipe( int fd, { struct tr_run_data data; const size_t nwant = sizeof( data ); - const ssize_t ngot = read( fd, &data, nwant ); + const ssize_t ngot = piperead( fd, &data, nwant ); if( !eh->die && ( ngot == (ssize_t)nwant ) ) { dbgmsg( "invoking function in libevent thread" ); @@ -108,7 +188,7 @@ readFromPipe( int fd, { tr_timer * timer; const size_t nwant = sizeof( timer ); - const ssize_t ngot = read( fd, &timer, nwant ); + const ssize_t ngot = piperead( fd, &timer, nwant ); if( !eh->die && ( ngot == (ssize_t)nwant ) ) { dbgmsg( "adding timer in libevent thread" ); @@ -268,8 +348,8 @@ tr_timerNew( struct tr_handle * handle, tr_lock * lock = handle->events->lock; tr_lockLock( lock ); - write( fd, &ch, 1 ); - write( fd, &timer, sizeof( timer ) ); + pipewrite( fd, &ch, 1 ); + pipewrite( fd, &timer, sizeof( timer ) ); tr_lockUnlock( lock ); } @@ -293,10 +373,10 @@ tr_runInEventThread( struct tr_handle * handle, struct tr_run_data data; tr_lockLock( lock ); - write( fd, &ch, 1 ); + pipewrite( fd, &ch, 1 ); data.func = func; data.user_data = user_data; - write( fd, &data, sizeof( data ) ); + pipewrite( fd, &data, sizeof( data ) ); tr_lockUnlock( lock ); } }