mirror of
https://github.com/transmission/transmission
synced 2025-02-12 09:25:03 +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>
|
#include <signal.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#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
|
#else
|
||||||
#include <unistd.h>
|
#define piperead(a,b,c) read(a,b,c)
|
||||||
|
#define pipewrite(a,b,c) write(a,b,c)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
|
@ -83,7 +163,7 @@ readFromPipe( int fd,
|
||||||
ch = '\0';
|
ch = '\0';
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = read( fd, &ch, 1 );
|
ret = piperead( fd, &ch, 1 );
|
||||||
}
|
}
|
||||||
while( !eh->die && ret < 0 && errno == EAGAIN );
|
while( !eh->die && ret < 0 && errno == EAGAIN );
|
||||||
|
|
||||||
|
@ -95,7 +175,7 @@ readFromPipe( int fd,
|
||||||
{
|
{
|
||||||
struct tr_run_data data;
|
struct tr_run_data data;
|
||||||
const size_t nwant = sizeof( 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 ) )
|
if( !eh->die && ( ngot == (ssize_t)nwant ) )
|
||||||
{
|
{
|
||||||
dbgmsg( "invoking function in libevent thread" );
|
dbgmsg( "invoking function in libevent thread" );
|
||||||
|
@ -108,7 +188,7 @@ readFromPipe( int fd,
|
||||||
{
|
{
|
||||||
tr_timer * timer;
|
tr_timer * timer;
|
||||||
const size_t nwant = sizeof( 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 ) )
|
if( !eh->die && ( ngot == (ssize_t)nwant ) )
|
||||||
{
|
{
|
||||||
dbgmsg( "adding timer in libevent thread" );
|
dbgmsg( "adding timer in libevent thread" );
|
||||||
|
@ -268,8 +348,8 @@ tr_timerNew( struct tr_handle * handle,
|
||||||
tr_lock * lock = handle->events->lock;
|
tr_lock * lock = handle->events->lock;
|
||||||
|
|
||||||
tr_lockLock( lock );
|
tr_lockLock( lock );
|
||||||
write( fd, &ch, 1 );
|
pipewrite( fd, &ch, 1 );
|
||||||
write( fd, &timer, sizeof( timer ) );
|
pipewrite( fd, &timer, sizeof( timer ) );
|
||||||
tr_lockUnlock( lock );
|
tr_lockUnlock( lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,10 +373,10 @@ tr_runInEventThread( struct tr_handle * handle,
|
||||||
struct tr_run_data data;
|
struct tr_run_data data;
|
||||||
|
|
||||||
tr_lockLock( lock );
|
tr_lockLock( lock );
|
||||||
write( fd, &ch, 1 );
|
pipewrite( fd, &ch, 1 );
|
||||||
data.func = func;
|
data.func = func;
|
||||||
data.user_data = user_data;
|
data.user_data = user_data;
|
||||||
write( fd, &data, sizeof( data ) );
|
pipewrite( fd, &data, sizeof( data ) );
|
||||||
tr_lockUnlock( lock );
|
tr_lockUnlock( lock );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue