diff options
author | Yann Ylavic <ylavic@apache.org> | 2015-03-13 00:27:19 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2015-03-13 00:27:19 +0000 |
commit | 4ae3ddd930a1558c9435b471aeb4444e560ecf1e (patch) | |
tree | af242da25c2bb5a706d9dc38363c418e1178625d /poll | |
parent | a19d7e5ce9b457b1879ed13e2d2e1faa5b0ef3ed (diff) | |
download | apr-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.c | 35 | ||||
-rw-r--r-- | poll/unix/kqueue.c | 33 | ||||
-rw-r--r-- | poll/unix/poll.c | 14 | ||||
-rw-r--r-- | poll/unix/pollcb.c | 3 | ||||
-rw-r--r-- | poll/unix/port.c | 33 | ||||
-rw-r--r-- | poll/unix/z_asio.c | 11 |
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; } |