summaryrefslogtreecommitdiff
path: root/os/beos/beosd.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/beos/beosd.c')
-rw-r--r--os/beos/beosd.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/os/beos/beosd.c b/os/beos/beosd.c
index 09a2cf8e9c..f1a517d16f 100644
--- a/os/beos/beosd.c
+++ b/os/beos/beosd.c
@@ -62,6 +62,8 @@
#include "http_main.h"
#include "http_log.h"
#include "beosd.h"
+#include "apr_lock.h"
+#include "mpm_common.h"
beosd_config_rec beosd_config;
@@ -110,3 +112,98 @@ void beosd_pre_config(void)
simply have a no-op here to allow for common conf files
*/
}
+
+AP_DECLARE(apr_status_t) beosd_accept(void **accepted, ap_listen_rec *lr,
+ apr_pool_t *ptrans)
+{
+ apr_socket_t *csd;
+ apr_status_t status;
+ int sockdes;
+
+ status = apr_accept(&csd, lr->sd, ptrans);
+ if (status == APR_SUCCESS) {
+ *accepted = csd;
+ apr_os_sock_get(&sockdes, csd);
+ if (sockdes >= FD_SETSIZE) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
+ "new file descriptor %d is too large; you probably need "
+ "to rebuild Apache with a larger FD_SETSIZE "
+ "(currently %d)",
+ sockdes, FD_SETSIZE);
+ apr_socket_close(csd);
+ return APR_EINTR;
+ }
+ return status;
+ }
+
+ if (APR_STATUS_IS_EINTR(status)) {
+ return status;
+ }
+ /* Our old behaviour here was to continue after accept()
+ * errors. But this leads us into lots of troubles
+ * because most of the errors are quite fatal. For
+ * example, EMFILE can be caused by slow descriptor
+ * leaks (say in a 3rd party module, or libc). It's
+ * foolish for us to continue after an EMFILE. We also
+ * seem to tickle kernel bugs on some platforms which
+ * lead to never-ending loops here. So it seems best
+ * to just exit in most cases.
+ */
+ switch (status) {
+#ifdef EPROTO
+ /* EPROTO on certain older kernels really means
+ * ECONNABORTED, so we need to ignore it for them.
+ * See discussion in new-httpd archives nh.9701
+ * search for EPROTO.
+ *
+ * Also see nh.9603, search for EPROTO:
+ * There is potentially a bug in Solaris 2.x x<6,
+ * and other boxes that implement tcp sockets in
+ * userland (i.e. on top of STREAMS). On these
+ * systems, EPROTO can actually result in a fatal
+ * loop. See PR#981 for example. It's hard to
+ * handle both uses of EPROTO.
+ */
+ case EPROTO:
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED:
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH:
+#endif
+ break;
+#ifdef ENETDOWN
+ case ENETDOWN:
+ /*
+ * When the network layer has been shut down, there
+ * is not much use in simply exiting: the parent
+ * would simply re-create us (and we'd fail again).
+ * Use the CHILDFATAL code to tear the server down.
+ * @@@ Martin's idea for possible improvement:
+ * A different approach would be to define
+ * a new APEXIT_NETDOWN exit code, the reception
+ * of which would make the parent shutdown all
+ * children, then idle-loop until it detected that
+ * the network is up again, and restart the children.
+ * Ben Hyde noted that temporary ENETDOWN situations
+ * occur in mobile IP.
+ */
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
+ "apr_accept: giving up.");
+ return APR_EGENERAL;
+#endif /*ENETDOWN*/
+
+ default:
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf,
+ "apr_accept: (client socket)");
+ return APR_EGENERAL;
+ }
+ return status;
+}