1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <unistd.h>
18#include "httpd.h"
19#include "http_config.h"
20#include "http_main.h"
21#include "http_log.h"
22#include "beosd.h"
23#include "mpm_common.h"
24
25beosd_config_rec beosd_config;
26
27/* Set group privileges.
28 *
29 * Note that until we get the multi-user situation sorted on beos,
30 * this is just a no-op to allow common configuration files!
31 */
32
33#if B_BEOS_VERSION < 0x0460
34static int set_group_privs(void)
35{
36    /* no-op */
37    return 0;
38}
39#endif
40
41
42int beosd_setup_child(void)
43{
44    /* TODO: revisit the whole issue of users/groups for BeOS as
45     * R5 and below doesn't really have much concept of them.
46     */
47
48    return 0;
49}
50
51
52AP_DECLARE(const char *) beosd_set_user(cmd_parms *cmd,
53                                        void *dummy, const char *arg)
54{
55    /* no-op */
56    return NULL;
57}
58
59AP_DECLARE(const char *) beosd_set_group(cmd_parms *cmd,
60                                         void *dummy, const char *arg)
61{
62    /* no-op */
63    return NULL;
64}
65
66void beosd_pre_config(void)
67{
68    /* Until the multi-user situation on BeOS is fixed,
69       simply have a no-op here to allow for common conf files
70     */
71}
72
73AP_DECLARE(apr_status_t) beosd_accept(void **accepted, ap_listen_rec *lr,
74                                      apr_pool_t *ptrans)
75{
76    apr_socket_t *csd;
77    apr_status_t status;
78    int sockdes;
79
80    status = apr_socket_accept(&csd, lr->sd, ptrans);
81    if (status == APR_SUCCESS) {
82        *accepted = csd;
83        apr_os_sock_get(&sockdes, csd);
84        if (sockdes >= FD_SETSIZE) {
85            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
86                         "new file descriptor %d is too large; you probably need "
87                         "to rebuild Apache with a larger FD_SETSIZE "
88                         "(currently %d)",
89                         sockdes, FD_SETSIZE);
90            apr_socket_close(csd);
91            return APR_EINTR;
92        }
93        return status;
94    }
95
96    if (APR_STATUS_IS_EINTR(status)) {
97        return status;
98    }
99    /* Our old behaviour here was to continue after accept()
100     * errors.  But this leads us into lots of troubles
101     * because most of the errors are quite fatal.  For
102     * example, EMFILE can be caused by slow descriptor
103     * leaks (say in a 3rd party module, or libc).  It's
104     * foolish for us to continue after an EMFILE.  We also
105     * seem to tickle kernel bugs on some platforms which
106     * lead to never-ending loops here.  So it seems best
107     * to just exit in most cases.
108     */
109    switch (status) {
110#ifdef EPROTO
111        /* EPROTO on certain older kernels really means
112         * ECONNABORTED, so we need to ignore it for them.
113         * See discussion in new-httpd archives nh.9701
114         * search for EPROTO.
115         *
116         * Also see nh.9603, search for EPROTO:
117         * There is potentially a bug in Solaris 2.x x<6,
118         * and other boxes that implement tcp sockets in
119         * userland (i.e. on top of STREAMS).  On these
120         * systems, EPROTO can actually result in a fatal
121         * loop.  See PR#981 for example.  It's hard to
122         * handle both uses of EPROTO.
123         */
124        case EPROTO:
125#endif
126#ifdef ECONNABORTED
127        case ECONNABORTED:
128#endif
129#ifdef ETIMEDOUT
130        case ETIMEDOUT:
131#endif
132#ifdef EHOSTUNREACH
133        case EHOSTUNREACH:
134#endif
135#ifdef ENETUNREACH
136        case ENETUNREACH:
137#endif
138            break;
139#ifdef ENETDOWN
140        case ENETDOWN:
141            /*
142             * When the network layer has been shut down, there
143             * is not much use in simply exiting: the parent
144             * would simply re-create us (and we'd fail again).
145             * Use the CHILDFATAL code to tear the server down.
146             * @@@ Martin's idea for possible improvement:
147             * A different approach would be to define
148             * a new APEXIT_NETDOWN exit code, the reception
149             * of which would make the parent shutdown all
150             * children, then idle-loop until it detected that
151             * the network is up again, and restart the children.
152             * Ben Hyde noted that temporary ENETDOWN situations
153             * occur in mobile IP.
154             */
155            ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
156                         "apr_socket_accept: giving up.");
157            return APR_EGENERAL;
158#endif /*ENETDOWN*/
159
160        default:
161            ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf,
162                         "apr_socket_accept: (client socket)");
163            return APR_EGENERAL;
164    }
165    return status;
166}
167