• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
45 int SHELL_EXIT_NOTIFY_FD = -1;
46 
fatal(const char * fn,const char * fmt,...)47 static 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)
dump_fde(fdevent * fde,const char * info)70 static 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 
92 static void fdevent_plist_enqueue(fdevent *node);
93 static void fdevent_plist_remove(fdevent *node);
94 static fdevent *fdevent_plist_dequeue(void);
95 static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata);
96 
97 static fdevent list_pending = {
98     .next = &list_pending,
99     .prev = &list_pending,
100 };
101 
102 static fdevent **fd_table = 0;
103 static int fd_table_max = 0;
104 
105 #ifdef CRAPTASTIC
106 //HAVE_EPOLL
107 
108 #include <sys/epoll.h>
109 
110 static int epoll_fd = -1;
111 
fdevent_init()112 static 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 
fdevent_connect(fdevent * fde)126 static 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 
fdevent_disconnect(fdevent * fde)142 static 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 
fdevent_update(fdevent * fde,unsigned events)158 static 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 
fdevent_process()204 static 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 
247 static fd_set read_fds;
248 static fd_set write_fds;
249 static fd_set error_fds;
250 
251 static int select_n = 0;
252 
fdevent_init(void)253 static void fdevent_init(void)
254 {
255     FD_ZERO(&read_fds);
256     FD_ZERO(&write_fds);
257     FD_ZERO(&error_fds);
258 }
259 
fdevent_connect(fdevent * fde)260 static void fdevent_connect(fdevent *fde)
261 {
262     if(fde->fd >= select_n) {
263         select_n = fde->fd + 1;
264     }
265 }
266 
fdevent_disconnect(fdevent * fde)267 static 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 
fdevent_update(fdevent * fde,unsigned events)281 static 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 */
fdevent_fd_check(fd_set * fds)305 static 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
dump_all_fds(const char * extra_msg)324 static inline void dump_all_fds(const char *extra_msg) {}
325 #else
dump_all_fds(const char * extra_msg)326 static void dump_all_fds(const char *extra_msg)
327 {
328 int 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 
fdevent_process()365 static 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 
fdevent_register(fdevent * fde)428 static 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 
fdevent_unregister(fdevent * fde)456 static 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 
fdevent_plist_enqueue(fdevent * node)474 static 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 
fdevent_plist_remove(fdevent * node)484 static 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 
fdevent_plist_dequeue(void)492 static 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 
fdevent_call_fdfunc(fdevent * fde)507 static 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 
fdevent_subproc_event_func(int fd,unsigned ev,void * userdata)517 static 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 
fdevent_create(int fd,fd_func func,void * arg)575 fdevent *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 
fdevent_destroy(fdevent * fde)584 void 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 
fdevent_install(fdevent * fde,int fd,fd_func func,void * arg)593 void 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 
fdevent_remove(fdevent * fde)611 void 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 
fdevent_set(fdevent * fde,unsigned events)628 void 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 
fdevent_add(fdevent * fde,unsigned events)654 void fdevent_add(fdevent *fde, unsigned events)
655 {
656     fdevent_set(
657         fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
658 }
659 
fdevent_del(fdevent * fde,unsigned events)660 void fdevent_del(fdevent *fde, unsigned events)
661 {
662     fdevent_set(
663         fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
664 }
665 
fdevent_subproc_setup()666 void 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 
fdevent_loop()681 void 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