2 fd.c -- I/O and event multiplexing
4 Copyright (C) 2003-2004 Guus Sliepen <guus@tinc-vpn.org>,
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "support/avl.h"
26 #include "support/xalloc.h"
30 static fd_set readset, writeset, errorset;
32 static avl_tree_t *fds;
34 volatile bool fd_running = false;
36 int fd_compare(struct fd *a, struct fd *b) {
47 fds = avl_tree_new((avl_compare_t)fd_compare, NULL);
58 bool fd_add(struct fd *fd) {
63 FD_SET(fd->fd, &readset);
66 FD_SET(fd->fd, &writeset);
69 FD_SET(fd->fd, &errorset);
77 bool fd_del(struct fd *fd) {
78 FD_CLR(fd->fd, &readset);
79 FD_CLR(fd->fd, &writeset);
80 FD_CLR(fd->fd, &errorset);
83 max_fd = ((struct fd *)fds->tail)->fd;
85 return avl_del(fds, fd);
88 bool fd_mod(struct fd *fd) {
90 FD_SET(fd->fd, &readset);
92 FD_CLR(fd->fd, &readset);
95 FD_SET(fd->fd, &writeset);
97 FD_CLR(fd->fd, &writeset);
100 FD_SET(fd->fd, &errorset);
102 FD_CLR(fd->fd, &errorset);
108 fd_set readtmp, writetmp, errortmp;
112 logger(LOG_INFO, "fd: running");
119 tv = event_timeout();
121 result = select(max_fd + 1, &readtmp, &writetmp, &errortmp, tv.tv_sec >= 0 ? &tv : NULL);
124 if(errno != EINTR && errno != EAGAIN) {
125 logger(LOG_ERR, _("fd: error while waiting for input: %s"), strerror(errno));
135 avl_foreach(fds, fd, {
136 if(fd->read && FD_ISSET(fd->fd, &readtmp))
138 if(fd->write && FD_ISSET(fd->fd, &writetmp))
140 if(fd->error && FD_ISSET(fd->fd, &errortmp))
148 logger(LOG_INFO, "fd: stopping");