sysdeps_win32.c revision 35237d135807af84bf9b0e5b8d7f8633e58db6f5
1#include "sysdeps.h" 2#include <windows.h> 3#include <winsock2.h> 4#include <stdio.h> 5#include <errno.h> 6#define TRACE_TAG TRACE_SYSDEPS 7#include "adb.h" 8 9extern void fatal(const char *fmt, ...); 10 11#define assert(cond) do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0) 12 13/**************************************************************************/ 14/**************************************************************************/ 15/***** *****/ 16/***** replaces libs/cutils/load_file.c *****/ 17/***** *****/ 18/**************************************************************************/ 19/**************************************************************************/ 20 21void *load_file(const char *fn, unsigned *_sz) 22{ 23 HANDLE file; 24 char *data; 25 DWORD file_size; 26 27 file = CreateFile( fn, 28 GENERIC_READ, 29 FILE_SHARE_READ, 30 NULL, 31 OPEN_EXISTING, 32 0, 33 NULL ); 34 35 if (file == INVALID_HANDLE_VALUE) 36 return NULL; 37 38 file_size = GetFileSize( file, NULL ); 39 data = NULL; 40 41 if (file_size > 0) { 42 data = (char*) malloc( file_size + 1 ); 43 if (data == NULL) { 44 D("load_file: could not allocate %ld bytes\n", file_size ); 45 file_size = 0; 46 } else { 47 DWORD out_bytes; 48 49 if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) || 50 out_bytes != file_size ) 51 { 52 D("load_file: could not read %ld bytes from '%s'\n", file_size, fn); 53 free(data); 54 data = NULL; 55 file_size = 0; 56 } 57 } 58 } 59 CloseHandle( file ); 60 61 *_sz = (unsigned) file_size; 62 return data; 63} 64 65/**************************************************************************/ 66/**************************************************************************/ 67/***** *****/ 68/***** common file descriptor handling *****/ 69/***** *****/ 70/**************************************************************************/ 71/**************************************************************************/ 72 73typedef const struct FHClassRec_* FHClass; 74 75typedef struct FHRec_* FH; 76 77typedef struct EventHookRec_* EventHook; 78 79typedef struct FHClassRec_ 80{ 81 void (*_fh_init) ( FH f ); 82 int (*_fh_close)( FH f ); 83 int (*_fh_lseek)( FH f, int pos, int origin ); 84 int (*_fh_read) ( FH f, void* buf, int len ); 85 int (*_fh_write)( FH f, const void* buf, int len ); 86 void (*_fh_hook) ( FH f, int events, EventHook hook ); 87 88} FHClassRec; 89 90/* used to emulate unix-domain socket pairs */ 91typedef struct SocketPairRec_* SocketPair; 92 93typedef struct FHRec_ 94{ 95 FHClass clazz; 96 int used; 97 int eof; 98 union { 99 HANDLE handle; 100 SOCKET socket; 101 SocketPair pair; 102 } u; 103 104 HANDLE event; 105 int mask; 106 107 char name[32]; 108 109} FHRec; 110 111#define fh_handle u.handle 112#define fh_socket u.socket 113#define fh_pair u.pair 114 115#define WIN32_FH_BASE 100 116 117#define WIN32_MAX_FHS 128 118 119static adb_mutex_t _win32_lock; 120static FHRec _win32_fhs[ WIN32_MAX_FHS ]; 121static int _win32_fh_count; 122 123static FH 124_fh_from_int( int fd ) 125{ 126 FH f; 127 128 fd -= WIN32_FH_BASE; 129 130 if (fd < 0 || fd >= _win32_fh_count) { 131 D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE ); 132 errno = EBADF; 133 return NULL; 134 } 135 136 f = &_win32_fhs[fd]; 137 138 if (f->used == 0) { 139 D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE ); 140 errno = EBADF; 141 return NULL; 142 } 143 144 return f; 145} 146 147 148static int 149_fh_to_int( FH f ) 150{ 151 if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS) 152 return (int)(f - _win32_fhs) + WIN32_FH_BASE; 153 154 return -1; 155} 156 157static FH 158_fh_alloc( FHClass clazz ) 159{ 160 int nn; 161 FH f = NULL; 162 163 adb_mutex_lock( &_win32_lock ); 164 165 if (_win32_fh_count < WIN32_MAX_FHS) { 166 f = &_win32_fhs[ _win32_fh_count++ ]; 167 goto Exit; 168 } 169 170 for (nn = 0; nn < WIN32_MAX_FHS; nn++) { 171 if ( _win32_fhs[nn].clazz == NULL) { 172 f = &_win32_fhs[nn]; 173 goto Exit; 174 } 175 } 176 D( "_fh_alloc: no more free file descriptors\n" ); 177Exit: 178 if (f) { 179 f->clazz = clazz; 180 f->used = 1; 181 f->eof = 0; 182 clazz->_fh_init(f); 183 } 184 adb_mutex_unlock( &_win32_lock ); 185 return f; 186} 187 188 189static int 190_fh_close( FH f ) 191{ 192 if ( f->used ) { 193 f->clazz->_fh_close( f ); 194 f->used = 0; 195 f->eof = 0; 196 f->clazz = NULL; 197 } 198 return 0; 199} 200 201/* forward definitions */ 202static const FHClassRec _fh_file_class; 203static const FHClassRec _fh_socket_class; 204 205/**************************************************************************/ 206/**************************************************************************/ 207/***** *****/ 208/***** file-based descriptor handling *****/ 209/***** *****/ 210/**************************************************************************/ 211/**************************************************************************/ 212 213static void 214_fh_file_init( FH f ) 215{ 216 f->fh_handle = INVALID_HANDLE_VALUE; 217} 218 219static int 220_fh_file_close( FH f ) 221{ 222 CloseHandle( f->fh_handle ); 223 f->fh_handle = INVALID_HANDLE_VALUE; 224 return 0; 225} 226 227static int 228_fh_file_read( FH f, void* buf, int len ) 229{ 230 DWORD read_bytes; 231 232 if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) { 233 D( "adb_read: could not read %d bytes from %s\n", len, f->name ); 234 errno = EIO; 235 return -1; 236 } else if (read_bytes < (DWORD)len) { 237 f->eof = 1; 238 } 239 return (int)read_bytes; 240} 241 242static int 243_fh_file_write( FH f, const void* buf, int len ) 244{ 245 DWORD wrote_bytes; 246 247 if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) { 248 D( "adb_file_write: could not write %d bytes from %s\n", len, f->name ); 249 errno = EIO; 250 return -1; 251 } else if (wrote_bytes < (DWORD)len) { 252 f->eof = 1; 253 } 254 return (int)wrote_bytes; 255} 256 257static int 258_fh_file_lseek( FH f, int pos, int origin ) 259{ 260 DWORD method; 261 DWORD result; 262 263 switch (origin) 264 { 265 case SEEK_SET: method = FILE_BEGIN; break; 266 case SEEK_CUR: method = FILE_CURRENT; break; 267 case SEEK_END: method = FILE_END; break; 268 default: 269 errno = EINVAL; 270 return -1; 271 } 272 273 result = SetFilePointer( f->fh_handle, pos, NULL, method ); 274 if (result == INVALID_SET_FILE_POINTER) { 275 errno = EIO; 276 return -1; 277 } else { 278 f->eof = 0; 279 } 280 return (int)result; 281} 282 283static void _fh_file_hook( FH f, int event, EventHook eventhook ); /* forward */ 284 285static const FHClassRec _fh_file_class = 286{ 287 _fh_file_init, 288 _fh_file_close, 289 _fh_file_lseek, 290 _fh_file_read, 291 _fh_file_write, 292 _fh_file_hook 293}; 294 295/**************************************************************************/ 296/**************************************************************************/ 297/***** *****/ 298/***** file-based descriptor handling *****/ 299/***** *****/ 300/**************************************************************************/ 301/**************************************************************************/ 302 303int adb_open(const char* path, int options) 304{ 305 FH f; 306 307 DWORD desiredAccess = 0; 308 DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 309 310 switch (options) { 311 case O_RDONLY: 312 desiredAccess = GENERIC_READ; 313 break; 314 case O_WRONLY: 315 desiredAccess = GENERIC_WRITE; 316 break; 317 case O_RDWR: 318 desiredAccess = GENERIC_READ | GENERIC_WRITE; 319 break; 320 default: 321 D("adb_open: invalid options (0x%0x)\n", options); 322 errno = EINVAL; 323 return -1; 324 } 325 326 f = _fh_alloc( &_fh_file_class ); 327 if ( !f ) { 328 errno = ENOMEM; 329 return -1; 330 } 331 332 f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING, 333 0, NULL ); 334 335 if ( f->fh_handle == INVALID_HANDLE_VALUE ) { 336 _fh_close(f); 337 D( "adb_open: could not open '%s':", path ); 338 switch (GetLastError()) { 339 case ERROR_FILE_NOT_FOUND: 340 D( "file not found\n" ); 341 errno = ENOENT; 342 return -1; 343 344 case ERROR_PATH_NOT_FOUND: 345 D( "path not found\n" ); 346 errno = ENOTDIR; 347 return -1; 348 349 default: 350 D( "unknown error\n" ); 351 errno = ENOENT; 352 return -1; 353 } 354 } 355 356 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path ); 357 D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) ); 358 return _fh_to_int(f); 359} 360 361/* ignore mode on Win32 */ 362int adb_creat(const char* path, int mode) 363{ 364 FH f; 365 366 f = _fh_alloc( &_fh_file_class ); 367 if ( !f ) { 368 errno = ENOMEM; 369 return -1; 370 } 371 372 f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 373 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 374 NULL ); 375 376 if ( f->fh_handle == INVALID_HANDLE_VALUE ) { 377 _fh_close(f); 378 D( "adb_creat: could not open '%s':", path ); 379 switch (GetLastError()) { 380 case ERROR_FILE_NOT_FOUND: 381 D( "file not found\n" ); 382 errno = ENOENT; 383 return -1; 384 385 case ERROR_PATH_NOT_FOUND: 386 D( "path not found\n" ); 387 errno = ENOTDIR; 388 return -1; 389 390 default: 391 D( "unknown error\n" ); 392 errno = ENOENT; 393 return -1; 394 } 395 } 396 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path ); 397 D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) ); 398 return _fh_to_int(f); 399} 400 401 402int adb_read(int fd, void* buf, int len) 403{ 404 FH f = _fh_from_int(fd); 405 406 if (f == NULL) { 407 return -1; 408 } 409 410 return f->clazz->_fh_read( f, buf, len ); 411} 412 413 414int adb_write(int fd, const void* buf, int len) 415{ 416 FH f = _fh_from_int(fd); 417 418 if (f == NULL) { 419 return -1; 420 } 421 422 return f->clazz->_fh_write(f, buf, len); 423} 424 425 426int adb_lseek(int fd, int pos, int where) 427{ 428 FH f = _fh_from_int(fd); 429 430 if (!f) { 431 return -1; 432 } 433 434 return f->clazz->_fh_lseek(f, pos, where); 435} 436 437 438int adb_close(int fd) 439{ 440 FH f = _fh_from_int(fd); 441 442 if (!f) { 443 return -1; 444 } 445 446 D( "adb_close: %s\n", f->name); 447 _fh_close(f); 448 return 0; 449} 450 451/**************************************************************************/ 452/**************************************************************************/ 453/***** *****/ 454/***** socket-based file descriptors *****/ 455/***** *****/ 456/**************************************************************************/ 457/**************************************************************************/ 458 459static void 460_socket_set_errno( void ) 461{ 462 switch (WSAGetLastError()) { 463 case 0: errno = 0; break; 464 case WSAEWOULDBLOCK: errno = EAGAIN; break; 465 case WSAEINTR: errno = EINTR; break; 466 default: 467 D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() ); 468 errno = EINVAL; 469 } 470} 471 472static void 473_fh_socket_init( FH f ) 474{ 475 f->fh_socket = INVALID_SOCKET; 476 f->event = WSACreateEvent(); 477 f->mask = 0; 478} 479 480static int 481_fh_socket_close( FH f ) 482{ 483 /* gently tell any peer that we're closing the socket */ 484 shutdown( f->fh_socket, SD_BOTH ); 485 closesocket( f->fh_socket ); 486 f->fh_socket = INVALID_SOCKET; 487 CloseHandle( f->event ); 488 f->mask = 0; 489 return 0; 490} 491 492static int 493_fh_socket_lseek( FH f, int pos, int origin ) 494{ 495 errno = EPIPE; 496 return -1; 497} 498 499static int 500_fh_socket_read( FH f, void* buf, int len ) 501{ 502 int result = recv( f->fh_socket, buf, len, 0 ); 503 if (result == SOCKET_ERROR) { 504 _socket_set_errno(); 505 result = -1; 506 } 507 return result; 508} 509 510static int 511_fh_socket_write( FH f, const void* buf, int len ) 512{ 513 int result = send( f->fh_socket, buf, len, 0 ); 514 if (result == SOCKET_ERROR) { 515 _socket_set_errno(); 516 result = -1; 517 } 518 return result; 519} 520 521static void _fh_socket_hook( FH f, int event, EventHook hook ); /* forward */ 522 523static const FHClassRec _fh_socket_class = 524{ 525 _fh_socket_init, 526 _fh_socket_close, 527 _fh_socket_lseek, 528 _fh_socket_read, 529 _fh_socket_write, 530 _fh_socket_hook 531}; 532 533/**************************************************************************/ 534/**************************************************************************/ 535/***** *****/ 536/***** replacement for libs/cutils/socket_xxxx.c *****/ 537/***** *****/ 538/**************************************************************************/ 539/**************************************************************************/ 540 541#include <winsock2.h> 542 543static int _winsock_init; 544 545static void 546_cleanup_winsock( void ) 547{ 548 WSACleanup(); 549} 550 551static void 552_init_winsock( void ) 553{ 554 if (!_winsock_init) { 555 WSADATA wsaData; 556 int rc = WSAStartup( MAKEWORD(2,2), &wsaData); 557 if (rc != 0) { 558 fatal( "adb: could not initialize Winsock\n" ); 559 } 560 atexit( _cleanup_winsock ); 561 _winsock_init = 1; 562 } 563} 564 565int socket_loopback_client(int port, int type) 566{ 567 FH f = _fh_alloc( &_fh_socket_class ); 568 struct sockaddr_in addr; 569 SOCKET s; 570 571 if (!f) 572 return -1; 573 574 if (!_winsock_init) 575 _init_winsock(); 576 577 memset(&addr, 0, sizeof(addr)); 578 addr.sin_family = AF_INET; 579 addr.sin_port = htons(port); 580 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 581 582 s = socket(AF_INET, type, 0); 583 if(s == INVALID_SOCKET) { 584 D("socket_loopback_client: could not create socket\n" ); 585 _fh_close(f); 586 return -1; 587 } 588 589 f->fh_socket = s; 590 if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 591 D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port ); 592 _fh_close(f); 593 return -1; 594 } 595 snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); 596 D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); 597 return _fh_to_int(f); 598} 599 600#define LISTEN_BACKLOG 4 601 602int socket_loopback_server(int port, int type) 603{ 604 FH f = _fh_alloc( &_fh_socket_class ); 605 struct sockaddr_in addr; 606 SOCKET s; 607 int n; 608 609 if (!f) { 610 return -1; 611 } 612 613 if (!_winsock_init) 614 _init_winsock(); 615 616 memset(&addr, 0, sizeof(addr)); 617 addr.sin_family = AF_INET; 618 addr.sin_port = htons(port); 619 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 620 621 s = socket(AF_INET, type, 0); 622 if(s == INVALID_SOCKET) return -1; 623 624 f->fh_socket = s; 625 626 n = 1; 627 setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n)); 628 629 if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 630 _fh_close(f); 631 return -1; 632 } 633 if (type == SOCK_STREAM) { 634 int ret; 635 636 ret = listen(s, LISTEN_BACKLOG); 637 if (ret < 0) { 638 _fh_close(f); 639 return -1; 640 } 641 } 642 snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); 643 D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); 644 return _fh_to_int(f); 645} 646 647 648int socket_network_client(const char *host, int port, int type) 649{ 650 FH f = _fh_alloc( &_fh_socket_class ); 651 struct hostent *hp; 652 struct sockaddr_in addr; 653 SOCKET s; 654 655 if (!f) 656 return -1; 657 658 if (!_winsock_init) 659 _init_winsock(); 660 661 hp = gethostbyname(host); 662 if(hp == 0) { 663 _fh_close(f); 664 return -1; 665 } 666 667 memset(&addr, 0, sizeof(addr)); 668 addr.sin_family = hp->h_addrtype; 669 addr.sin_port = htons(port); 670 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); 671 672 s = socket(hp->h_addrtype, type, 0); 673 if(s == INVALID_SOCKET) { 674 _fh_close(f); 675 return -1; 676 } 677 f->fh_socket = s; 678 679 if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 680 _fh_close(f); 681 return -1; 682 } 683 684 snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); 685 D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); 686 return _fh_to_int(f); 687} 688 689 690int socket_inaddr_any_server(int port, int type) 691{ 692 FH f = _fh_alloc( &_fh_socket_class ); 693 struct sockaddr_in addr; 694 SOCKET s; 695 int n; 696 697 if (!f) 698 return -1; 699 700 if (!_winsock_init) 701 _init_winsock(); 702 703 memset(&addr, 0, sizeof(addr)); 704 addr.sin_family = AF_INET; 705 addr.sin_port = htons(port); 706 addr.sin_addr.s_addr = htonl(INADDR_ANY); 707 708 s = socket(AF_INET, type, 0); 709 if(s == INVALID_SOCKET) { 710 _fh_close(f); 711 return -1; 712 } 713 714 f->fh_socket = s; 715 n = 1; 716 setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n)); 717 718 if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 719 _fh_close(f); 720 return -1; 721 } 722 723 if (type == SOCK_STREAM) { 724 int ret; 725 726 ret = listen(s, LISTEN_BACKLOG); 727 if (ret < 0) { 728 _fh_close(f); 729 return -1; 730 } 731 } 732 snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); 733 D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); 734 return _fh_to_int(f); 735} 736 737#undef accept 738int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) 739{ 740 FH serverfh = _fh_from_int(serverfd); 741 FH fh; 742 743 if ( !serverfh || serverfh->clazz != &_fh_socket_class ) { 744 D( "adb_socket_accept: invalid fd %d\n", serverfd ); 745 return -1; 746 } 747 748 fh = _fh_alloc( &_fh_socket_class ); 749 if (!fh) { 750 D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" ); 751 return -1; 752 } 753 754 fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen ); 755 if (fh->fh_socket == INVALID_SOCKET) { 756 _fh_close( fh ); 757 D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() ); 758 return -1; 759 } 760 761 snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name ); 762 D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) ); 763 return _fh_to_int(fh); 764} 765 766 767void disable_tcp_nagle(int fd) 768{ 769 FH fh = _fh_from_int(fd); 770 int on; 771 772 if ( !fh || fh->clazz != &_fh_socket_class ) 773 return; 774 775 setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) ); 776} 777 778/**************************************************************************/ 779/**************************************************************************/ 780/***** *****/ 781/***** emulated socketpairs *****/ 782/***** *****/ 783/**************************************************************************/ 784/**************************************************************************/ 785 786/* we implement socketpairs directly in use space for the following reasons: 787 * - it avoids copying data from/to the Nt kernel 788 * - it allows us to implement fdevent hooks easily and cheaply, something 789 * that is not possible with standard Win32 pipes !! 790 * 791 * basically, we use two circular buffers, each one corresponding to a given 792 * direction. 793 * 794 * each buffer is implemented as two regions: 795 * 796 * region A which is (a_start,a_end) 797 * region B which is (0, b_end) with b_end <= a_start 798 * 799 * an empty buffer has: a_start = a_end = b_end = 0 800 * 801 * a_start is the pointer where we start reading data 802 * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE, 803 * then you start writing at b_end 804 * 805 * the buffer is full when b_end == a_start && a_end == BUFFER_SIZE 806 * 807 * there is room when b_end < a_start || a_end < BUFER_SIZE 808 * 809 * when reading, a_start is incremented, it a_start meets a_end, then 810 * we do: a_start = 0, a_end = b_end, b_end = 0, and keep going on.. 811 */ 812 813#define BIP_BUFFER_SIZE 4096 814 815#if 0 816#include <stdio.h> 817# define BIPD(x) D x 818# define BIPDUMP bip_dump_hex 819 820static void bip_dump_hex( const unsigned char* ptr, size_t len ) 821{ 822 int nn, len2 = len; 823 824 if (len2 > 8) len2 = 8; 825 826 for (nn = 0; nn < len2; nn++) 827 printf("%02x", ptr[nn]); 828 printf(" "); 829 830 for (nn = 0; nn < len2; nn++) { 831 int c = ptr[nn]; 832 if (c < 32 || c > 127) 833 c = '.'; 834 printf("%c", c); 835 } 836 printf("\n"); 837 fflush(stdout); 838} 839 840#else 841# define BIPD(x) do {} while (0) 842# define BIPDUMP(p,l) BIPD(p) 843#endif 844 845typedef struct BipBufferRec_ 846{ 847 int a_start; 848 int a_end; 849 int b_end; 850 int fdin; 851 int fdout; 852 int closed; 853 int can_write; /* boolean */ 854 HANDLE evt_write; /* event signaled when one can write to a buffer */ 855 int can_read; /* boolean */ 856 HANDLE evt_read; /* event signaled when one can read from a buffer */ 857 CRITICAL_SECTION lock; 858 unsigned char buff[ BIP_BUFFER_SIZE ]; 859 860} BipBufferRec, *BipBuffer; 861 862static void 863bip_buffer_init( BipBuffer buffer ) 864{ 865 D( "bit_buffer_init %p\n", buffer ); 866 buffer->a_start = 0; 867 buffer->a_end = 0; 868 buffer->b_end = 0; 869 buffer->can_write = 1; 870 buffer->can_read = 0; 871 buffer->fdin = 0; 872 buffer->fdout = 0; 873 buffer->closed = 0; 874 buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL ); 875 buffer->evt_read = CreateEvent( NULL, TRUE, FALSE, NULL ); 876 InitializeCriticalSection( &buffer->lock ); 877} 878 879static void 880bip_buffer_close( BipBuffer bip ) 881{ 882 bip->closed = 1; 883 884 if (!bip->can_read) { 885 SetEvent( bip->evt_read ); 886 } 887 if (!bip->can_write) { 888 SetEvent( bip->evt_write ); 889 } 890} 891 892static void 893bip_buffer_done( BipBuffer bip ) 894{ 895 BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout )); 896 CloseHandle( bip->evt_read ); 897 CloseHandle( bip->evt_write ); 898 DeleteCriticalSection( &bip->lock ); 899} 900 901static int 902bip_buffer_write( BipBuffer bip, const void* src, int len ) 903{ 904 int avail, count = 0; 905 906 if (len <= 0) 907 return 0; 908 909 BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len )); 910 BIPDUMP( src, len ); 911 912 EnterCriticalSection( &bip->lock ); 913 914 while (!bip->can_write) { 915 int ret; 916 LeaveCriticalSection( &bip->lock ); 917 918 if (bip->closed) { 919 errno = EPIPE; 920 return -1; 921 } 922 /* spinlocking here is probably unfair, but let's live with it */ 923 ret = WaitForSingleObject( bip->evt_write, INFINITE ); 924 if (ret != WAIT_OBJECT_0) { /* buffer probably closed */ 925 D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() ); 926 return 0; 927 } 928 if (bip->closed) { 929 errno = EPIPE; 930 return -1; 931 } 932 EnterCriticalSection( &bip->lock ); 933 } 934 935 BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len )); 936 937 avail = BIP_BUFFER_SIZE - bip->a_end; 938 if (avail > 0) 939 { 940 /* we can append to region A */ 941 if (avail > len) 942 avail = len; 943 944 memcpy( bip->buff + bip->a_end, src, avail ); 945 src += avail; 946 count += avail; 947 len -= avail; 948 949 bip->a_end += avail; 950 if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) { 951 bip->can_write = 0; 952 ResetEvent( bip->evt_write ); 953 goto Exit; 954 } 955 } 956 957 if (len == 0) 958 goto Exit; 959 960 avail = bip->a_start - bip->b_end; 961 assert( avail > 0 ); /* since can_write is TRUE */ 962 963 if (avail > len) 964 avail = len; 965 966 memcpy( bip->buff + bip->b_end, src, avail ); 967 count += avail; 968 bip->b_end += avail; 969 970 if (bip->b_end == bip->a_start) { 971 bip->can_write = 0; 972 ResetEvent( bip->evt_write ); 973 } 974 975Exit: 976 assert( count > 0 ); 977 978 if ( !bip->can_read ) { 979 bip->can_read = 1; 980 SetEvent( bip->evt_read ); 981 } 982 983 BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", 984 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read )); 985 LeaveCriticalSection( &bip->lock ); 986 987 return count; 988 } 989 990static int 991bip_buffer_read( BipBuffer bip, void* dst, int len ) 992{ 993 int avail, count = 0; 994 995 if (len <= 0) 996 return 0; 997 998 BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len )); 999 1000 EnterCriticalSection( &bip->lock ); 1001 while ( !bip->can_read ) 1002 { 1003#if 0 1004 LeaveCriticalSection( &bip->lock ); 1005 errno = EAGAIN; 1006 return -1; 1007#else 1008 int ret; 1009 LeaveCriticalSection( &bip->lock ); 1010 1011 if (bip->closed) { 1012 errno = EPIPE; 1013 return -1; 1014 } 1015 1016 ret = WaitForSingleObject( bip->evt_read, INFINITE ); 1017 if (ret != WAIT_OBJECT_0) { /* probably closed buffer */ 1018 D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError()); 1019 return 0; 1020 } 1021 if (bip->closed) { 1022 errno = EPIPE; 1023 return -1; 1024 } 1025 EnterCriticalSection( &bip->lock ); 1026#endif 1027 } 1028 1029 BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len )); 1030 1031 avail = bip->a_end - bip->a_start; 1032 assert( avail > 0 ); /* since can_read is TRUE */ 1033 1034 if (avail > len) 1035 avail = len; 1036 1037 memcpy( dst, bip->buff + bip->a_start, avail ); 1038 dst += avail; 1039 count += avail; 1040 len -= avail; 1041 1042 bip->a_start += avail; 1043 if (bip->a_start < bip->a_end) 1044 goto Exit; 1045 1046 bip->a_start = 0; 1047 bip->a_end = bip->b_end; 1048 bip->b_end = 0; 1049 1050 avail = bip->a_end; 1051 if (avail > 0) { 1052 if (avail > len) 1053 avail = len; 1054 memcpy( dst, bip->buff, avail ); 1055 count += avail; 1056 bip->a_start += avail; 1057 1058 if ( bip->a_start < bip->a_end ) 1059 goto Exit; 1060 1061 bip->a_start = bip->a_end = 0; 1062 } 1063 1064 bip->can_read = 0; 1065 ResetEvent( bip->evt_read ); 1066 1067Exit: 1068 assert( count > 0 ); 1069 1070 if (!bip->can_write ) { 1071 bip->can_write = 1; 1072 SetEvent( bip->evt_write ); 1073 } 1074 1075 BIPDUMP( (const unsigned char*)dst - count, count ); 1076 BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", 1077 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read )); 1078 LeaveCriticalSection( &bip->lock ); 1079 1080 return count; 1081} 1082 1083typedef struct SocketPairRec_ 1084{ 1085 BipBufferRec a2b_bip; 1086 BipBufferRec b2a_bip; 1087 FH a_fd; 1088 int used; 1089 1090} SocketPairRec; 1091 1092void _fh_socketpair_init( FH f ) 1093{ 1094 f->fh_pair = NULL; 1095} 1096 1097static int 1098_fh_socketpair_close( FH f ) 1099{ 1100 if ( f->fh_pair ) { 1101 SocketPair pair = f->fh_pair; 1102 1103 if ( f == pair->a_fd ) { 1104 pair->a_fd = NULL; 1105 } 1106 1107 bip_buffer_close( &pair->b2a_bip ); 1108 bip_buffer_close( &pair->a2b_bip ); 1109 1110 if ( --pair->used == 0 ) { 1111 bip_buffer_done( &pair->b2a_bip ); 1112 bip_buffer_done( &pair->a2b_bip ); 1113 free( pair ); 1114 } 1115 f->fh_pair = NULL; 1116 } 1117 return 0; 1118} 1119 1120static int 1121_fh_socketpair_lseek( FH f, int pos, int origin ) 1122{ 1123 errno = ESPIPE; 1124 return -1; 1125} 1126 1127static int 1128_fh_socketpair_read( FH f, void* buf, int len ) 1129{ 1130 SocketPair pair = f->fh_pair; 1131 BipBuffer bip; 1132 1133 if (!pair) 1134 return -1; 1135 1136 if ( f == pair->a_fd ) 1137 bip = &pair->b2a_bip; 1138 else 1139 bip = &pair->a2b_bip; 1140 1141 return bip_buffer_read( bip, buf, len ); 1142} 1143 1144static int 1145_fh_socketpair_write( FH f, const void* buf, int len ) 1146{ 1147 SocketPair pair = f->fh_pair; 1148 BipBuffer bip; 1149 1150 if (!pair) 1151 return -1; 1152 1153 if ( f == pair->a_fd ) 1154 bip = &pair->a2b_bip; 1155 else 1156 bip = &pair->b2a_bip; 1157 1158 return bip_buffer_write( bip, buf, len ); 1159} 1160 1161 1162static void _fh_socketpair_hook( FH f, int event, EventHook hook ); /* forward */ 1163 1164static const FHClassRec _fh_socketpair_class = 1165{ 1166 _fh_socketpair_init, 1167 _fh_socketpair_close, 1168 _fh_socketpair_lseek, 1169 _fh_socketpair_read, 1170 _fh_socketpair_write, 1171 _fh_socketpair_hook 1172}; 1173 1174 1175int adb_socketpair( int sv[2] ) 1176{ 1177 FH fa, fb; 1178 SocketPair pair; 1179 1180 fa = _fh_alloc( &_fh_socketpair_class ); 1181 fb = _fh_alloc( &_fh_socketpair_class ); 1182 1183 if (!fa || !fb) 1184 goto Fail; 1185 1186 pair = malloc( sizeof(*pair) ); 1187 if (pair == NULL) { 1188 D("adb_socketpair: not enough memory to allocate pipes\n" ); 1189 goto Fail; 1190 } 1191 1192 bip_buffer_init( &pair->a2b_bip ); 1193 bip_buffer_init( &pair->b2a_bip ); 1194 1195 fa->fh_pair = pair; 1196 fb->fh_pair = pair; 1197 pair->used = 2; 1198 pair->a_fd = fa; 1199 1200 sv[0] = _fh_to_int(fa); 1201 sv[1] = _fh_to_int(fb); 1202 1203 pair->a2b_bip.fdin = sv[0]; 1204 pair->a2b_bip.fdout = sv[1]; 1205 pair->b2a_bip.fdin = sv[1]; 1206 pair->b2a_bip.fdout = sv[0]; 1207 1208 snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] ); 1209 snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] ); 1210 D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] ); 1211 return 0; 1212 1213Fail: 1214 _fh_close(fb); 1215 _fh_close(fa); 1216 return -1; 1217} 1218 1219/**************************************************************************/ 1220/**************************************************************************/ 1221/***** *****/ 1222/***** fdevents emulation *****/ 1223/***** *****/ 1224/***** this is a very simple implementation, we rely on the fact *****/ 1225/***** that ADB doesn't use FDE_ERROR. *****/ 1226/***** *****/ 1227/**************************************************************************/ 1228/**************************************************************************/ 1229 1230#define FATAL(x...) fatal(__FUNCTION__, x) 1231 1232#if DEBUG 1233static void dump_fde(fdevent *fde, const char *info) 1234{ 1235 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, 1236 fde->state & FDE_READ ? 'R' : ' ', 1237 fde->state & FDE_WRITE ? 'W' : ' ', 1238 fde->state & FDE_ERROR ? 'E' : ' ', 1239 info); 1240} 1241#else 1242#define dump_fde(fde, info) do { } while(0) 1243#endif 1244 1245#define FDE_EVENTMASK 0x00ff 1246#define FDE_STATEMASK 0xff00 1247 1248#define FDE_ACTIVE 0x0100 1249#define FDE_PENDING 0x0200 1250#define FDE_CREATED 0x0400 1251 1252static void fdevent_plist_enqueue(fdevent *node); 1253static void fdevent_plist_remove(fdevent *node); 1254static fdevent *fdevent_plist_dequeue(void); 1255 1256static fdevent list_pending = { 1257 .next = &list_pending, 1258 .prev = &list_pending, 1259}; 1260 1261static fdevent **fd_table = 0; 1262static int fd_table_max = 0; 1263 1264typedef struct EventLooperRec_* EventLooper; 1265 1266typedef struct EventHookRec_ 1267{ 1268 EventHook next; 1269 FH fh; 1270 HANDLE h; 1271 int wanted; /* wanted event flags */ 1272 int ready; /* ready event flags */ 1273 void* aux; 1274 void (*prepare)( EventHook hook ); 1275 int (*start) ( EventHook hook ); 1276 void (*stop) ( EventHook hook ); 1277 int (*check) ( EventHook hook ); 1278 int (*peek) ( EventHook hook ); 1279} EventHookRec; 1280 1281static EventHook _free_hooks; 1282 1283static EventHook 1284event_hook_alloc( FH fh ) 1285{ 1286 EventHook hook = _free_hooks; 1287 if (hook != NULL) 1288 _free_hooks = hook->next; 1289 else { 1290 hook = malloc( sizeof(*hook) ); 1291 if (hook == NULL) 1292 fatal( "could not allocate event hook\n" ); 1293 } 1294 hook->next = NULL; 1295 hook->fh = fh; 1296 hook->wanted = 0; 1297 hook->ready = 0; 1298 hook->h = INVALID_HANDLE_VALUE; 1299 hook->aux = NULL; 1300 1301 hook->prepare = NULL; 1302 hook->start = NULL; 1303 hook->stop = NULL; 1304 hook->check = NULL; 1305 hook->peek = NULL; 1306 1307 return hook; 1308} 1309 1310static void 1311event_hook_free( EventHook hook ) 1312{ 1313 hook->fh = NULL; 1314 hook->wanted = 0; 1315 hook->ready = 0; 1316 hook->next = _free_hooks; 1317 _free_hooks = hook; 1318} 1319 1320 1321static void 1322event_hook_signal( EventHook hook ) 1323{ 1324 FH f = hook->fh; 1325 int fd = _fh_to_int(f); 1326 fdevent* fde = fd_table[ fd - WIN32_FH_BASE ]; 1327 1328 if (fde != NULL && fde->fd == fd) { 1329 if ((fde->state & FDE_PENDING) == 0) { 1330 fde->state |= FDE_PENDING; 1331 fdevent_plist_enqueue( fde ); 1332 } 1333 fde->events |= hook->wanted; 1334 } 1335} 1336 1337 1338#define MAX_LOOPER_HANDLES WIN32_MAX_FHS 1339 1340typedef struct EventLooperRec_ 1341{ 1342 EventHook hooks; 1343 HANDLE htab[ MAX_LOOPER_HANDLES ]; 1344 int htab_count; 1345 1346} EventLooperRec; 1347 1348static EventHook* 1349event_looper_find_p( EventLooper looper, FH fh ) 1350{ 1351 EventHook *pnode = &looper->hooks; 1352 EventHook node = *pnode; 1353 for (;;) { 1354 if ( node == NULL || node->fh == fh ) 1355 break; 1356 pnode = &node->next; 1357 node = *pnode; 1358 } 1359 return pnode; 1360} 1361 1362static void 1363event_looper_hook( EventLooper looper, int fd, int events ) 1364{ 1365 FH f = _fh_from_int(fd); 1366 EventHook *pnode; 1367 EventHook node; 1368 1369 if (f == NULL) /* invalid arg */ { 1370 D("event_looper_hook: invalid fd=%d\n", fd); 1371 return; 1372 } 1373 1374 pnode = event_looper_find_p( looper, f ); 1375 node = *pnode; 1376 if ( node == NULL ) { 1377 node = event_hook_alloc( f ); 1378 node->next = *pnode; 1379 *pnode = node; 1380 } 1381 1382 if ( (node->wanted & events) != events ) { 1383 /* this should update start/stop/check/peek */ 1384 D("event_looper_hook: call hook for %d (new=%x, old=%x)\n", 1385 fd, node->wanted, events); 1386 f->clazz->_fh_hook( f, events & ~node->wanted, node ); 1387 node->wanted |= events; 1388 } else { 1389 D("event_looper_hook: ignoring events %x for %d wanted=%x)\n", 1390 events, fd, node->wanted); 1391 } 1392} 1393 1394static void 1395event_looper_unhook( EventLooper looper, int fd, int events ) 1396{ 1397 FH fh = _fh_from_int(fd); 1398 EventHook *pnode = event_looper_find_p( looper, fh ); 1399 EventHook node = *pnode; 1400 1401 if (node != NULL) { 1402 int events2 = events & node->wanted; 1403 if ( events2 == 0 ) { 1404 D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd ); 1405 return; 1406 } 1407 node->wanted &= ~events2; 1408 if (!node->wanted) { 1409 *pnode = node->next; 1410 event_hook_free( node ); 1411 } 1412 } 1413} 1414 1415static EventLooperRec win32_looper; 1416 1417static void fdevent_init(void) 1418{ 1419 win32_looper.htab_count = 0; 1420 win32_looper.hooks = NULL; 1421} 1422 1423static void fdevent_connect(fdevent *fde) 1424{ 1425 EventLooper looper = &win32_looper; 1426 int events = fde->state & FDE_EVENTMASK; 1427 1428 if (events != 0) 1429 event_looper_hook( looper, fde->fd, events ); 1430} 1431 1432static void fdevent_disconnect(fdevent *fde) 1433{ 1434 EventLooper looper = &win32_looper; 1435 int events = fde->state & FDE_EVENTMASK; 1436 1437 if (events != 0) 1438 event_looper_unhook( looper, fde->fd, events ); 1439} 1440 1441static void fdevent_update(fdevent *fde, unsigned events) 1442{ 1443 EventLooper looper = &win32_looper; 1444 unsigned events0 = fde->state & FDE_EVENTMASK; 1445 1446 if (events != events0) { 1447 int removes = events0 & ~events; 1448 int adds = events & ~events0; 1449 if (removes) { 1450 D("fdevent_update: remove %x from %d\n", removes, fde->fd); 1451 event_looper_unhook( looper, fde->fd, removes ); 1452 } 1453 if (adds) { 1454 D("fdevent_update: add %x to %d\n", adds, fde->fd); 1455 event_looper_hook ( looper, fde->fd, adds ); 1456 } 1457 } 1458} 1459 1460static void fdevent_process() 1461{ 1462 EventLooper looper = &win32_looper; 1463 EventHook hook; 1464 int gotone = 0; 1465 1466 /* if we have at least one ready hook, execute it/them */ 1467 for (hook = looper->hooks; hook; hook = hook->next) { 1468 hook->ready = 0; 1469 if (hook->prepare) { 1470 hook->prepare(hook); 1471 if (hook->ready != 0) { 1472 event_hook_signal( hook ); 1473 gotone = 1; 1474 } 1475 } 1476 } 1477 1478 /* nothing's ready yet, so wait for something to happen */ 1479 if (!gotone) 1480 { 1481 looper->htab_count = 0; 1482 1483 for (hook = looper->hooks; hook; hook = hook->next) 1484 { 1485 if (hook->start && !hook->start(hook)) { 1486 D( "fdevent_process: error when starting a hook\n" ); 1487 return; 1488 } 1489 if (hook->h != INVALID_HANDLE_VALUE) { 1490 int nn; 1491 1492 for (nn = 0; nn < looper->htab_count; nn++) 1493 { 1494 if ( looper->htab[nn] == hook->h ) 1495 goto DontAdd; 1496 } 1497 looper->htab[ looper->htab_count++ ] = hook->h; 1498 DontAdd: 1499 ; 1500 } 1501 } 1502 1503 if (looper->htab_count == 0) { 1504 D( "fdevent_process: nothing to wait for !!\n" ); 1505 return; 1506 } 1507 1508 do 1509 { 1510 int wait_ret; 1511 1512 D( "adb_win32: waiting for %d events\n", looper->htab_count ); 1513 if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) { 1514 D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS, aborting!\n", looper->htab_count); 1515 abort(); 1516 } 1517 wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE ); 1518 if (wait_ret == (int)WAIT_FAILED) { 1519 D( "adb_win32: wait failed, error %ld\n", GetLastError() ); 1520 } else { 1521 D( "adb_win32: got one (index %d)\n", wait_ret ); 1522 1523 /* according to Cygwin, some objects like consoles wake up on "inappropriate" events 1524 * like mouse movements. we need to filter these with the "check" function 1525 */ 1526 if ((unsigned)wait_ret < (unsigned)looper->htab_count) 1527 { 1528 for (hook = looper->hooks; hook; hook = hook->next) 1529 { 1530 if ( looper->htab[wait_ret] == hook->h && 1531 (!hook->check || hook->check(hook)) ) 1532 { 1533 D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready ); 1534 event_hook_signal( hook ); 1535 gotone = 1; 1536 break; 1537 } 1538 } 1539 } 1540 } 1541 } 1542 while (!gotone); 1543 1544 for (hook = looper->hooks; hook; hook = hook->next) { 1545 if (hook->stop) 1546 hook->stop( hook ); 1547 } 1548 } 1549 1550 for (hook = looper->hooks; hook; hook = hook->next) { 1551 if (hook->peek && hook->peek(hook)) 1552 event_hook_signal( hook ); 1553 } 1554} 1555 1556 1557static void fdevent_register(fdevent *fde) 1558{ 1559 int fd = fde->fd - WIN32_FH_BASE; 1560 1561 if(fd < 0) { 1562 FATAL("bogus negative fd (%d)\n", fde->fd); 1563 } 1564 1565 if(fd >= fd_table_max) { 1566 int oldmax = fd_table_max; 1567 if(fde->fd > 32000) { 1568 FATAL("bogus huuuuge fd (%d)\n", fde->fd); 1569 } 1570 if(fd_table_max == 0) { 1571 fdevent_init(); 1572 fd_table_max = 256; 1573 } 1574 while(fd_table_max <= fd) { 1575 fd_table_max *= 2; 1576 } 1577 fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max); 1578 if(fd_table == 0) { 1579 FATAL("could not expand fd_table to %d entries\n", fd_table_max); 1580 } 1581 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); 1582 } 1583 1584 fd_table[fd] = fde; 1585} 1586 1587static void fdevent_unregister(fdevent *fde) 1588{ 1589 int fd = fde->fd - WIN32_FH_BASE; 1590 1591 if((fd < 0) || (fd >= fd_table_max)) { 1592 FATAL("fd out of range (%d)\n", fde->fd); 1593 } 1594 1595 if(fd_table[fd] != fde) { 1596 FATAL("fd_table out of sync"); 1597 } 1598 1599 fd_table[fd] = 0; 1600 1601 if(!(fde->state & FDE_DONT_CLOSE)) { 1602 dump_fde(fde, "close"); 1603 adb_close(fde->fd); 1604 } 1605} 1606 1607static void fdevent_plist_enqueue(fdevent *node) 1608{ 1609 fdevent *list = &list_pending; 1610 1611 node->next = list; 1612 node->prev = list->prev; 1613 node->prev->next = node; 1614 list->prev = node; 1615} 1616 1617static void fdevent_plist_remove(fdevent *node) 1618{ 1619 node->prev->next = node->next; 1620 node->next->prev = node->prev; 1621 node->next = 0; 1622 node->prev = 0; 1623} 1624 1625static fdevent *fdevent_plist_dequeue(void) 1626{ 1627 fdevent *list = &list_pending; 1628 fdevent *node = list->next; 1629 1630 if(node == list) return 0; 1631 1632 list->next = node->next; 1633 list->next->prev = list; 1634 node->next = 0; 1635 node->prev = 0; 1636 1637 return node; 1638} 1639 1640fdevent *fdevent_create(int fd, fd_func func, void *arg) 1641{ 1642 fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); 1643 if(fde == 0) return 0; 1644 fdevent_install(fde, fd, func, arg); 1645 fde->state |= FDE_CREATED; 1646 return fde; 1647} 1648 1649void fdevent_destroy(fdevent *fde) 1650{ 1651 if(fde == 0) return; 1652 if(!(fde->state & FDE_CREATED)) { 1653 FATAL("fde %p not created by fdevent_create()\n", fde); 1654 } 1655 fdevent_remove(fde); 1656} 1657 1658void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 1659{ 1660 memset(fde, 0, sizeof(fdevent)); 1661 fde->state = FDE_ACTIVE; 1662 fde->fd = fd; 1663 fde->func = func; 1664 fde->arg = arg; 1665 1666 fdevent_register(fde); 1667 dump_fde(fde, "connect"); 1668 fdevent_connect(fde); 1669 fde->state |= FDE_ACTIVE; 1670} 1671 1672void fdevent_remove(fdevent *fde) 1673{ 1674 if(fde->state & FDE_PENDING) { 1675 fdevent_plist_remove(fde); 1676 } 1677 1678 if(fde->state & FDE_ACTIVE) { 1679 fdevent_disconnect(fde); 1680 dump_fde(fde, "disconnect"); 1681 fdevent_unregister(fde); 1682 } 1683 1684 fde->state = 0; 1685 fde->events = 0; 1686} 1687 1688 1689void fdevent_set(fdevent *fde, unsigned events) 1690{ 1691 events &= FDE_EVENTMASK; 1692 1693 if((fde->state & FDE_EVENTMASK) == (int)events) return; 1694 1695 if(fde->state & FDE_ACTIVE) { 1696 fdevent_update(fde, events); 1697 dump_fde(fde, "update"); 1698 } 1699 1700 fde->state = (fde->state & FDE_STATEMASK) | events; 1701 1702 if(fde->state & FDE_PENDING) { 1703 /* if we're pending, make sure 1704 ** we don't signal an event that 1705 ** is no longer wanted. 1706 */ 1707 fde->events &= (~events); 1708 if(fde->events == 0) { 1709 fdevent_plist_remove(fde); 1710 fde->state &= (~FDE_PENDING); 1711 } 1712 } 1713} 1714 1715void fdevent_add(fdevent *fde, unsigned events) 1716{ 1717 fdevent_set( 1718 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); 1719} 1720 1721void fdevent_del(fdevent *fde, unsigned events) 1722{ 1723 fdevent_set( 1724 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); 1725} 1726 1727void fdevent_loop() 1728{ 1729 fdevent *fde; 1730 1731 for(;;) { 1732#if DEBUG 1733 fprintf(stderr,"--- ---- waiting for events\n"); 1734#endif 1735 fdevent_process(); 1736 1737 while((fde = fdevent_plist_dequeue())) { 1738 unsigned events = fde->events; 1739 fde->events = 0; 1740 fde->state &= (~FDE_PENDING); 1741 dump_fde(fde, "callback"); 1742 fde->func(fde->fd, events, fde->arg); 1743 } 1744 } 1745} 1746 1747/** FILE EVENT HOOKS 1748 **/ 1749 1750static void _event_file_prepare( EventHook hook ) 1751{ 1752 if (hook->wanted & (FDE_READ|FDE_WRITE)) { 1753 /* we can always read/write */ 1754 hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE); 1755 } 1756} 1757 1758static int _event_file_peek( EventHook hook ) 1759{ 1760 return (hook->wanted & (FDE_READ|FDE_WRITE)); 1761} 1762 1763static void _fh_file_hook( FH f, int events, EventHook hook ) 1764{ 1765 hook->h = f->fh_handle; 1766 hook->prepare = _event_file_prepare; 1767 hook->peek = _event_file_peek; 1768} 1769 1770/** SOCKET EVENT HOOKS 1771 **/ 1772 1773static void _event_socket_verify( EventHook hook, WSANETWORKEVENTS* evts ) 1774{ 1775 if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) { 1776 if (hook->wanted & FDE_READ) 1777 hook->ready |= FDE_READ; 1778 if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR) 1779 hook->ready |= FDE_ERROR; 1780 } 1781 if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) { 1782 if (hook->wanted & FDE_WRITE) 1783 hook->ready |= FDE_WRITE; 1784 if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR) 1785 hook->ready |= FDE_ERROR; 1786 } 1787 if ( evts->lNetworkEvents & FD_OOB ) { 1788 if (hook->wanted & FDE_ERROR) 1789 hook->ready |= FDE_ERROR; 1790 } 1791} 1792 1793static void _event_socket_prepare( EventHook hook ) 1794{ 1795 WSANETWORKEVENTS evts; 1796 1797 /* look if some of the events we want already happened ? */ 1798 if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts )) 1799 _event_socket_verify( hook, &evts ); 1800} 1801 1802static int _socket_wanted_to_flags( int wanted ) 1803{ 1804 int flags = 0; 1805 if (wanted & FDE_READ) 1806 flags |= FD_READ | FD_ACCEPT | FD_CLOSE; 1807 1808 if (wanted & FDE_WRITE) 1809 flags |= FD_WRITE | FD_CONNECT | FD_CLOSE; 1810 1811 if (wanted & FDE_ERROR) 1812 flags |= FD_OOB; 1813 1814 return flags; 1815} 1816 1817static int _event_socket_start( EventHook hook ) 1818{ 1819 /* create an event which we're going to wait for */ 1820 FH fh = hook->fh; 1821 long flags = _socket_wanted_to_flags( hook->wanted ); 1822 1823 hook->h = fh->event; 1824 if (hook->h == INVALID_HANDLE_VALUE) { 1825 D( "_event_socket_start: no event for %s\n", fh->name ); 1826 return 0; 1827 } 1828 1829 if ( flags != fh->mask ) { 1830 D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags ); 1831 if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) { 1832 D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() ); 1833 CloseHandle( hook->h ); 1834 hook->h = INVALID_HANDLE_VALUE; 1835 exit(1); 1836 return 0; 1837 } 1838 fh->mask = flags; 1839 } 1840 return 1; 1841} 1842 1843static void _event_socket_stop( EventHook hook ) 1844{ 1845 hook->h = INVALID_HANDLE_VALUE; 1846} 1847 1848static int _event_socket_check( EventHook hook ) 1849{ 1850 int result = 0; 1851 FH fh = hook->fh; 1852 WSANETWORKEVENTS evts; 1853 1854 if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) { 1855 _event_socket_verify( hook, &evts ); 1856 result = (hook->ready != 0); 1857 if (result) { 1858 ResetEvent( hook->h ); 1859 } 1860 } 1861 D( "_event_socket_check %s returns %d\n", fh->name, result ); 1862 return result; 1863} 1864 1865static int _event_socket_peek( EventHook hook ) 1866{ 1867 WSANETWORKEVENTS evts; 1868 FH fh = hook->fh; 1869 1870 /* look if some of the events we want already happened ? */ 1871 if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) { 1872 _event_socket_verify( hook, &evts ); 1873 if (hook->ready) 1874 ResetEvent( hook->h ); 1875 } 1876 1877 return hook->ready != 0; 1878} 1879 1880 1881 1882static void _fh_socket_hook( FH f, int events, EventHook hook ) 1883{ 1884 hook->prepare = _event_socket_prepare; 1885 hook->start = _event_socket_start; 1886 hook->stop = _event_socket_stop; 1887 hook->check = _event_socket_check; 1888 hook->peek = _event_socket_peek; 1889 1890 _event_socket_start( hook ); 1891} 1892 1893/** SOCKETPAIR EVENT HOOKS 1894 **/ 1895 1896static void _event_socketpair_prepare( EventHook hook ) 1897{ 1898 FH fh = hook->fh; 1899 SocketPair pair = fh->fh_pair; 1900 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip; 1901 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip; 1902 1903 if (hook->wanted & FDE_READ && rbip->can_read) 1904 hook->ready |= FDE_READ; 1905 1906 if (hook->wanted & FDE_WRITE && wbip->can_write) 1907 hook->ready |= FDE_WRITE; 1908 } 1909 1910 static int _event_socketpair_start( EventHook hook ) 1911 { 1912 FH fh = hook->fh; 1913 SocketPair pair = fh->fh_pair; 1914 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip; 1915 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip; 1916 1917 if (hook->wanted == FDE_READ) 1918 hook->h = rbip->evt_read; 1919 1920 else if (hook->wanted == FDE_WRITE) 1921 hook->h = wbip->evt_write; 1922 1923 else { 1924 D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" ); 1925 return 0; 1926 } 1927 D( "_event_socketpair_start: hook %s for %x wanted=%x\n", 1928 hook->fh->name, _fh_to_int(fh), hook->wanted); 1929 return 1; 1930} 1931 1932static int _event_socketpair_peek( EventHook hook ) 1933{ 1934 _event_socketpair_prepare( hook ); 1935 return hook->ready != 0; 1936} 1937 1938static void _fh_socketpair_hook( FH fh, int events, EventHook hook ) 1939{ 1940 hook->prepare = _event_socketpair_prepare; 1941 hook->start = _event_socketpair_start; 1942 hook->peek = _event_socketpair_peek; 1943} 1944 1945 1946void 1947adb_sysdeps_init( void ) 1948{ 1949#define ADB_MUTEX(x) InitializeCriticalSection( & x ); 1950#include "mutex_list.h" 1951 InitializeCriticalSection( &_win32_lock ); 1952} 1953 1954