diff options
author | brianp <brianp@13f79535-47bb-0310-9956-ffa450edef68> | 2002-08-07 00:06:12 +0000 |
---|---|---|
committer | brianp <brianp@13f79535-47bb-0310-9956-ffa450edef68> | 2002-08-07 00:06:12 +0000 |
commit | d003a04aed55303637e9f37c857b75d7d6cc498a (patch) | |
tree | 83dcc4e9965cde2228e8aecded155a4435650abf /poll | |
parent | bee0c5ded1f9b070f69845435faa475760ff83ec (diff) | |
download | libapr-d003a04aed55303637e9f37c857b75d7d6cc498a.tar.gz |
Changed apr_poll_socket_remove() and apr_poll() to avoid
putting invalid descriptors on the pollset after removing
from the middle of the array
Reported by: Rob Saccoccio <robs@fastcgi.com>
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@63801 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll')
-rw-r--r-- | poll/unix/poll.c | 10 | ||||
-rw-r--r-- | poll/unix/pollacc.c | 21 |
2 files changed, 28 insertions, 3 deletions
diff --git a/poll/unix/poll.c b/poll/unix/poll.c index f495c821f..da79e4b95 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -151,6 +151,10 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num, else if (aprset[i].desc_type == APR_POLL_FILE) { pollset[i].fd = aprset[i].desc.f->filedes; } + else if (aprset[i].desc_type == APR_NO_DESC) { + num = i + 1; + break; + } pollset[i].events = get_event(aprset[i].reqevents); } @@ -221,7 +225,7 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n #endif fd = aprset[i].desc.s->socketdes; } - else { + else if (aprset[i].desc_type == APR_POLL_FILE) { #if !APR_FILES_AS_SOCKETS return APR_EBADF; #else @@ -237,6 +241,10 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n #endif /* APR_FILES_AS_SOCKETS */ } + else if (aprset[i].desc_type == APR_NO_DESC) { + num = i + 1; + break; + } if (aprset[i].reqevents & APR_POLLIN) { FD_SET(fd, &readset); } diff --git a/poll/unix/pollacc.c b/poll/unix/pollacc.c index d421a45c0..36a2c8c7c 100644 --- a/poll/unix/pollacc.c +++ b/poll/unix/pollacc.c @@ -134,11 +134,28 @@ APR_DECLARE(apr_status_t) apr_poll_socket_mask(apr_pollfd_t *aprset, APR_DECLARE(apr_status_t) apr_poll_socket_remove(apr_pollfd_t *aprset, apr_socket_t *sock) { - apr_pollfd_t *curr = find_poll_sock(aprset, sock); - if (curr == NULL) { + apr_pollfd_t *match = NULL; + apr_pollfd_t *curr; + + for (curr = aprset; (curr->desc_type != APR_POLL_LASTDESC) && + (curr->desc_type != APR_NO_DESC); curr++) { + if (curr->desc.s == sock) { + match = curr; + } + } + if (match == NULL) { return APR_NOTFOUND; } + /* Remove this entry by swapping the last entry into its place. + * This ensures that the non-APR_NO_DESC entries are all at the + * start of the array, so that apr_poll() doesn't have to worry + * about invalid entries in the middle of the pollset. + */ + curr--; + if (curr != match) { + *match = *curr; + } curr->desc_type = APR_NO_DESC; return APR_SUCCESS; |