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 + -
显示快捷键?