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