Index: eloop.c |
diff --git a/eloop.c b/eloop.c |
index 5c61445ee3da8e7e5a31e534e0578b45622ae81f..99fdcefbbe17898a97f8b37ad18aaa8a3f08482f 100644 |
--- a/eloop.c |
+++ b/eloop.c |
@@ -41,7 +41,9 @@ static struct timeval now; |
static struct event { |
int fd; |
+ int flags; |
void (*callback)(void *); |
+ void (*callback_f)(int, void *); |
void *arg; |
struct event *next; |
} *events; |
@@ -58,17 +60,23 @@ static struct timeout *free_timeouts; |
static struct pollfd *fds; |
static size_t fds_len; |
-void |
-add_event(int fd, void (*callback)(void *), void *arg) |
+static int |
+_add_event_flags(int fd, |
+ int flags, |
+ void (*callback)(void *), |
+ void (*callback_f)(int, void *), |
+ void *arg) |
{ |
struct event *e, *last = NULL; |
/* We should only have one callback monitoring the fd */ |
for (e = events; e; e = e->next) { |
if (e->fd == fd) { |
+ e->flags = flags; |
e->callback = callback; |
+ e->callback_f = callback_f; |
e->arg = arg; |
- return; |
+ return 0; |
} |
last = e; |
} |
@@ -77,16 +85,34 @@ add_event(int fd, void (*callback)(void *), void *arg) |
if (free_events) { |
e = free_events; |
free_events = e->next; |
- } else |
- e = xmalloc(sizeof(*e)); |
+ } else { |
+ e = malloc(sizeof(*e)); |
+ if (e == NULL) |
+ return -1; |
+ } |
e->fd = fd; |
+ e->flags = flags; |
e->callback = callback; |
+ e->callback_f = callback_f; |
e->arg = arg; |
e->next = NULL; |
if (last) |
last->next = e; |
else |
events = e; |
+ return 0; |
+} |
+ |
+int |
+add_event(int fd, void (*callback)(void *), void *arg) |
+{ |
+ return _add_event_flags(fd, 0, callback, NULL, arg); |
+} |
+ |
+int |
+add_event_flags(int fd, int flags, void (*callback)(int, void *), void *arg) |
+{ |
+ return _add_event_flags(fd, flags, NULL, callback, arg); |
} |
void |
@@ -296,7 +322,7 @@ start_eloop(void) |
msecs = INT_MAX; |
else |
msecs = tv.tv_sec * 1000 + |
- (tv.tv_usec + 999) / 1000; |
+ (tv.tv_usec + 999) / 1000; |
} else |
/* No timeouts, so wait forever. */ |
msecs = -1; |
@@ -312,14 +338,20 @@ start_eloop(void) |
} |
if (nfds > fds_len) { |
free(fds); |
- /* Allocate 5 more than we need for future use */ |
- fds_len = nfds + 5; |
- fds = xmalloc(sizeof(*fds) * fds_len); |
+ fds = malloc(sizeof(*fds) * nfds); |
+ if (fds == NULL) { |
+ syslog(LOG_ERR, "malloc: %m"); |
+ exit(EXIT_FAILURE); |
+ } |
+ fds_len = nfds; |
} |
nfds = 0; |
for (e = events; e; e = e->next) { |
fds[nfds].fd = e->fd; |
- fds[nfds].events = POLLIN; |
+ if (e->flags == 0) |
+ fds[nfds].events = POLLIN; |
+ else |
+ fds[nfds].events = e->flags; |
fds[nfds].revents = 0; |
nfds++; |
} |
@@ -338,13 +370,18 @@ start_eloop(void) |
if (n == 0) |
continue; |
for (i = 0; i < nfds; i++) { |
- if (!(fds[i].revents & (POLLIN | POLLHUP))) |
+ if (fds[i].revents == 0) |
continue; |
for (e = events; e; e = e->next) { |
- if (e->fd == fds[i].fd) { |
- e->callback(e->arg); |
+ if (e->fd != fds[i].fd) |
+ continue; |
+ if (e->flags) { |
+ e->callback_f(fds[i].revents, e->arg); |
break; |
} |
+ if (fds[i].revents & (POLLIN | POLLHUP)) |
+ e->callback(e->arg); |
+ break; |
} |
} |
} |