summaryrefslogtreecommitdiff
path: root/poll
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2015-03-13 00:27:19 +0000
committerYann Ylavic <ylavic@apache.org>2015-03-13 00:27:19 +0000
commit4ae3ddd930a1558c9435b471aeb4444e560ecf1e (patch)
treeaf242da25c2bb5a706d9dc38363c418e1178625d /poll
parenta19d7e5ce9b457b1879ed13e2d2e1faa5b0ef3ed (diff)
downloadapr-4ae3ddd930a1558c9435b471aeb4444e560ecf1e.tar.gz
apr_poll(cb): fix error paths returned values and leaks.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1666341 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll')
-rw-r--r--poll/unix/epoll.c35
-rw-r--r--poll/unix/kqueue.c33
-rw-r--r--poll/unix/poll.c14
-rw-r--r--poll/unix/pollcb.c3
-rw-r--r--poll/unix/port.c33
-rw-r--r--poll/unix/z_asio.c11
6 files changed, 94 insertions, 35 deletions
diff --git a/poll/unix/epoll.c b/poll/unix/epoll.c
index 965e2833c..23686d5f5 100644
--- a/poll/unix/epoll.c
+++ b/poll/unix/epoll.c
@@ -106,12 +106,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
{
int fd_flags;
- if ((fd_flags = fcntl(fd, F_GETFD)) == -1)
- return errno;
+ if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(fd);
+ pollset->p = NULL;
+ return rv;
+ }
fd_flags |= FD_CLOEXEC;
- if (fcntl(fd, F_SETFD, fd_flags) == -1)
- return errno;
+ if (fcntl(fd, F_SETFD, fd_flags) == -1) {
+ rv = errno;
+ close(fd);
+ pollset->p = NULL;
+ return rv;
+ }
}
#endif
@@ -122,11 +130,13 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
APR_THREAD_MUTEX_DEFAULT,
p)) != APR_SUCCESS)) {
+ close(fd);
pollset->p = NULL;
return rv;
}
#else
if (flags & APR_POLLSET_THREADSAFE) {
+ close(fd);
pollset->p = NULL;
return APR_ENOTIMPL;
}
@@ -347,13 +357,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
#ifndef HAVE_EPOLL_CREATE1
{
int fd_flags;
+ apr_status_t rv;
- if ((fd_flags = fcntl(fd, F_GETFD)) == -1)
- return errno;
+ if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(fd);
+ pollcb->fd = -1;
+ return rv;
+ }
fd_flags |= FD_CLOEXEC;
- if (fcntl(fd, F_SETFD, fd_flags) == -1)
- return errno;
+ if (fcntl(fd, F_SETFD, fd_flags) == -1) {
+ rv = errno;
+ close(fd);
+ pollcb->fd = -1;
+ return rv;
+ }
}
#endif
diff --git a/poll/unix/kqueue.c b/poll/unix/kqueue.c
index 2e25c9fde..355ccba99 100644
--- a/poll/unix/kqueue.c
+++ b/poll/unix/kqueue.c
@@ -115,12 +115,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
{
int flags;
- if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1)
- return errno;
+ if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(pollset->p->kqueue_fd);
+ pollset->p = NULL;
+ return rv;
+ }
flags |= FD_CLOEXEC;
- if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1)
- return errno;
+ if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1) {
+ rv = errno;
+ close(pollset->p->kqueue_fd);
+ pollset->p = NULL;
+ return rv;
+ }
}
pollset->p->result_set = apr_palloc(p, pollset->p->setsize * sizeof(apr_pollfd_t));
@@ -338,13 +346,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
{
int flags;
+ apr_status_t rv;
- if ((flags = fcntl(fd, F_GETFD)) == -1)
- return errno;
+ if ((flags = fcntl(fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(fd);
+ pollcb->fd = -1;
+ return rv;
+ }
flags |= FD_CLOEXEC;
- if (fcntl(fd, F_SETFD, flags) == -1)
- return errno;
+ if (fcntl(fd, F_SETFD, flags) == -1) {
+ rv = errno;
+ close(fd);
+ pollcb->fd = -1;
+ return rv;
+ }
}
pollcb->fd = fd;
diff --git a/poll/unix/poll.c b/poll/unix/poll.c
index 871126b34..a11e7a932 100644
--- a/poll/unix/poll.c
+++ b/poll/unix/poll.c
@@ -240,24 +240,22 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
{
int ret;
apr_status_t rv = APR_SUCCESS;
-#ifdef WIN32
- apr_interval_time_t orig_timeout = timeout;
-#endif
- if (timeout > 0) {
- timeout /= 1000;
- }
#ifdef WIN32
/* WSAPoll() requires at least one socket. */
if (pollset->nelts == 0) {
*num = 0;
- if (orig_timeout > 0) {
- apr_sleep(orig_timeout);
+ if (timeout > 0) {
+ apr_sleep(timeout);
return APR_TIMEUP;
}
return APR_SUCCESS;
}
+ if (timeout > 0) {
+ timeout /= 1000;
+ }
+
ret = WSAPoll(pollset->p->pollset, pollset->nelts, (int)timeout);
#else
ret = poll(pollset->p->pollset, pollset->nelts, timeout);
diff --git a/poll/unix/pollcb.c b/poll/unix/pollcb.c
index e01006b38..ca9812520 100644
--- a/poll/unix/pollcb.c
+++ b/poll/unix/pollcb.c
@@ -156,6 +156,9 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
}
pollcb->provider = provider;
}
+ else if (rv != APR_SUCCESS) {
+ return rv;
+ }
if (flags & APR_POLLSET_WAKEABLE) {
/* Create wakeup pipe */
diff --git a/poll/unix/port.c b/poll/unix/port.c
index 8f14488bd..ee7700970 100644
--- a/poll/unix/port.c
+++ b/poll/unix/port.c
@@ -188,12 +188,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
{
int flags;
- if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1)
- return errno;
+ if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(pollset->p->port_fd);
+ pollset->p = NULL;
+ return rv;
+ }
flags |= FD_CLOEXEC;
- if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1)
- return errno;
+ if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1) {
+ rv = errno;
+ close(pollset->p->port_fd);
+ pollset->p = NULL;
+ return rv;
+ }
}
pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
@@ -477,13 +485,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
{
int flags;
+ apr_status_t rv;
- if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1)
- return errno;
+ if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1) {
+ rv = errno;
+ close(pollcb->fd);
+ pollcb->fd = -1;
+ return rv;
+ }
flags |= FD_CLOEXEC;
- if (fcntl(pollcb->fd, F_SETFD, flags) == -1)
- return errno;
+ if (fcntl(pollcb->fd, F_SETFD, flags) == -1) {
+ rv = errno;
+ close(pollcb->fd);
+ pollcb->fd = -1;
+ return rv;
+ }
}
pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));
diff --git a/poll/unix/z_asio.c b/poll/unix/z_asio.c
index d2df69638..7e0fd89a5 100644
--- a/poll/unix/z_asio.c
+++ b/poll/unix/z_asio.c
@@ -272,7 +272,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
APR_THREAD_MUTEX_DEFAULT,
p) != APR_SUCCESS) {
DBG1(1, "apr_thread_mutex_create returned %d\n", rv);
- pollset = NULL;
+ pollset->p = NULL;
return rv;
}
rv = msgget(IPC_PRIVATE, S_IWUSR+S_IRUSR); /* user r/w perms */
@@ -280,7 +280,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
#if DEBUG
perror(__FUNCTION__ " msgget returned < 0 ");
#endif
- pollset = NULL;
+ pollset->p = NULL;
return rv;
}
@@ -292,7 +292,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
APR_RING_INIT(&priv->prior_ready_ring, asio_elem_t, link);
#else /* APR doesn't have threads but caller wants a threadsafe pollset */
- pollset = NULL;
+ pollset->p = NULL;
return APR_ENOTIMPL;
#endif
@@ -304,6 +304,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
priv->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
if ((!priv->pollset) || (!priv->query_set)) {
+ pollset->p = NULL;
return APR_ENOMEM;
}
}
@@ -314,6 +315,10 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
priv->size = size;
priv->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
if (!priv->result_set) {
+ if (flags & APR_POLLSET_THREADSAFE) {
+ msgctl(priv->msg_q, IPC_RMID, NULL);
+ }
+ pollset->p = NULL;
return APR_ENOMEM;
}