diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-08-21 16:06:11 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-08-21 16:06:11 +0200 |
commit | 9d99a7699d7021a1c219d6553e037ac7ba4a5a37 (patch) | |
tree | 54c7c4383e3c2e627ea7736e3345d558dcdf23b9 | |
parent | 58411110894c0a9e6a1a1ec9dbdf2fbe2ef3da00 (diff) | |
download | conntrack-tools-9d99a7699d7021a1c219d6553e037ac7ba4a5a37.tar.gz conntrack-tools-9d99a7699d7021a1c219d6553e037ac7ba4a5a37.zip |
conntrackd: allow to remove file descriptors from set
With this patch, we can remove file descriptors dinamically
from our own file descriptor pool.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/fds.h | 9 | ||||
-rw-r--r-- | src/fds.c | 46 |
2 files changed, 55 insertions, 0 deletions
diff --git a/include/fds.h b/include/fds.h index 019d3f9..f3728d7 100644 --- a/include/fds.h +++ b/include/fds.h @@ -1,13 +1,22 @@ #ifndef _FDS_H_ #define _FDS_H_ +#include "linux_list.h" + struct fds { int maxfd; fd_set readfds; + struct list_head list; +}; + +struct fds_item { + struct list_head head; + int fd; }; struct fds *create_fds(void); void destroy_fds(struct fds *); int register_fd(int fd, struct fds *fds); +int unregister_fd(int fd, struct fds *fds); #endif @@ -27,20 +27,66 @@ struct fds *create_fds(void) if (fds == NULL) return NULL; + INIT_LIST_HEAD(&fds->list); + return fds; } void destroy_fds(struct fds *fds) { + struct fds_item *this, *tmp; + + list_for_each_entry_safe(this, tmp, &fds->list, head) { + list_del(&this->head); + FD_CLR(this->fd, &fds->readfds); + free(this); + } free(fds); } int register_fd(int fd, struct fds *fds) { + struct fds_item *item; + FD_SET(fd, &fds->readfds); if (fd > fds->maxfd) fds->maxfd = fd; + item = calloc(sizeof(struct fds_item), 1); + if (item == NULL) + return -1; + + item->fd = fd; + list_add(&item->head, &fds->list); + return 0; } + +int unregister_fd(int fd, struct fds *fds) +{ + int found = 0, maxfd = -1; + struct fds_item *this, *tmp; + + list_for_each_entry_safe(this, tmp, &fds->list, head) { + if (this->fd == fd) { + list_del(&this->head); + FD_CLR(this->fd, &fds->readfds); + free(this); + found = 1; + /* ... and recalculate maxfd, see below. */ + } + } + /* not found, report an error. */ + if (!found) + return -1; + + /* calculate the new maximum fd. */ + list_for_each_entry(this, &fds->list, head) { + if (maxfd < this->fd) { + maxfd = this->fd; + } + } + return 0; +} + |