summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2012-11-07 16:13:21 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2012-11-07 16:13:21 +0000
commit4aa4bfc3ccee6e3219d008c5cc0b641424a0ec35 (patch)
tree3c61fab621d7c83d08817a6e0a77f71f4b207628
parent057f859112347fb0dff7d6a03a03a424cbc2c662 (diff)
downloadlibapr-4aa4bfc3ccee6e3219d008c5cc0b641424a0ec35.tar.gz
Trunk r1406690:
apr_socket_accept_filter: Return success when trying to again set the filter to the same value as before. Use apr_cpystrn(). PR: 37863 (warning message from Apache httpd during restart) git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@1406694 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES4
-rw-r--r--network_io/unix/sockopt.c21
2 files changed, 23 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index a1781b02e..cd111da1f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
-*- coding: utf-8 -*-
Changes for APR 1.4.7
+ *) apr_socket_accept_filter: Return success when trying to again set
+ the filter to the same value as before, avoiding an unhelpful
+ APR_EINVAL. PR 37863. [Jeff Trawick]
+
*) configure: Fix Linux 3.x detection. PR 54001. [Gilles Espinasse
<g esp free fr>]
diff --git a/network_io/unix/sockopt.c b/network_io/unix/sockopt.c
index 546f4a3fa..7b67c2ec1 100644
--- a/network_io/unix/sockopt.c
+++ b/network_io/unix/sockopt.c
@@ -389,8 +389,25 @@ apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *nonconst_name,
const char *args = nonconst_args;
struct accept_filter_arg af;
- strncpy(af.af_name, name, 16);
- strncpy(af.af_arg, args, 256 - 16);
+ socklen_t optlen = sizeof(af);
+
+ /* FreeBSD returns an error if the filter is already set; ignore
+ * this call if we previously set it to the same value.
+ */
+ if ((getsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER,
+ &af, &optlen)) == 0) {
+ if (!strcmp(name, af.af_name) && !strcmp(args, af.af_arg)) {
+ return APR_SUCCESS;
+ }
+ }
+
+ /* Uhh, at least in FreeBSD 9 the fields are declared as arrays of
+ * these lengths; did sizeof not work in some ancient release?
+ *
+ * FreeBSD kernel sets the last byte to a '\0'.
+ */
+ apr_cpystrn(af.af_name, name, 16);
+ apr_cpystrn(af.af_arg, args, 256 - 16);
if ((setsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER,
&af, sizeof(af))) < 0) {