sysdeps_win32.c

来自「Android 一些工具」· C语言 代码 · 共 1,954 行 · 第 1/4 页

C
1,954
字号
}static int_fh_socket_lseek( FH  f, int pos, int origin ){    errno = EPIPE;    return -1;}static int_fh_socket_read( FH  f, void*  buf, int  len ){    int  result = recv( f->fh_socket, buf, len, 0 );    if (result == SOCKET_ERROR) {        _socket_set_errno();        result = -1;    }    return  result;}static int_fh_socket_write( FH  f, const void*  buf, int  len ){    int  result = send( f->fh_socket, buf, len, 0 );    if (result == SOCKET_ERROR) {        _socket_set_errno();        result = -1;    }    return result;}static void  _fh_socket_hook( FH  f, int  event, EventHook  hook );  /* forward */static const FHClassRec  _fh_socket_class ={    _fh_socket_init,    _fh_socket_close,    _fh_socket_lseek,    _fh_socket_read,    _fh_socket_write,    _fh_socket_hook};/**************************************************************************//**************************************************************************//*****                                                                *****//*****    replacement for libs/cutils/socket_xxxx.c                   *****//*****                                                                *****//**************************************************************************//**************************************************************************/#include <winsock2.h>static int  _winsock_init;static void_cleanup_winsock( void ){    WSACleanup();}static void_init_winsock( void ){    if (!_winsock_init) {        WSADATA  wsaData;        int      rc = WSAStartup( MAKEWORD(2,2), &wsaData);        if (rc != 0) {            fatal( "adb: could not initialize Winsock\n" );        }        atexit( _cleanup_winsock );        _winsock_init = 1;    }}int socket_loopback_client(int port, int type){    FH  f = _fh_alloc( &_fh_socket_class );    struct sockaddr_in addr;    SOCKET  s;    if (!f)        return -1;    if (!_winsock_init)        _init_winsock();    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);    s = socket(AF_INET, type, 0);    if(s == INVALID_SOCKET) {        D("socket_loopback_client: could not create socket\n" );        _fh_close(f);        return -1;    }    f->fh_socket = s;    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port );        _fh_close(f);        return -1;    }    snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );    D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );    return _fh_to_int(f);}#define LISTEN_BACKLOG 4int socket_loopback_server(int port, int type){    FH   f = _fh_alloc( &_fh_socket_class );    struct sockaddr_in addr;    SOCKET  s;    int  n;    if (!f) {        return -1;    }    if (!_winsock_init)        _init_winsock();    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);    s = socket(AF_INET, type, 0);    if(s == INVALID_SOCKET) return -1;    f->fh_socket = s;    n = 1;    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        _fh_close(f);        return -1;    }    if (type == SOCK_STREAM) {        int ret;        ret = listen(s, LISTEN_BACKLOG);        if (ret < 0) {            _fh_close(f);            return -1;        }    }    snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );    D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );    return _fh_to_int(f);}int socket_network_client(const char *host, int port, int type){    FH  f = _fh_alloc( &_fh_socket_class );    struct hostent *hp;    struct sockaddr_in addr;    SOCKET s;    if (!f)        return -1;    if (!_winsock_init)        _init_winsock();    hp = gethostbyname(host);    if(hp == 0) {        _fh_close(f);        return -1;    }    memset(&addr, 0, sizeof(addr));    addr.sin_family = hp->h_addrtype;    addr.sin_port = htons(port);    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);    s = socket(hp->h_addrtype, type, 0);    if(s == INVALID_SOCKET) {        _fh_close(f);        return -1;    }    f->fh_socket = s;    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        _fh_close(f);        return -1;    }    snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );    D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );    return _fh_to_int(f);}int socket_inaddr_any_server(int port, int type){    FH  f = _fh_alloc( &_fh_socket_class );    struct sockaddr_in addr;    SOCKET  s;    int n;    if (!f)        return -1;    if (!_winsock_init)        _init_winsock();    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = htonl(INADDR_ANY);    s = socket(AF_INET, type, 0);    if(s == INVALID_SOCKET) {        _fh_close(f);        return -1;    }    f->fh_socket = s;    n = 1;    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        _fh_close(f);        return -1;    }    if (type == SOCK_STREAM) {        int ret;        ret = listen(s, LISTEN_BACKLOG);        if (ret < 0) {            _fh_close(f);            return -1;        }    }    snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );    D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );    return _fh_to_int(f);}#undef acceptint  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen){    FH   serverfh = _fh_from_int(serverfd);    FH   fh;        if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {        D( "adb_socket_accept: invalid fd %d\n", serverfd );        return -1;    }        fh = _fh_alloc( &_fh_socket_class );    if (!fh) {        D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );        return -1;    }    fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );    if (fh->fh_socket == INVALID_SOCKET) {        _fh_close( fh );        D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );        return -1;    }        snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );    return  _fh_to_int(fh);}void  disable_tcp_nagle(int fd){    FH   fh = _fh_from_int(fd);    int  on;        if ( !fh || fh->clazz != &_fh_socket_class )        return;    setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) );}/**************************************************************************//**************************************************************************//*****                                                                *****//*****    emulated socketpairs                                       *****//*****                                                                *****//**************************************************************************//**************************************************************************//* we implement socketpairs directly in use space for the following reasons: *   - it avoids copying data from/to the Nt kernel *   - it allows us to implement fdevent hooks easily and cheaply, something *     that is not possible with standard Win32 pipes !! * * basically, we use two circular buffers, each one corresponding to a given * direction. * * each buffer is implemented as two regions: * *   region A which is (a_start,a_end) *   region B which is (0, b_end)  with b_end <= a_start * * an empty buffer has:  a_start = a_end = b_end = 0 * * a_start is the pointer where we start reading data * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE, * then you start writing at b_end * * the buffer is full when  b_end == a_start && a_end == BUFFER_SIZE * * there is room when b_end < a_start || a_end < BUFER_SIZE * * when reading, a_start is incremented, it a_start meets a_end, then * we do:  a_start = 0, a_end = b_end, b_end = 0, and keep going on.. */#define  BIP_BUFFER_SIZE   4096#if 0#include <stdio.h>#  define  BIPD(x)      D x#  define  BIPDUMP   bip_dump_hexstatic void  bip_dump_hex( const unsigned char*  ptr, size_t  len ){    int  nn, len2 = len;    if (len2 > 8) len2 = 8;    for (nn = 0; nn < len2; nn++)         printf("%02x", ptr[nn]);    printf("  ");    for (nn = 0; nn < len2; nn++) {        int  c = ptr[nn];        if (c < 32 || c > 127)            c = '.';        printf("%c", c);    }    printf("\n");    fflush(stdout);}#else#  define  BIPD(x)        do {} while (0)#  define  BIPDUMP(p,l)   BIPD(p)#endiftypedef struct BipBufferRec_{    int                a_start;    int                a_end;    int                b_end;    int                fdin;    int                fdout;    int                closed;    int                can_write;  /* boolean */    HANDLE             evt_write;  /* event signaled when one can write to a buffer  */    int                can_read;   /* boolean */    HANDLE             evt_read;   /* event signaled when one can read from a buffer */    CRITICAL_SECTION  lock;    unsigned char      buff[ BIP_BUFFER_SIZE ];} BipBufferRec, *BipBuffer;static voidbip_buffer_init( BipBuffer  buffer ){    D( "bit_buffer_init %p\n", buffer );    buffer->a_start   = 0;    buffer->a_end     = 0;    buffer->b_end     = 0;    buffer->can_write = 1;    buffer->can_read  = 0;    buffer->fdin      = 0;    buffer->fdout     = 0;    buffer->closed    = 0;    buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );    buffer->evt_read  = CreateEvent( NULL, TRUE, FALSE, NULL );    InitializeCriticalSection( &buffer->lock );}static voidbip_buffer_close( BipBuffer  bip ){    bip->closed = 1;    if (!bip->can_read) {        SetEvent( bip->evt_read );    }    if (!bip->can_write) {        SetEvent( bip->evt_write );    }}static voidbip_buffer_done( BipBuffer  bip ){    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));    CloseHandle( bip->evt_read );    CloseHandle( bip->evt_write );    DeleteCriticalSection( &bip->lock );}static intbip_buffer_write( BipBuffer  bip, const void* src, int  len ){    int  avail, count = 0;    if (len <= 0)        return 0;    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));    BIPDUMP( src, len );    EnterCriticalSection( &bip->lock );    while (!bip->can_write) {        int  ret;        LeaveCriticalSection( &bip->lock );        if (bip->closed) {            errno = EPIPE;            return -1;        }        /* spinlocking here is probably unfair, but let's live with it */        ret = WaitForSingleObject( bip->evt_write, INFINITE );        if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );            return 0;        }        if (bip->closed) {            errno = EPIPE;            return -1;        }        EnterCriticalSection( &bip->lock );    }    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));    avail = BIP_BUFFER_SIZE - bip->a_end;    if (avail > 0)    {        /* we can append to region A */        if (avail > len)            avail = len;                 memcpy( bip->buff + bip->a_end, src, avail );        src   += avail;        count += avail;        len   -= avail;             bip->a_end += avail;        if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {            bip->can_write = 0;            ResetEvent( bip->evt_write );            goto Exit;        }    }        if (len == 0)        goto Exit;    avail = bip->a_start - bip->b_end;    assert( avail > 0 );  /* since can_write is TRUE */        if (avail > len)        avail = len;            memcpy( bip->buff + bip->b_end, src, avail );    count += avail;    bip->b_end += avail;        if (bip->b_end == bip->a_start) {        bip->can_write = 0;        ResetEvent( bip->evt_write );    }    Exit:    assert( count > 0 );    if ( !bip->can_read ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?