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:
parent
a257d0fb89
commit
f6f9d898e4
1 changed files with 90 additions and 10 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue