2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <sys/ioctl.h>
31 #include "transport.h"
35 /* !!! Do not enable DEBUG for the sdb that will run as the server:
36 ** both stdout and stderr are used to communicate between the client
37 ** and server. Any extra output will cause failures.
39 #define DEBUG 0 /* non-0 will break sdb server */
41 // This socket is used when a subproc shell service exists.
42 // It wakes up the fdevent_loop() and cause the correct handling
43 // of the shell's pseudo-tty master. I.e. force close it.
44 int SHELL_EXIT_NOTIFY_FD = -1;
46 static void fatal(const char *fn, const char *fmt, ...)
50 fprintf(stderr, "%s:", fn);
51 vfprintf(stderr, fmt, ap);
56 #define FATAL(x...) fatal(__FUNCTION__, x)
61 sdb_mutex_lock(&D_lock); \
62 int save_errno = errno; \
63 fprintf(stderr, "%s::%s():", __FILE__, __FUNCTION__); \
65 fprintf(stderr, __VA_ARGS__); \
66 sdb_mutex_unlock(&D_lock); \
69 static void dump_fde(fdevent *fde, const char *info)
71 sdb_mutex_lock(&D_lock);
72 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
73 fde->state & FDE_READ ? 'R' : ' ',
74 fde->state & FDE_WRITE ? 'W' : ' ',
75 fde->state & FDE_ERROR ? 'E' : ' ',
77 sdb_mutex_unlock(&D_lock);
80 #define D(...) ((void)0)
81 #define dump_fde(fde, info) do { } while(0)
84 #define FDE_EVENTMASK 0x00ff
85 #define FDE_STATEMASK 0xff00
87 #define FDE_ACTIVE 0x0100
88 #define FDE_PENDING 0x0200
89 #define FDE_CREATED 0x0400
91 static void fdevent_plist_enqueue(fdevent *node);
92 static void fdevent_plist_remove(fdevent *node);
93 static fdevent *fdevent_plist_dequeue(void);
94 static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata);
96 static fdevent list_pending = {
97 .next = &list_pending,
98 .prev = &list_pending,
101 static fdevent **fd_table = 0;
102 static int fd_table_max = 0;
107 #include <sys/epoll.h>
109 static int epoll_fd = -1;
111 static void fdevent_init()
113 /* XXX: what's a good size for the passed in hint? */
114 epoll_fd = epoll_create(256);
117 perror("epoll_create() failed");
121 /* mark for close-on-exec */
122 fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
125 static void fdevent_connect(fdevent *fde)
127 struct epoll_event ev;
129 memset(&ev, 0, sizeof(ev));
134 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
135 perror("epoll_ctl() failed\n");
141 static void fdevent_disconnect(fdevent *fde)
143 struct epoll_event ev;
145 memset(&ev, 0, sizeof(ev));
149 /* technically we only need to delete if we
150 ** were actively monitoring events, but let's
151 ** be aggressive and do it anyway, just in case
152 ** something's out of sync
154 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev);
157 static void fdevent_update(fdevent *fde, unsigned events)
159 struct epoll_event ev;
162 active = (fde->state & FDE_EVENTMASK) != 0;
164 memset(&ev, 0, sizeof(ev));
168 if(events & FDE_READ) ev.events |= EPOLLIN;
169 if(events & FDE_WRITE) ev.events |= EPOLLOUT;
170 if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);
172 fde->state = (fde->state & FDE_STATEMASK) | events;
175 /* we're already active. if we're changing to *no*
176 ** events being monitored, we need to delete, otherwise
177 ** we need to just modify
180 if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
181 perror("epoll_ctl() failed\n");
185 if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
186 perror("epoll_ctl() failed\n");
191 /* we're not active. if we're watching events, we need
192 ** to add, otherwise we can just do nothing
195 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
196 perror("epoll_ctl() failed\n");
203 static void fdevent_process()
205 struct epoll_event events[256];
209 n = epoll_wait(epoll_fd, events, 256, -1);
212 if(errno == EINTR) return;
213 perror("epoll_wait");
217 for(i = 0; i < n; i++) {
218 struct epoll_event *ev = events + i;
221 if(ev->events & EPOLLIN) {
222 fde->events |= FDE_READ;
224 if(ev->events & EPOLLOUT) {
225 fde->events |= FDE_WRITE;
227 if(ev->events & (EPOLLERR | EPOLLHUP)) {
228 fde->events |= FDE_ERROR;
231 if(fde->state & FDE_PENDING) continue;
232 fde->state |= FDE_PENDING;
233 fdevent_plist_enqueue(fde);
238 #else /* USE_SELECT */
241 #include <winsock2.h>
243 #include <sys/select.h>
246 static fd_set read_fds;
247 static fd_set write_fds;
248 static fd_set error_fds;
250 static int select_n = 0;
252 static void fdevent_init(void)
259 static void fdevent_connect(fdevent *fde)
261 if(fde->fd >= select_n) {
262 select_n = fde->fd + 1;
266 static void fdevent_disconnect(fdevent *fde)
270 FD_CLR(fde->fd, &read_fds);
271 FD_CLR(fde->fd, &write_fds);
272 FD_CLR(fde->fd, &error_fds);
274 for(n = 0, i = 0; i < select_n; i++) {
275 if(fd_table[i] != 0) n = i;
280 static void fdevent_update(fdevent *fde, unsigned events)
282 if(events & FDE_READ) {
283 FD_SET(fde->fd, &read_fds);
285 FD_CLR(fde->fd, &read_fds);
287 if(events & FDE_WRITE) {
288 FD_SET(fde->fd, &write_fds);
290 FD_CLR(fde->fd, &write_fds);
292 if(events & FDE_ERROR) {
293 FD_SET(fde->fd, &error_fds);
295 FD_CLR(fde->fd, &error_fds);
298 fde->state = (fde->state & FDE_STATEMASK) | events;
301 /* Looks at fd_table[] for bad FDs and sets bit in fds.
302 ** Returns the number of bad FDs.
304 static int fdevent_fd_check(fd_set *fds)
309 for(i = 0; i < select_n; i++) {
311 if(fde == 0) continue;
312 if(fcntl(i, F_GETFL, NULL) < 0) {
315 // fde->state |= FDE_DONT_CLOSE;
323 static inline void dump_all_fds(const char *extra_msg) {}
325 static void dump_all_fds(const char *extra_msg)
329 // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank
330 char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff;
331 size_t max_chars = FD_SETSIZE * 6 + 1;
333 #define SAFE_SPRINTF(...) \
335 printed_out = snprintf(pb, max_chars, __VA_ARGS__); \
336 if (printed_out <= 0) { \
337 D("... snprintf failed.\n"); \
340 if (max_chars < (unsigned int)printed_out) { \
341 D("... snprintf out of space.\n"); \
345 max_chars -= printed_out; \
348 for(i = 0; i < select_n; i++) {
350 SAFE_SPRINTF("%d", i);
355 if(fcntl(i, F_GETFL, NULL) < 0) {
360 D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff);
364 static int fdevent_process()
369 fd_set rfd, wfd, efd;
371 memcpy(&rfd, &read_fds, sizeof(fd_set));
372 memcpy(&wfd, &write_fds, sizeof(fd_set));
373 memcpy(&efd, &error_fds, sizeof(fd_set));
375 dump_all_fds("pre select()");
377 n = select(select_n, &rfd, &wfd, &efd, NULL);
378 int saved_errno = errno;
379 D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
381 dump_all_fds("post select()");
384 switch(saved_errno) {
385 case EINTR: return -1;
387 // Can't trust the FD sets after an error.
393 D("Unexpected select() error=%d\n", saved_errno);
398 // We fake a read, as the rest of the code assumes
399 // that errors will be detected at that point.
400 n = fdevent_fd_check(&rfd);
403 for(i = 0; (i < select_n) && (n > 0); i++) {
405 if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; }
406 if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; }
407 if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; }
412 FATAL("missing fde for fd %d\n", i);
414 fde->events |= events;
416 D("got events fde->fd=%d events=%04x, state=%04x\n",
417 fde->fd, fde->events, fde->state);
418 if(fde->state & FDE_PENDING) continue;
419 fde->state |= FDE_PENDING;
420 fdevent_plist_enqueue(fde);
429 static void fdevent_register(fdevent *fde)
432 FATAL("bogus negative fd (%d)\n", fde->fd);
435 if(fde->fd >= fd_table_max) {
436 int oldmax = fd_table_max;
437 if(fde->fd > 32000) {
438 FATAL("bogus huuuuge fd (%d)\n", fde->fd);
440 if(fd_table_max == 0) {
444 while(fd_table_max <= fde->fd) {
447 fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
449 FATAL("could not expand fd_table to %d entries\n", fd_table_max);
451 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
454 fd_table[fde->fd] = fde;
457 static void fdevent_unregister(fdevent *fde)
459 if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
460 FATAL("fd out of range (%d)\n", fde->fd);
463 if(fd_table[fde->fd] != fde) {
464 FATAL("fd_table out of sync [%d]\n", fde->fd);
467 fd_table[fde->fd] = 0;
469 if(!(fde->state & FDE_DONT_CLOSE)) {
470 dump_fde(fde, "close");
475 static void fdevent_plist_enqueue(fdevent *node)
477 fdevent *list = &list_pending;
480 node->prev = list->prev;
481 node->prev->next = node;
485 static void fdevent_plist_remove(fdevent *node)
487 node->prev->next = node->next;
488 node->next->prev = node->prev;
493 static fdevent *fdevent_plist_dequeue(void)
495 fdevent *list = &list_pending;
496 fdevent *node = list->next;
498 if(node == list) return 0;
500 list->next = node->next;
501 list->next->prev = list;
508 static void fdevent_call_fdfunc(fdevent* fde)
510 unsigned events = fde->events;
512 if(!(fde->state & FDE_PENDING)) return;
513 fde->state &= (~FDE_PENDING);
514 dump_fde(fde, "callback");
515 fde->func(fde->fd, events, fde->arg);
518 static void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata)
521 D("subproc handling on fd=%d ev=%04x\n", fd, ev);
523 // Hook oneself back into the fde's suitable for select() on read.
524 if((fd < 0) || (fd >= fd_table_max)) {
525 FATAL("fd %d out of range for fd_table \n", fd);
527 fdevent *fde = fd_table[fd];
528 fdevent_add(fde, FDE_READ);
533 if(readx(fd, &subproc_fd, sizeof(subproc_fd))) {
534 FATAL("Failed to read the subproc's fd from fd=%d\n", fd);
536 if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
537 D("subproc_fd %d out of range 0, fd_table_max=%d\n",
538 subproc_fd, fd_table_max);
541 fdevent *subproc_fde = fd_table[subproc_fd];
543 D("subproc_fd %d cleared from fd_table\n", subproc_fd);
546 if(subproc_fde->fd != subproc_fd) {
547 // Already reallocated?
548 D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
552 subproc_fde->force_eof = 1;
555 ioctl(subproc_fd, FIONREAD, &rcount);
556 D("subproc with fd=%d has rcount=%d err=%d\n",
557 subproc_fd, rcount, errno);
560 // If there is data left, it will show up in the select().
561 // This works because there is no other thread reading that
562 // data when in this fd_func().
566 D("subproc_fde.state=%04x\n", subproc_fde->state);
567 subproc_fde->events |= FDE_READ;
568 if(subproc_fde->state & FDE_PENDING) {
571 subproc_fde->state |= FDE_PENDING;
572 fdevent_call_fdfunc(subproc_fde);
576 fdevent *fdevent_create(int fd, fd_func func, void *arg)
578 fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
579 if(fde == 0) return 0;
580 fdevent_install(fde, fd, func, arg);
581 fde->state |= FDE_CREATED;
585 void fdevent_destroy(fdevent *fde)
588 if(!(fde->state & FDE_CREATED)) {
589 FATAL("fde %p not created by fdevent_create()\n", fde);
594 void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
596 memset(fde, 0, sizeof(fdevent));
597 fde->state = FDE_ACTIVE;
604 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
605 D("failed to close fd exec:%d\n",fd);
608 fdevent_register(fde);
609 dump_fde(fde, "connect");
610 fdevent_connect(fde);
611 fde->state |= FDE_ACTIVE;
614 void fdevent_remove(fdevent *fde)
616 if(fde->state & FDE_PENDING) {
617 fdevent_plist_remove(fde);
620 if(fde->state & FDE_ACTIVE) {
621 fdevent_disconnect(fde);
622 dump_fde(fde, "disconnect");
623 fdevent_unregister(fde);
631 void fdevent_set(fdevent *fde, unsigned events)
633 events &= FDE_EVENTMASK;
635 if((fde->state & FDE_EVENTMASK) == events) return;
637 if(fde->state & FDE_ACTIVE) {
638 fdevent_update(fde, events);
639 dump_fde(fde, "update");
642 fde->state = (fde->state & FDE_STATEMASK) | events;
644 if(fde->state & FDE_PENDING) {
645 /* if we're pending, make sure
646 ** we don't signal an event that
647 ** is no longer wanted.
649 fde->events &= (~events);
650 if(fde->events == 0) {
651 fdevent_plist_remove(fde);
652 fde->state &= (~FDE_PENDING);
657 void fdevent_add(fdevent *fde, unsigned events)
660 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
663 void fdevent_del(fdevent *fde, unsigned events)
666 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
669 void fdevent_subproc_setup()
673 if(sdb_socketpair(s)) {
674 FATAL("cannot create shell-exit socket-pair\n");
676 SHELL_EXIT_NOTIFY_FD = s[0];
678 fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL);
680 FATAL("cannot create fdevent for shell-exit handler\n");
681 fdevent_add(fde, FDE_READ);
687 fdevent_subproc_setup();
690 D("--- ---- waiting for events\n");
692 if (fdevent_process() < 0) {
696 while((fde = fdevent_plist_dequeue())) {
697 fdevent_call_fdfunc(fde);