a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe/* Licensed to the Apache Software Foundation (ASF) under one or more
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * contributor license agreements. See the NOTICE file distributed with
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * this work for additional information regarding copyright ownership.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * The ASF licenses this file to You under the Apache License, Version 2.0
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * (the "License"); you may not use this file except in compliance with
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * the License. You may obtain a copy of the License at
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * http://www.apache.org/licenses/LICENSE-2.0
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * Unless required by applicable law or agreed to in writing, software
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * distributed under the License is distributed on an "AS IS" BASIS,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * See the License for the specific language governing permissions and
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * limitations under the License.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe/* The purpose of this file is to store the code that MOST mpm's will need
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * this does not mean a function only goes into this file if every MPM needs
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * it. It means that if a function is needed by more than one MPM, and
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * future maintenance would be served by making the code common, then the
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * function belongs here.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * This is going in src/main because it is not platform specific, it is
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * specific to multi-process servers, but NOT to Unix. Which is why it
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * does not belong in src/os/unix
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
31eeb74b832eea054c7a42081c1afdeccd987e5etrawick#ifndef WIN32
31eeb74b832eea054c7a42081c1afdeccd987e5etrawick
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_thread_proc.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_signal.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_strings.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#define APR_WANT_STRFUNC
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_want.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_getopt.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_optional.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "apr_allocator.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "httpd.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "http_config.h"
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf#include "http_core.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "http_log.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "http_main.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "mpm_common.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "ap_mpm.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "ap_listen.h"
66b7d26b8c3164ddd1cd1ee1d0bec6cd5780301btrawick#include "scoreboard.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include "util_mutex.h"
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef HAVE_PWD_H
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include <pwd.h>
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef HAVE_GRP_H
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include <grp.h>
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#if APR_HAVE_UNISTD_H
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#include <unistd.h>
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf/* we know core's module_index is 0 */
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf#undef APLOG_MODULE_INDEX
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asf
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowetypedef enum {DO_NOTHING, SEND_SIGTERM, SEND_SIGKILL, GIVEUP} action_t;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowetypedef struct extra_process_t {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe struct extra_process_t *next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid_t pid;
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick ap_generation_t gen;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe} extra_process_t;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic extra_process_t *extras;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(void) ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
3a59bb90be3bc6246632384c3d885b875ae507d5sf extra_process_t *p = (extra_process_t *)ap_malloc(sizeof(extra_process_t));
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe p->next = extras;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe p->pid = pid;
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick p->gen = gen;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extras = p;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(int) ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *cur = extras;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *prev = NULL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe while (cur && cur->pid != pid) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe prev = cur;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur = cur->next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (cur) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (prev) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe prev->next = cur->next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extras = cur->next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
5dbf872a31f8e3734c75cc03a1956410445d843crpluem *old_gen = cur->gen;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe free(cur);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1; /* found */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* we don't know about any such process */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic int reclaim_one_pid(pid_t pid, action_t action)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_proc_t proc;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t waitret;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_exit_why_e why;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int status;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* Ensure pid sanity. */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pid < 1) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe proc.pid = pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe waitret = apr_proc_wait(&proc, &status, &why, APR_NOWAIT);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (waitret != APR_CHILD_NOTDONE) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (waitret == APR_CHILD_DONE)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_process_child_status(&proc, why, status);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe switch(action) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case DO_NOTHING:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case SEND_SIGTERM:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* ok, now it's being annoying */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_WARNING,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00045)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "child process %" APR_PID_T_FMT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe " still did not exit, "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "sending a SIGTERM",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe kill(pid, SIGTERM);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case SEND_SIGKILL:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_ERR,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00046)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "child process %" APR_PID_T_FMT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe " still did not exit, "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "sending a SIGKILL",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe kill(pid, SIGKILL);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case GIVEUP:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* gave it our best shot, but alas... If this really
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * is a child we are trying to kill and it really hasn't
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * exited, we will likely fail to bind to the port
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * after the restart.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_ERR,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00047)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "could not make child process %" APR_PID_T_FMT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe " exit, "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "attempting to continue anyway",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(void) ap_reclaim_child_processes(int terminate,
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankg ap_reclaim_callback_fn_t *mpm_callback)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_time_t waittime = 1024 * 16;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int i;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *cur_extra;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int not_dead_yet;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int max_daemons;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_time_t starttime = apr_time_now();
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* this table of actions and elapsed times tells what action is taken
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * at which elapsed time from starting the reclaim
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe struct {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe action_t action;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_time_t action_time;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe } action_table[] = {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {DO_NOTHING, 0}, /* dummy entry for iterations where we reap
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * children but take no action against
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * stragglers
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {SEND_SIGTERM, apr_time_from_sec(3)},
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {SEND_SIGTERM, apr_time_from_sec(5)},
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {SEND_SIGTERM, apr_time_from_sec(7)},
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {SEND_SIGKILL, apr_time_from_sec(9)},
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe {GIVEUP, apr_time_from_sec(10)}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe };
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int cur_action; /* index of action we decided to take this
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * iteration
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int next_action = 1; /* index of first real action */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe do {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_sleep(waittime);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* don't let waittime get longer than 1 second; otherwise, we don't
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * react quickly to the last child exiting, and taking action can
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * be delayed
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe waittime = waittime * 4;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (waittime > apr_time_from_sec(1)) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe waittime = apr_time_from_sec(1);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* see what action to take, if any */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (action_table[next_action].action_time <= apr_time_now() - starttime) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_action = next_action;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ++next_action;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_action = 0; /* nothing to do */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* now see who is done */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe not_dead_yet = 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe for (i = 0; i < max_daemons; ++i) {
66b7d26b8c3164ddd1cd1ee1d0bec6cd5780301btrawick process_score *ps = ap_get_scoreboard_process(i);
66b7d26b8c3164ddd1cd1ee1d0bec6cd5780301btrawick pid_t pid = ps->pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pid == 0) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe continue; /* not every scoreboard entry is in use */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (reclaim_one_pid(pid, action_table[cur_action].action)) {
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick mpm_callback(i, 0, 0);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ++not_dead_yet;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_extra = extras;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe while (cur_extra) {
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick ap_generation_t old_gen;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *next = cur_extra->next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick mpm_callback(-1, cur_extra->pid, old_gen);
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick }
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick else {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick AP_DEBUG_ASSERT(1 == 0);
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ++not_dead_yet;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_extra = next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#if APR_HAS_OTHER_CHILD
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe } while (not_dead_yet > 0 &&
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe action_table[cur_action].action != GIVEUP);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int i;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *cur_extra;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int max_daemons;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* now see who is done */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe for (i = 0; i < max_daemons; ++i) {
66b7d26b8c3164ddd1cd1ee1d0bec6cd5780301btrawick process_score *ps = ap_get_scoreboard_process(i);
66b7d26b8c3164ddd1cd1ee1d0bec6cd5780301btrawick pid_t pid = ps->pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pid == 0) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe continue; /* not every scoreboard entry is in use */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (reclaim_one_pid(pid, DO_NOTHING)) {
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick mpm_callback(i, 0, 0);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_extra = extras;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe while (cur_extra) {
925a6d92173ab96cdb0a8976c7aac13ef809e218trawick ap_generation_t old_gen;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe extra_process_t *next = cur_extra->next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick mpm_callback(-1, cur_extra->pid, old_gen);
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick }
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick else {
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick AP_DEBUG_ASSERT(1 == 0);
03ef97f46428f440af87766e2bdf98080fbfd4fatrawick }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe cur_extra = next;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe/* Before sending the signal to the pid this function verifies that
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * the pid is a member of the current process group; either using
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * apr_proc_wait(), where waitpid() guarantees to fail for non-child
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * processes; or by using getpgid() directly, if available. */
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(apr_status_t) ap_mpm_safe_kill(pid_t pid, int sig)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifndef HAVE_GETPGID
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_proc_t proc;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_exit_why_e why;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int status;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* Ensure pid sanity */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pid < 1) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_EINVAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe proc.pid = pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_proc_wait(&proc, &status, &why, APR_NOWAIT);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv == APR_CHILD_DONE) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* The child already died - log the termination status if
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * necessary: */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_process_child_status(&proc, why, status);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_EINVAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else if (rv != APR_CHILD_NOTDONE) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* The child is already dead and reaped, or was a bogus pid -
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * log this either way. */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf, APLOGNO(00048)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "cannot send signal %d to pid %ld (non-child or "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "already dead)", sig, (long)pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_EINVAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#else
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid_t pg;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* Ensure pid sanity. */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pid < 1) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_EINVAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim pg = getpgid(pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pg == -1) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* Process already dead... */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return errno;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (pg != getpgrp()) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, APLOGNO(00049)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "refusing to send signal %d to pid %ld outside "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "process group", sig, (long)pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_EINVAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return kill(pid, sig) ? errno : APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(int) ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why,
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankg int status)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int signum = status;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe const char *sigdesc;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* Child died... if it died due to a fatal error,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * we should simply bail out. The caller needs to
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * check for bad rc from us and exit, running any
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * appropriate cleanups.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * If the child died due to a resource shortage,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * the parent should limit the rate of forking
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (APR_PROC_CHECK_EXIT(why)) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (status == APEXIT_CHILDSICK) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return status;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (status == APEXIT_CHILDFATAL) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_ALERT,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00050)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "Child %" APR_PID_T_FMT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe " returned a Fatal error... Apache is exiting!",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid->pid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APEXIT_CHILDFATAL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (APR_PROC_CHECK_SIGNALED(why)) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sigdesc = apr_signal_description_get(signum);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe switch (signum) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case SIGTERM:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case SIGHUP:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case AP_SIG_GRACEFUL:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case SIGKILL:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe default:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (APR_PROC_CHECK_CORE_DUMP(why)) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_NOTICE,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00051)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "child pid %ld exit signal %s (%d), "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "possible coredump in %s",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe (long)pid->pid, sigdesc, signum,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_coredump_dir);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_NOTICE,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00052)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "child pid %ld exit signal %s (%d)",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe (long)pid->pid, sigdesc, signum);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweAP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *pod = apr_palloc(p, sizeof(**pod));
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_file_pipe_create_ex(&((*pod)->pod_in), &((*pod)->pod_out),
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe APR_WRITE_BLOCK, p);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_file_pipe_timeout_set((*pod)->pod_in, 0);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe (*pod)->p = p;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* close these before exec. */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_file_inherit_unset((*pod)->pod_in);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_file_inherit_unset((*pod)->pod_out);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweAP_DECLARE(apr_status_t) ap_mpm_pod_check(ap_pod_t *pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe char c;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_size_t len = 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_file_read(pod->pod_in, &c, &len);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if ((rv == APR_SUCCESS) && (len == 1)) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return AP_NORESTART;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweAP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_file_close(pod->pod_out);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_file_close(pod->pod_in);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic apr_status_t pod_signal_internal(ap_pod_t *pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe char char_of_death = '!';
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_size_t one = 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_file_write(pod->pod_out, &char_of_death, &one);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00053)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "write pipe_of_death");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimAP_DECLARE(apr_status_t) ap_mpm_podx_open(apr_pool_t *p, ap_pod_t **pod)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_status_t rv;
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim *pod = apr_palloc(p, sizeof(**pod));
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim if (rv != APR_SUCCESS) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim /*
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_file_pipe_timeout_set((*pod)->pod_in, 0);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim */
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim (*pod)->p = p;
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim /* close these before exec. */
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_file_inherit_unset((*pod)->pod_in);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_file_inherit_unset((*pod)->pod_out);
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return APR_SUCCESS;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimAP_DECLARE(int) ap_mpm_podx_check(ap_pod_t *pod)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim char c;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_os_file_t fd;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim int rc;
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim /* we need to surface EINTR so we'll have to grab the
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim * native file descriptor and do the OS read() ourselves
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim */
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_os_file_get(&fd, pod->pod_in);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rc = read(fd, &c, 1);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim if (rc == 1) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim switch (c) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim case AP_MPM_PODX_RESTART_CHAR:
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return AP_MPM_PODX_RESTART;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim case AP_MPM_PODX_GRACEFUL_CHAR:
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return AP_MPM_PODX_GRACEFUL;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return AP_MPM_PODX_NORESTART;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimAP_DECLARE(apr_status_t) ap_mpm_podx_close(ap_pod_t *pod)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_status_t rv;
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rv = apr_file_close(pod->pod_out);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim if (rv != APR_SUCCESS) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rv = apr_file_close(pod->pod_in);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim if (rv != APR_SUCCESS) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimstatic apr_status_t podx_signal_internal(ap_pod_t *pod,
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim ap_podx_restart_t graceful)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_status_t rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_size_t one = 1;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim char char_of_death = ' ';
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim switch (graceful) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim case AP_MPM_PODX_RESTART:
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim char_of_death = AP_MPM_PODX_RESTART_CHAR;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim break;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim case AP_MPM_PODX_GRACEFUL:
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim char_of_death = AP_MPM_PODX_GRACEFUL_CHAR;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim break;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim case AP_MPM_PODX_NORESTART:
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim break;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rv = apr_file_write(pod->pod_out, &char_of_death, &one);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim if (rv != APR_SUCCESS) {
dc09fa76d6e9783a9d7fd4eddc1f1dfedbaa743cjim ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(02404)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim "write pipe_of_death");
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return rv;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimAP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t * pod,
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim ap_podx_restart_t graceful)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim return podx_signal_internal(pod, graceful);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
7cc77074d12e6ed11433da96af0df1e1a27e9b3djimAP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t * pod, int num,
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim ap_podx_restart_t graceful)
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim{
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim int i;
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim apr_status_t rv = APR_SUCCESS;
982c7823d8ad8c593209d2d91cba5b38615f36a5jailletc
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim for (i = 0; i < num && rv == APR_SUCCESS; i++) {
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim rv = podx_signal_internal(pod, graceful);
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim }
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim}
7cc77074d12e6ed11433da96af0df1e1a27e9b3djim
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton/* This function connects to the server and sends enough data to
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton * ensure the child wakes up and processes a new connection. This
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton * permits the MPM to skip the poll when there is only one listening
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton * socket, because it provides a alternate way to unblock an accept()
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton * when the pod is used. */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic apr_status_t dummy_connection(ap_pod_t *pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
799ddc9f13bdcb23a662be8ec8276d44edd8b532jorton const char *data;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_socket_t *sock;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_pool_t *p;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_size_t len;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_listen_rec *lp;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* create a temporary pool for the socket. pconf stays around too long */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = apr_pool_create(&p, pod->p);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* If possible, find a listener which is configured for
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * plain-HTTP, not SSL; using an SSL port would either be
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * expensive to do correctly (performing a complete SSL handshake)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * or cause log spam by doing incorrectly (simply sending EOF). */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic lp = ap_listeners;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic while (lp && lp->protocol && strcasecmp(lp->protocol, "http") != 0) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic lp = lp->next;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (!lp) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic lp = ap_listeners;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
3c990331fc6702119e4f5b8ba9eae3021aea5265jim
a742cbb3e85669473b3233f30e3978bb6a20083cylavic rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (rv != APR_SUCCESS) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00054)
a742cbb3e85669473b3233f30e3978bb6a20083cylavic "get socket to connect to listener");
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_pool_destroy(p);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic return rv;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
3c990331fc6702119e4f5b8ba9eae3021aea5265jim
a742cbb3e85669473b3233f30e3978bb6a20083cylavic /* on some platforms (e.g., FreeBSD), the kernel won't accept many
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * queued connections before it starts blocking local connects...
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * we need to keep from blocking too long and instead return an error,
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * because the MPM won't want to hold up a graceful restart for a
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * long time
a742cbb3e85669473b3233f30e3978bb6a20083cylavic */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic rv = apr_socket_timeout_set(sock, apr_time_from_sec(3));
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (rv != APR_SUCCESS) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00055)
a742cbb3e85669473b3233f30e3978bb6a20083cylavic "set timeout on socket to connect to listener");
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_socket_close(sock);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_pool_destroy(p);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic return rv;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a742cbb3e85669473b3233f30e3978bb6a20083cylavic rv = apr_socket_connect(sock, lp->bind_addr);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (rv != APR_SUCCESS) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic int log_level = APLOG_WARNING;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (APR_STATUS_IS_TIMEUP(rv)) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic /* probably some server processes bailed out already and there
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * is nobody around to call accept and clear out the kernel
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * connection queue; usually this is not worth logging
a742cbb3e85669473b3233f30e3978bb6a20083cylavic */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic log_level = APLOG_DEBUG;
3c990331fc6702119e4f5b8ba9eae3021aea5265jim }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a742cbb3e85669473b3233f30e3978bb6a20083cylavic ap_log_error(APLOG_MARK, log_level, rv, ap_server_conf, APLOGNO(00056)
a742cbb3e85669473b3233f30e3978bb6a20083cylavic "connect to listener on %pI", lp->bind_addr);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_pool_destroy(p);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic return rv;
3c990331fc6702119e4f5b8ba9eae3021aea5265jim }
a742cbb3e85669473b3233f30e3978bb6a20083cylavic
a742cbb3e85669473b3233f30e3978bb6a20083cylavic if (lp->protocol && strcasecmp(lp->protocol, "https") == 0) {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic /* Send a TLS 1.0 close_notify alert. This is perhaps the
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * "least wrong" way to open and cleanly terminate an SSL
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * connection. It should "work" without noisy error logs if
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * the server actually expects SSLv3/TLSv1. With
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * SSLv23_server_method() OpenSSL's SSL_accept() fails
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * ungracefully on receipt of this message, since it requires
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * an 11-byte ClientHello message and this is too short. */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic static const unsigned char tls10_close_notify[7] = {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic '\x15', /* TLSPlainText.type = Alert (21) */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic '\x03', '\x01', /* TLSPlainText.version = {3, 1} */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic '\x00', '\x02', /* TLSPlainText.length = 2 */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic '\x01', /* Alert.level = warning (1) */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic '\x00' /* Alert.description = close_notify (0) */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic };
a742cbb3e85669473b3233f30e3978bb6a20083cylavic data = (const char *)tls10_close_notify;
a742cbb3e85669473b3233f30e3978bb6a20083cylavic len = sizeof(tls10_close_notify);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
a742cbb3e85669473b3233f30e3978bb6a20083cylavic else /* ... XXX other request types here? */ {
a742cbb3e85669473b3233f30e3978bb6a20083cylavic /* Create an HTTP request string. We include a User-Agent so
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * that adminstrators can track down the cause of the
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * odd-looking requests in their logs. A complete request is
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * used since kernel-level filtering may require that much
a742cbb3e85669473b3233f30e3978bb6a20083cylavic * data before returning from accept(). */
a742cbb3e85669473b3233f30e3978bb6a20083cylavic data = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ",
a742cbb3e85669473b3233f30e3978bb6a20083cylavic ap_get_server_description(),
a742cbb3e85669473b3233f30e3978bb6a20083cylavic " (internal dummy connection)\r\n\r\n", NULL);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic len = strlen(data);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic }
a742cbb3e85669473b3233f30e3978bb6a20083cylavic
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_socket_send(sock, data, &len);
a742cbb3e85669473b3233f30e3978bb6a20083cylavic apr_socket_close(sock);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_pool_destroy(p);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweAP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = pod_signal_internal(pod);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return dummy_connection(pod);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowevoid ap_mpm_pod_killpg(ap_pod_t *pod, int num)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int i;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv = APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* we don't write anything to the pod here... we assume
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * that the would-be reader of the pod has another way to
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * see that it is time to die once we wake it up
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * writing lots of things to the pod at once is very
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * problematic... we can fill the kernel pipe buffer and
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * be blocked until somebody consumes some bytes or
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * we hit a timeout... if we hit a timeout we can't just
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * keep trying because maybe we'll never successfully
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * write again... but then maybe we'll leave would-be
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * readers stranded (a number of them could be tied up for
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * a while serving time-consuming requests)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
7f6bfe455bd605a6401d2fcc9423972a24266b16jim /* Recall: we only worry about IDLE child processes here */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe for (i = 0; i < num && rv == APR_SUCCESS; i++) {
7f6bfe455bd605a6401d2fcc9423972a24266b16jim if (ap_scoreboard_image->servers[i][0].status != SERVER_READY ||
7f6bfe455bd605a6401d2fcc9423972a24266b16jim ap_scoreboard_image->servers[i][0].pid == 0) {
7f6bfe455bd605a6401d2fcc9423972a24266b16jim continue;
7f6bfe455bd605a6401d2fcc9423972a24266b16jim }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = dummy_connection(pod);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
0e67059cefafb553d274f83e1cbd182878623d57mturkstatic const char *dash_k_arg = NULL;
b761a57b4e63006c287823270876ab40d3212160covenerstatic const char *dash_k_arg_noarg = "noarg";
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic int send_signal(pid_t pid, int sig)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (kill(pid, sig) < 0) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL, APLOGNO(00057)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "sending signal to server");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweint ap_signal_server(int *exit_status, apr_pool_t *pconf)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe pid_t otherpid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe int running = 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe const char *status;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *exit_status = 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe rv = ap_read_pid(pconf, ap_pid_fname, &otherpid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv != APR_SUCCESS) {
2c2ced9d18f0b065f620b0ead09ba25e955c3cc7sf if (!APR_STATUS_IS_ENOENT(rv)) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL, APLOGNO(00058)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "Error retrieving pid file %s", ap_pid_fname);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00059)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "Remove it before continuing if it is corrupted.");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *exit_status = 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe status = "httpd (no pid file) not running";
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (kill(otherpid, 0) == 0) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe running = 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe status = apr_psprintf(pconf,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "httpd (pid %" APR_PID_T_FMT ") already "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "running", otherpid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe status = apr_psprintf(pconf,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "httpd (pid %" APR_PID_T_FMT "?) not running",
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe otherpid);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
b761a57b4e63006c287823270876ab40d3212160covener if (!strcmp(dash_k_arg, "start") || dash_k_arg == dash_k_arg_noarg) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (running) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe printf("%s\n", status);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!strcmp(dash_k_arg, "stop")) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!running) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe printf("%s\n", status);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe send_signal(otherpid, SIGTERM);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!strcmp(dash_k_arg, "restart")) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!running) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe printf("httpd not running, trying to start\n");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *exit_status = send_signal(otherpid, SIGHUP);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!strcmp(dash_k_arg, "graceful")) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!running) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe printf("httpd not running, trying to start\n");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *exit_status = send_signal(otherpid, AP_SIG_GRACEFUL);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!strcmp(dash_k_arg, "graceful-stop")) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!running) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe printf("%s\n", status);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *exit_status = send_signal(otherpid, AP_SIG_GRACEFUL_STOP);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowevoid ap_mpm_rewrite_args(process_rec *process)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_array_header_t *mpm_new_argv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_status_t rv;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_getopt_t *opt;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe char optbuf[3];
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe const char *optarg;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe mpm_new_argv = apr_array_make(process->pool, process->argc,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sizeof(const char **));
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *(const char **)apr_array_push(mpm_new_argv) = process->argv[0];
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_getopt_init(&opt, process->pool, process->argc, process->argv);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe opt->errfn = NULL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe optbuf[0] = '-';
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* option char returned by apr_getopt() will be stored in optbuf[1] */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe optbuf[2] = '\0';
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe while ((rv = apr_getopt(opt, "k:" AP_SERVER_BASEARGS,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe optbuf + 1, &optarg)) == APR_SUCCESS) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe switch(optbuf[1]) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe case 'k':
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!dash_k_arg) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (!strcmp(optarg, "start") || !strcmp(optarg, "stop") ||
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe !strcmp(optarg, "restart") || !strcmp(optarg, "graceful") ||
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe !strcmp(optarg, "graceful-stop")) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe dash_k_arg = optarg;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe break;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe default:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *(const char **)apr_array_push(mpm_new_argv) =
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_pstrdup(process->pool, optbuf);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (optarg) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *(const char **)apr_array_push(mpm_new_argv) = optarg;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* back up to capture the bad argument */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (rv == APR_BADCH || rv == APR_BADARG) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe opt->ind--;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe while (opt->ind < opt->argc) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe *(const char **)apr_array_push(mpm_new_argv) =
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_pstrdup(process->pool, opt->argv[opt->ind++]);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe process->argc = mpm_new_argv->nelts;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe process->argv = (const char * const *)mpm_new_argv->elts;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (NULL == dash_k_arg) {
b761a57b4e63006c287823270876ab40d3212160covener dash_k_arg = dash_k_arg_noarg;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
b761a57b4e63006c287823270876ab40d3212160covener
b761a57b4e63006c287823270876ab40d3212160covener APR_REGISTER_OPTIONAL_FN(ap_signal_server);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic pid_t parent_pid, my_pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic apr_pool_t *pconf;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#if AP_ENABLE_EXCEPTION_HOOK
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic int exception_hook_enabled;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wroweconst char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe const char *arg)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (err != NULL) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return err;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (cmd->server->is_virtual) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return "EnableExceptionHook directive not allowed in <VirtualHost>";
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (strcasecmp(arg, "on") == 0) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe exception_hook_enabled = 1;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else if (strcasecmp(arg, "off") == 0) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe exception_hook_enabled = 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe else {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return "parameter must be 'on' or 'off'";
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return NULL;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic void run_fatal_exception_hook(int sig)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_exception_info_t ei = {0};
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (exception_hook_enabled &&
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe geteuid() != 0 &&
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe my_pid != parent_pid) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ei.sig = sig;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ei.pid = my_pid;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_run_fatal_exception(&ei);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* AP_ENABLE_EXCEPTION_HOOK */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe/* handle all varieties of core dumping signals */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowestatic void sig_coredump(int sig)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_filepath_set(ap_coredump_dir, pconf);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(sig, SIG_DFL);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#if AP_ENABLE_EXCEPTION_HOOK
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe run_fatal_exception_hook(sig);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* linuxthreads issue calling getpid() here:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * This comparison won't match if the crashing thread is
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * some module's thread that runs in the parent process.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * The fallout, which is limited to linuxthreads:
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * The special log message won't be written when such a
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * thread in the parent causes the parent to crash.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (getpid() == parent_pid) {
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe ap_log_error(APLOG_MARK, APLOG_NOTICE,
185aa71728867671e105178b4c66fbc22b65ae26sf 0, ap_server_conf, APLOGNO(00060)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "seg fault or similar nasty error detected "
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe "in the parent process");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* XXX we can probably add some rudimentary cleanup code here,
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * like getting rid of the pid file. If any additional bad stuff
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * happens, we are protected from recursive errors taking down the
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * system since this function is no longer the signal handler GLA
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe }
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe kill(getpid(), sig);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe /* At this point we've got sig blocked, because we're still inside
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * the signal handler. When we leave the signal handler it will
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * be unblocked, and we'll take the signal... and coredump or whatever
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * is appropriate for this particular Unix. In addition the parent
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * will see the real signal we received -- whereas if we called
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe * abort() here, the parent would only see SIGABRT.
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(apr_status_t) ap_fatal_signal_child_setup(server_rec *s)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe my_pid = getpid();
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgAP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s,
b9c7c55b3a937fa1c72239003635a321e3ef4445rpluem apr_pool_t *in_pconf)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe{
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifndef NO_USE_SIGACTION
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe struct sigaction sa;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sigemptyset(&sa.sa_mask);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#if defined(SA_ONESHOT)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sa.sa_flags = SA_ONESHOT;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#elif defined(SA_RESETHAND)
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sa.sa_flags = SA_RESETHAND;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#else
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sa.sa_flags = 0;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe sa.sa_handler = sig_coredump;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGSEGV, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00061) "sigaction(SIGSEGV)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGBUS
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGBUS, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00062) "sigaction(SIGBUS)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGABORT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGABORT, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00063) "sigaction(SIGABORT)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGABRT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGABRT, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00064) "sigaction(SIGABRT)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGILL
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGILL, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00065) "sigaction(SIGILL)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGFPE
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe if (sigaction(SIGFPE, &sa, NULL) < 0)
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00066) "sigaction(SIGFPE)");
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#else /* NO_USE_SIGACTION */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGSEGV, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGBUS
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGBUS, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* SIGBUS */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGABORT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGABORT, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* SIGABORT */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGABRT
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGABRT, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* SIGABRT */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGILL
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGILL, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* SIGILL */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#ifdef SIGFPE
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe apr_signal(SIGFPE, sig_coredump);
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* SIGFPE */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe#endif /* NO_USE_SIGACTION */
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
b9c7c55b3a937fa1c72239003635a321e3ef4445rpluem pconf = in_pconf;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe parent_pid = my_pid = getpid();
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe return APR_SUCCESS;
a1a4e55fb7678118a8334019c18509c248b0c0b3wrowe}
31eeb74b832eea054c7a42081c1afdeccd987e5etrawick
31eeb74b832eea054c7a42081c1afdeccd987e5etrawick#endif /* WIN32 */