1/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c 2** 3** Copyright 2006, Brian Swetland <swetland@frotz.net> 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <sys/ioctl.h> 19 20#include <stdlib.h> 21#include <stdio.h> 22#include <string.h> 23#include <unistd.h> 24#include <errno.h> 25 26#include <fcntl.h> 27 28#include <stdarg.h> 29#include <stddef.h> 30 31#include "fdevent.h" 32#include "transport.h" 33#include "sysdeps.h" 34 35 36/* !!! Do not enable DEBUG for the adb that will run as the server: 37** both stdout and stderr are used to communicate between the client 38** and server. Any extra output will cause failures. 39*/ 40#define DEBUG 0 /* non-0 will break adb server */ 41 42// This socket is used when a subproc shell service exists. 43// It wakes up the fdevent_loop() and cause the correct handling 44// of the shell's pseudo-tty master. I.e. force close it. 45int SHELL_EXIT_NOTIFY_FD = -1; 46 47static void fatal(const char *fn, const char *fmt, ...) 48{ 49 va_list ap; 50 va_start(ap, fmt); 51 fprintf(stderr, "%s:", fn); 52 vfprintf(stderr, fmt, ap); 53 va_end(ap); 54 abort(); 55} 56 57#define FATAL(x...) fatal(__FUNCTION__, x) 58 59#if DEBUG 60#define D(...) \ 61 do { \ 62 adb_mutex_lock(&D_lock); \ 63 int save_errno = errno; \ 64 fprintf(stderr, "%s::%s():", __FILE__, __FUNCTION__); \ 65 errno = save_errno; \ 66 fprintf(stderr, __VA_ARGS__); \ 67 adb_mutex_unlock(&D_lock); \ 68 errno = save_errno; \ 69 } while(0) 70static void dump_fde(fdevent *fde, const char *info) 71{ 72 adb_mutex_lock(&D_lock); 73 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, 74 fde->state & FDE_READ ? 'R' : ' ', 75 fde->state & FDE_WRITE ? 'W' : ' ', 76 fde->state & FDE_ERROR ? 'E' : ' ', 77 info); 78 adb_mutex_unlock(&D_lock); 79} 80#else 81#define D(...) ((void)0) 82#define dump_fde(fde, info) do { } while(0) 83#endif 84 85#define FDE_EVENTMASK 0x00ff 86#define FDE_STATEMASK 0xff00 87 88#define FDE_ACTIVE 0x0100 89#define FDE_PENDING 0x0200 90#define FDE_CREATED 0x0400 91 92static void fdevent_plist_enqueue(fdevent *node); 93static void fdevent_plist_remove(fdevent *node); 94static fdevent *fdevent_plist_dequeue(void); 95static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata); 96 97static fdevent list_pending = { 98 .next = &list_pending, 99 .prev = &list_pending, 100}; 101 102static fdevent **fd_table = 0; 103static int fd_table_max = 0; 104 105#ifdef CRAPTASTIC 106//HAVE_EPOLL 107 108#include <sys/epoll.h> 109 110static int epoll_fd = -1; 111 112static void fdevent_init() 113{ 114 /* XXX: what's a good size for the passed in hint? */ 115 epoll_fd = epoll_create(256); 116 117 if(epoll_fd < 0) { 118 perror("epoll_create() failed"); 119 exit(1); 120 } 121 122 /* mark for close-on-exec */ 123 fcntl(epoll_fd, F_SETFD, FD_CLOEXEC); 124} 125 126static void fdevent_connect(fdevent *fde) 127{ 128 struct epoll_event ev; 129 130 memset(&ev, 0, sizeof(ev)); 131 ev.events = 0; 132 ev.data.ptr = fde; 133 134#if 0 135 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 136 perror("epoll_ctl() failed\n"); 137 exit(1); 138 } 139#endif 140} 141 142static void fdevent_disconnect(fdevent *fde) 143{ 144 struct epoll_event ev; 145 146 memset(&ev, 0, sizeof(ev)); 147 ev.events = 0; 148 ev.data.ptr = fde; 149 150 /* technically we only need to delete if we 151 ** were actively monitoring events, but let's 152 ** be aggressive and do it anyway, just in case 153 ** something's out of sync 154 */ 155 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev); 156} 157 158static void fdevent_update(fdevent *fde, unsigned events) 159{ 160 struct epoll_event ev; 161 int active; 162 163 active = (fde->state & FDE_EVENTMASK) != 0; 164 165 memset(&ev, 0, sizeof(ev)); 166 ev.events = 0; 167 ev.data.ptr = fde; 168 169 if(events & FDE_READ) ev.events |= EPOLLIN; 170 if(events & FDE_WRITE) ev.events |= EPOLLOUT; 171 if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP); 172 173 fde->state = (fde->state & FDE_STATEMASK) | events; 174 175 if(active) { 176 /* we're already active. if we're changing to *no* 177 ** events being monitored, we need to delete, otherwise 178 ** we need to just modify 179 */ 180 if(ev.events) { 181 if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) { 182 perror("epoll_ctl() failed\n"); 183 exit(1); 184 } 185 } else { 186 if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) { 187 perror("epoll_ctl() failed\n"); 188 exit(1); 189 } 190 } 191 } else { 192 /* we're not active. if we're watching events, we need 193 ** to add, otherwise we can just do nothing 194 */ 195 if(ev.events) { 196 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 197 perror("epoll_ctl() failed\n"); 198 exit(1); 199 } 200 } 201 } 202} 203 204static void fdevent_process() 205{ 206 struct epoll_event events[256]; 207 fdevent *fde; 208 int i, n; 209 210 n = epoll_wait(epoll_fd, events, 256, -1); 211 212 if(n < 0) { 213 if(errno == EINTR) return; 214 perror("epoll_wait"); 215 exit(1); 216 } 217 218 for(i = 0; i < n; i++) { 219 struct epoll_event *ev = events + i; 220 fde = ev->data.ptr; 221 222 if(ev->events & EPOLLIN) { 223 fde->events |= FDE_READ; 224 } 225 if(ev->events & EPOLLOUT) { 226 fde->events |= FDE_WRITE; 227 } 228 if(ev->events & (EPOLLERR | EPOLLHUP)) { 229 fde->events |= FDE_ERROR; 230 } 231 if(fde->events) { 232 if(fde->state & FDE_PENDING) continue; 233 fde->state |= FDE_PENDING; 234 fdevent_plist_enqueue(fde); 235 } 236 } 237} 238 239#else /* USE_SELECT */ 240 241#ifdef HAVE_WINSOCK 242#include <winsock2.h> 243#else 244#include <sys/select.h> 245#endif 246 247static fd_set read_fds; 248static fd_set write_fds; 249static fd_set error_fds; 250 251static int select_n = 0; 252 253static void fdevent_init(void) 254{ 255 FD_ZERO(&read_fds); 256 FD_ZERO(&write_fds); 257 FD_ZERO(&error_fds); 258} 259 260static void fdevent_connect(fdevent *fde) 261{ 262 if(fde->fd >= select_n) { 263 select_n = fde->fd + 1; 264 } 265} 266 267static void fdevent_disconnect(fdevent *fde) 268{ 269 int i, n; 270 271 FD_CLR(fde->fd, &read_fds); 272 FD_CLR(fde->fd, &write_fds); 273 FD_CLR(fde->fd, &error_fds); 274 275 for(n = 0, i = 0; i < select_n; i++) { 276 if(fd_table[i] != 0) n = i; 277 } 278 select_n = n + 1; 279} 280 281static void fdevent_update(fdevent *fde, unsigned events) 282{ 283 if(events & FDE_READ) { 284 FD_SET(fde->fd, &read_fds); 285 } else { 286 FD_CLR(fde->fd, &read_fds); 287 } 288 if(events & FDE_WRITE) { 289 FD_SET(fde->fd, &write_fds); 290 } else { 291 FD_CLR(fde->fd, &write_fds); 292 } 293 if(events & FDE_ERROR) { 294 FD_SET(fde->fd, &error_fds); 295 } else { 296 FD_CLR(fde->fd, &error_fds); 297 } 298 299 fde->state = (fde->state & FDE_STATEMASK) | events; 300} 301 302/* Looks at fd_table[] for bad FDs and sets bit in fds. 303** Returns the number of bad FDs. 304*/ 305static int fdevent_fd_check(fd_set *fds) 306{ 307 int i, n = 0; 308 fdevent *fde; 309 310 for(i = 0; i < select_n; i++) { 311 fde = fd_table[i]; 312 if(fde == 0) continue; 313 if(fcntl(i, F_GETFL, NULL) < 0) { 314 FD_SET(i, fds); 315 n++; 316 // fde->state |= FDE_DONT_CLOSE; 317 318 } 319 } 320 return n; 321} 322 323#if !DEBUG 324static inline void dump_all_fds(const char *extra_msg) {} 325#else 326static void dump_all_fds(const char *extra_msg) 327{ 328int i; 329 fdevent *fde; 330 // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank 331 char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff; 332 size_t max_chars = FD_SETSIZE * 6 + 1; 333 int printed_out; 334#define SAFE_SPRINTF(...) \ 335 do { \ 336 printed_out = snprintf(pb, max_chars, __VA_ARGS__); \ 337 if (printed_out <= 0) { \ 338 D("... snprintf failed.\n"); \ 339 return; \ 340 } \ 341 if (max_chars < (unsigned int)printed_out) { \ 342 D("... snprintf out of space.\n"); \ 343 return; \ 344 } \ 345 pb += printed_out; \ 346 max_chars -= printed_out; \ 347 } while(0) 348 349 for(i = 0; i < select_n; i++) { 350 fde = fd_table[i]; 351 SAFE_SPRINTF("%d", i); 352 if(fde == 0) { 353 SAFE_SPRINTF("? "); 354 continue; 355 } 356 if(fcntl(i, F_GETFL, NULL) < 0) { 357 SAFE_SPRINTF("b"); 358 } 359 SAFE_SPRINTF(" "); 360 } 361 D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff); 362} 363#endif 364 365static void fdevent_process() 366{ 367 int i, n; 368 fdevent *fde; 369 unsigned events; 370 fd_set rfd, wfd, efd; 371 372 memcpy(&rfd, &read_fds, sizeof(fd_set)); 373 memcpy(&wfd, &write_fds, sizeof(fd_set)); 374 memcpy(&efd, &error_fds, sizeof(fd_set)); 375 376 dump_all_fds("pre select()"); 377 378 n = select(select_n, &rfd, &wfd, &efd, NULL); 379 int saved_errno = errno; 380 D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0); 381 382 dump_all_fds("post select()"); 383 384 if(n < 0) { 385 switch(saved_errno) { 386 case EINTR: return; 387 case EBADF: 388 // Can't trust the FD sets after an error. 389 FD_ZERO(&wfd); 390 FD_ZERO(&efd); 391 FD_ZERO(&rfd); 392 break; 393 default: 394 D("Unexpected select() error=%d\n", saved_errno); 395 return; 396 } 397 } 398 if(n <= 0) { 399 // We fake a read, as the rest of the code assumes 400 // that errors will be detected at that point. 401 n = fdevent_fd_check(&rfd); 402 } 403 404 for(i = 0; (i < select_n) && (n > 0); i++) { 405 events = 0; 406 if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; } 407 if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; } 408 if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; } 409 410 if(events) { 411 fde = fd_table[i]; 412 if(fde == 0) 413 FATAL("missing fde for fd %d\n", i); 414 415 fde->events |= events; 416 417 D("got events fde->fd=%d events=%04x, state=%04x\n", 418 fde->fd, fde->events, fde->state); 419 if(fde->state & FDE_PENDING) continue; 420 fde->state |= FDE_PENDING; 421 fdevent_plist_enqueue(fde); 422 } 423 } 424} 425 426#endif 427 428static void fdevent_register(fdevent *fde) 429{ 430 if(fde->fd < 0) { 431 FATAL("bogus negative fd (%d)\n", fde->fd); 432 } 433 434 if(fde->fd >= fd_table_max) { 435 int oldmax = fd_table_max; 436 if(fde->fd > 32000) { 437 FATAL("bogus huuuuge fd (%d)\n", fde->fd); 438 } 439 if(fd_table_max == 0) { 440 fdevent_init(); 441 fd_table_max = 256; 442 } 443 while(fd_table_max <= fde->fd) { 444 fd_table_max *= 2; 445 } 446 fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max); 447 if(fd_table == 0) { 448 FATAL("could not expand fd_table to %d entries\n", fd_table_max); 449 } 450 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); 451 } 452 453 fd_table[fde->fd] = fde; 454} 455 456static void fdevent_unregister(fdevent *fde) 457{ 458 if((fde->fd < 0) || (fde->fd >= fd_table_max)) { 459 FATAL("fd out of range (%d)\n", fde->fd); 460 } 461 462 if(fd_table[fde->fd] != fde) { 463 FATAL("fd_table out of sync [%d]\n", fde->fd); 464 } 465 466 fd_table[fde->fd] = 0; 467 468 if(!(fde->state & FDE_DONT_CLOSE)) { 469 dump_fde(fde, "close"); 470 adb_close(fde->fd); 471 } 472} 473 474static void fdevent_plist_enqueue(fdevent *node) 475{ 476 fdevent *list = &list_pending; 477 478 node->next = list; 479 node->prev = list->prev; 480 node->prev->next = node; 481 list->prev = node; 482} 483 484static void fdevent_plist_remove(fdevent *node) 485{ 486 node->prev->next = node->next; 487 node->next->prev = node->prev; 488 node->next = 0; 489 node->prev = 0; 490} 491 492static fdevent *fdevent_plist_dequeue(void) 493{ 494 fdevent *list = &list_pending; 495 fdevent *node = list->next; 496 497 if(node == list) return 0; 498 499 list->next = node->next; 500 list->next->prev = list; 501 node->next = 0; 502 node->prev = 0; 503 504 return node; 505} 506 507static void fdevent_call_fdfunc(fdevent* fde) 508{ 509 unsigned events = fde->events; 510 fde->events = 0; 511 if(!(fde->state & FDE_PENDING)) return; 512 fde->state &= (~FDE_PENDING); 513 dump_fde(fde, "callback"); 514 fde->func(fde->fd, events, fde->arg); 515} 516 517static void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata) 518{ 519 520 D("subproc handling on fd=%d ev=%04x\n", fd, ev); 521 522 // Hook oneself back into the fde's suitable for select() on read. 523 if((fd < 0) || (fd >= fd_table_max)) { 524 FATAL("fd %d out of range for fd_table \n", fd); 525 } 526 fdevent *fde = fd_table[fd]; 527 fdevent_add(fde, FDE_READ); 528 529 if(ev & FDE_READ){ 530 int subproc_fd; 531 532 if(readx(fd, &subproc_fd, sizeof(subproc_fd))) { 533 FATAL("Failed to read the subproc's fd from fd=%d\n", fd); 534 } 535 if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) { 536 D("subproc_fd %d out of range 0, fd_table_max=%d\n", 537 subproc_fd, fd_table_max); 538 return; 539 } 540 fdevent *subproc_fde = fd_table[subproc_fd]; 541 if(!subproc_fde) { 542 D("subproc_fd %d cleared from fd_table\n", subproc_fd); 543 return; 544 } 545 if(subproc_fde->fd != subproc_fd) { 546 // Already reallocated? 547 D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd); 548 return; 549 } 550 551 subproc_fde->force_eof = 1; 552 553 int rcount = 0; 554 ioctl(subproc_fd, FIONREAD, &rcount); 555 D("subproc with fd=%d has rcount=%d err=%d\n", 556 subproc_fd, rcount, errno); 557 558 if(rcount) { 559 // If there is data left, it will show up in the select(). 560 // This works because there is no other thread reading that 561 // data when in this fd_func(). 562 return; 563 } 564 565 D("subproc_fde.state=%04x\n", subproc_fde->state); 566 subproc_fde->events |= FDE_READ; 567 if(subproc_fde->state & FDE_PENDING) { 568 return; 569 } 570 subproc_fde->state |= FDE_PENDING; 571 fdevent_call_fdfunc(subproc_fde); 572 } 573} 574 575fdevent *fdevent_create(int fd, fd_func func, void *arg) 576{ 577 fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); 578 if(fde == 0) return 0; 579 fdevent_install(fde, fd, func, arg); 580 fde->state |= FDE_CREATED; 581 return fde; 582} 583 584void fdevent_destroy(fdevent *fde) 585{ 586 if(fde == 0) return; 587 if(!(fde->state & FDE_CREATED)) { 588 FATAL("fde %p not created by fdevent_create()\n", fde); 589 } 590 fdevent_remove(fde); 591} 592 593void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 594{ 595 memset(fde, 0, sizeof(fdevent)); 596 fde->state = FDE_ACTIVE; 597 fde->fd = fd; 598 fde->force_eof = 0; 599 fde->func = func; 600 fde->arg = arg; 601 602#ifndef HAVE_WINSOCK 603 fcntl(fd, F_SETFL, O_NONBLOCK); 604#endif 605 fdevent_register(fde); 606 dump_fde(fde, "connect"); 607 fdevent_connect(fde); 608 fde->state |= FDE_ACTIVE; 609} 610 611void fdevent_remove(fdevent *fde) 612{ 613 if(fde->state & FDE_PENDING) { 614 fdevent_plist_remove(fde); 615 } 616 617 if(fde->state & FDE_ACTIVE) { 618 fdevent_disconnect(fde); 619 dump_fde(fde, "disconnect"); 620 fdevent_unregister(fde); 621 } 622 623 fde->state = 0; 624 fde->events = 0; 625} 626 627 628void fdevent_set(fdevent *fde, unsigned events) 629{ 630 events &= FDE_EVENTMASK; 631 632 if((fde->state & FDE_EVENTMASK) == events) return; 633 634 if(fde->state & FDE_ACTIVE) { 635 fdevent_update(fde, events); 636 dump_fde(fde, "update"); 637 } 638 639 fde->state = (fde->state & FDE_STATEMASK) | events; 640 641 if(fde->state & FDE_PENDING) { 642 /* if we're pending, make sure 643 ** we don't signal an event that 644 ** is no longer wanted. 645 */ 646 fde->events &= (~events); 647 if(fde->events == 0) { 648 fdevent_plist_remove(fde); 649 fde->state &= (~FDE_PENDING); 650 } 651 } 652} 653 654void fdevent_add(fdevent *fde, unsigned events) 655{ 656 fdevent_set( 657 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); 658} 659 660void fdevent_del(fdevent *fde, unsigned events) 661{ 662 fdevent_set( 663 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); 664} 665 666void fdevent_subproc_setup() 667{ 668 int s[2]; 669 670 if(adb_socketpair(s)) { 671 FATAL("cannot create shell-exit socket-pair\n"); 672 } 673 SHELL_EXIT_NOTIFY_FD = s[0]; 674 fdevent *fde; 675 fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); 676 if(!fde) 677 FATAL("cannot create fdevent for shell-exit handler\n"); 678 fdevent_add(fde, FDE_READ); 679} 680 681void fdevent_loop() 682{ 683 fdevent *fde; 684 fdevent_subproc_setup(); 685 686 for(;;) { 687 D("--- ---- waiting for events\n"); 688 689 fdevent_process(); 690 691 while((fde = fdevent_plist_dequeue())) { 692 fdevent_call_fdfunc(fde); 693 } 694 } 695} 696