summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrjung <rjung@13f79535-47bb-0310-9956-ffa450edef68>2013-02-25 00:16:02 +0000
committerrjung <rjung@13f79535-47bb-0310-9956-ffa450edef68>2013-02-25 00:16:02 +0000
commitdf171430f10ce038fbeeb202ac418026cea3c67f (patch)
treea95e674d2328cdfe9c9866658693f434d1b6f508
parent92827ff083e28b774ad23ab780247c0900bc851a (diff)
downloadlibapr-df171430f10ce038fbeeb202ac418026cea3c67f.tar.gz
Fix detection of O_NONBLOCK inheritance.
The original test failed occasionally on a busy FreeBSD server when accept() returned EAGAIN. Backport of r1449568 from trunk resp. r1449569 from 1.5.x. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@1449570 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--build/apr_network.m431
2 files changed, 34 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index d090185ca..2ea186092 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes for APR 1.4.7
+ *) configure: Fix detection of O_NONBLOCK inheritance on busy
+ systems. [Rainer Jung]
+
*) Remove unused code, fix strict C compliance bug in SHA-256
implementation. [Jan Kaluza <jkaluza redhat.com>]
diff --git a/build/apr_network.m4 b/build/apr_network.m4
index 4d479a45a..d70fbd998 100644
--- a/build/apr_network.m4
+++ b/build/apr_network.m4
@@ -555,13 +555,24 @@ dnl
AC_DEFUN([APR_CHECK_O_NONBLOCK_INHERITED], [
AC_CACHE_CHECK(if O_NONBLOCK setting is inherited from listening sockets, ac_cv_o_nonblock_inherited,[
AC_TRY_RUN( [
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDIO_H
#include <stdio.h>
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -632,6 +643,26 @@ int main(void) {
exit(1);
}
sa_len = sizeof sa;
+ /* 1 second select timeout */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ /* Set up fd set */
+ FD_ZERO(&fds);
+ FD_SET(listen_s, &fds);
+ /* Wait for socket to become readable */
+ rc = select(listen_s + 1, &fds, NULL, NULL, &tv);
+ if (rc < 0) {
+ perror("select");
+ exit(1);
+ }
+ if (rc == 0) {
+ fprintf(stderr, "Socket failed to become readable (timeout)\n");
+ exit(1);
+ }
+ if (!FD_ISSET(listen_s, &fds)) {
+ fprintf(stderr, "Socket failed to become readable (selected another fd)\n");
+ exit(1);
+ }
connected_s = accept(listen_s, (struct sockaddr *)&sa, &sa_len);
if (connected_s < 0) {
perror("accept");