Ticket #1079: pipefunctions.patch

File pipefunctions.patch, 8.1 KB (added by alexat, 10 years ago)
  • libtransmission/platform.c

     
    233233}
    234234
    235235/***
     236****  PIPES
     237***/
     238
     239#ifdef WIN32
     240
     241int
     242tr_pipe( int handles[2] )
     243{
     244    SOCKET s;
     245    struct sockaddr_in serv_addr;
     246    int len = sizeof( serv_addr );
     247
     248    handles[0] = handles[1] = INVALID_SOCKET;
     249
     250    if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
     251    {
     252        tr_dbg("tr_pipe failed to create socket: %ui", WSAGetLastError());
     253        return -1;
     254    }
     255
     256    memset( &serv_addr, 0, sizeof( serv_addr ) );
     257    serv_addr.sin_family = AF_INET;
     258    serv_addr.sin_port = htons(0);
     259    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
     260    if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
     261    {
     262        tr_dbg("tr_pipe failed to bind: %ui", WSAGetLastError());
     263        closesocket(s);
     264        return -1;
     265    }
     266    if (listen(s, 1) == SOCKET_ERROR)
     267    {
     268        tr_ndbg("event","tr_pipe failed to listen: %ui", WSAGetLastError());
     269        closesocket(s);
     270        return -1;
     271    }
     272    if (getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR)
     273    {
     274        tr_dbg("tr_pipe failed to getsockname: %ui", WSAGetLastError());
     275        closesocket(s);
     276        return -1;
     277    }
     278    if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
     279    {
     280        tr_dbg("tr_pipe failed to create socket 2: %ui", WSAGetLastError());
     281        closesocket(s);
     282        return -1;
     283    }
     284
     285    if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
     286    {
     287        tr_dbg("tr_pipe failed to connect socket: %ui", WSAGetLastError());
     288        closesocket(s);
     289        return -1;
     290    }
     291    if ((handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET)
     292    {
     293        tr_dbg("tr_pipe failed to accept socket: %ui", WSAGetLastError());
     294        closesocket(handles[1]);
     295        handles[1] = INVALID_SOCKET;
     296        closesocket(s);
     297        return -1;
     298    }
     299    closesocket(s);
     300    return 0;
     301}
     302
     303int
     304tr_piperead( int s, char *buf, int len )
     305{
     306    int ret = recv(s, buf, len, 0);
     307
     308    if (ret < 0) {
     309        const int werror= WSAGetLastError();
     310        switch(werror) {
     311          /* simplified error mapping (not valid for connect) */
     312            case WSAEWOULDBLOCK:
     313                errno = EAGAIN;
     314                break;
     315            case WSAECONNRESET:
     316                /* EOF on the pipe! (win32 socket based implementation) */
     317                ret = 0;
     318                /* fall through */
     319            default:
     320                errno = werror;
     321                break;
     322        }
     323    } else
     324        errno = 0;
     325    return ret;
     326}
     327
     328int
     329tr_set_nonblocking( int s )
     330{
     331    unsigned long opt = 1;
     332    return ioctlsocket( s, FIONBIO, &opt );
     333}
     334
     335#else
     336
     337#include <fcntl.h>
     338
     339int
     340tr_set_nonblocking( int s )
     341{
     342#if defined( O_NONBLOCK )
     343    return fcntl( s, F_SETFL, fcntl( s, F_GETFL ) | O_NONBLOCK );
     344#else
     345    unsigned long opt = 1;
     346    return ioctl( s, FIONBIO, &opt );
     347#endif
     348}
     349
     350#endif
     351
     352/***
    236353****  PATHS
    237354***/
    238355
  • libtransmission/trevent.c

     
    2323#include "net.h"
    2424#include "session.h"
    2525
    26 #ifdef WIN32
    27 
    28 #include "utils.h"
    29 #include <winsock2.h>
    30 
    31 static int
    32 pgpipe( int handles[2] )
    33 {
    34     SOCKET s;
    35     struct sockaddr_in serv_addr;
    36     int len = sizeof( serv_addr );
    37 
    38     handles[0] = handles[1] = INVALID_SOCKET;
    39 
    40     if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
    41     {
    42         tr_dbg("pgpipe failed to create socket: %ui", WSAGetLastError());
    43         return -1;
    44     }
    45 
    46     memset( &serv_addr, 0, sizeof( serv_addr ) );
    47     serv_addr.sin_family = AF_INET;
    48     serv_addr.sin_port = htons(0);
    49     serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    50     if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
    51     {
    52         tr_dbg("pgpipe failed to bind: %ui", WSAGetLastError());
    53         closesocket(s);
    54         return -1;
    55     }
    56     if (listen(s, 1) == SOCKET_ERROR)
    57     {
    58         tr_ndbg("event","pgpipe failed to listen: %ui", WSAGetLastError());
    59         closesocket(s);
    60         return -1;
    61     }
    62     if (getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR)
    63     {
    64         tr_dbg("pgpipe failed to getsockname: %ui", WSAGetLastError());
    65         closesocket(s);
    66         return -1;
    67     }
    68     if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    69     {
    70         tr_dbg("pgpipe failed to create socket 2: %ui", WSAGetLastError());
    71         closesocket(s);
    72         return -1;
    73     }
    74 
    75     if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
    76     {
    77         tr_dbg("pgpipe failed to connect socket: %ui", WSAGetLastError());
    78         closesocket(s);
    79         return -1;
    80     }
    81     if ((handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET)
    82     {
    83         tr_dbg("pgpipe failed to accept socket: %ui", WSAGetLastError());
    84         closesocket(handles[1]);
    85         handles[1] = INVALID_SOCKET;
    86         closesocket(s);
    87         return -1;
    88     }
    89     closesocket(s);
    90     return 0;
    91 }
    92 
    93 static int
    94 piperead( int s, char *buf, int len )
    95 {
    96     int ret = recv(s, buf, len, 0);
    97 
    98     if (ret < 0) {
    99         const int werror= WSAGetLastError();
    100         switch(werror) {
    101           /* simplified error mapping (not valid for connect) */
    102             case WSAEWOULDBLOCK:
    103                 errno = EAGAIN;
    104                 break;
    105             case WSAECONNRESET:
    106                 /* EOF on the pipe! (win32 socket based implementation) */
    107                 ret = 0;
    108                 /* fall through */
    109             default:
    110                 errno = werror;
    111                 break;
    112         }
    113     } else
    114         errno = 0;
    115     return ret;
    116 }
    117 
    118 #define pipe(a) pgpipe(a)
    119 #define pipewrite(a,b,c) send(a,(char*)b,c,0)
    120 
    121 #else
    122 #define piperead(a,b,c) read(a,b,c)
    123 #define pipewrite(a,b,c) write(a,b,c)
    124 #endif
    125 
    126 #include <unistd.h> /* read(), write(), pipe() */
    127 
    128 #include "transmission.h"
    12926#include "platform.h" /* tr_lockLock() */
    13027#include "trevent.h"
    13128#include "utils.h"
     
    17370    ch = '\0';
    17471    do
    17572    {
    176         ret = piperead( fd, &ch, 1 );
     73        ret = tr_piperead( fd, &ch, 1 );
    17774    }
    17875    while( !eh->die && ret < 0 && errno == EAGAIN );
    17976
     
    18582        {
    18683            struct tr_run_data data;
    18784            const size_t       nwant = sizeof( data );
    188             const ssize_t      ngot = piperead( fd, &data, nwant );
     85            const ssize_t      ngot = tr_piperead( fd, &data, nwant );
    18986            if( !eh->die && ( ngot == (ssize_t)nwant ) )
    19087            {
    19188                dbgmsg( "invoking function in libevent thread" );
     
    264161
    265162    eh = tr_new0( tr_event_handle, 1 );
    266163    eh->lock = tr_lockNew( );
    267     pipe( eh->fds );
     164    tr_pipe( eh->fds );
    268165    eh->session = session;
    269166    eh->thread = tr_threadNew( libeventThreadFunc, eh );
    270167
     
    319216        struct tr_run_data data;
    320217
    321218        tr_lockLock( lock );
    322         pipewrite( fd, &ch, 1 );
     219        tr_pipewrite( fd, &ch, 1 );
    323220        data.func = func;
    324221        data.user_data = user_data;
    325         pipewrite( fd, &data, sizeof( data ) );
     222        tr_pipewrite( fd, &data, sizeof( data ) );
    326223        tr_lockUnlock( lock );
    327224    }
    328225}
  • libtransmission/platform.h

     
    7575    @param thread the thread being tested */
    7676bool tr_amInThread( const tr_thread * );
    7777
     78#ifdef WIN32
     79
     80#include <winsock2.h>
     81
     82int    tr_pipe( int handles[2] );
     83
     84int    tr_piperead( int s, char *buf, int len );
     85
     86#define tr_pipewrite(a,b,c) send(a,(char*)b,c,0)
     87
     88#else
     89
     90#include <unistd.h>
     91
     92#define tr_pipe(a) pipe(a)
     93#define tr_piperead(a,b,c) read(a,b,c)
     94#define tr_pipewrite(a,b,c) write(a,b,c)
     95
     96#endif
     97
     98/** @brief set socket non-blocking
     99    @return a value other than -1 on success */
     100int tr_set_nonblocking( int s );
     101
    78102/***
    79103****
    80104***/