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