1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-31 19:34:05 +00:00

(libT) #1327: win32 cannot select() on the file descriptors of pipe()

This commit is contained in:
Charles Kerr 2008-10-14 18:17:33 +00:00
parent a257d0fb89
commit f6f9d898e4

View file

@ -19,12 +19,92 @@
#include <signal.h>
#ifdef WIN32
#include <fcntl.h>
#define pipe( f ) _pipe( f, 1000, _O_BINARY )
#include <WinSock2.h>
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 <unistd.h>
#define piperead(a,b,c) read(a,b,c)
#define pipewrite(a,b,c) write(a,b,c)
#endif
#include <unistd.h>
#include <event.h>
#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 );
}
}