--- httpd-2.4.26/server/mpm/prefork/prefork.c.sigint 2017-06-05 15:09:49.000000000 +0300 +++ httpd-2.4.26/server/mpm/prefork/prefork.c 2017-06-20 17:21:20.643408107 +0300 @@ -203,40 +203,43 @@ ap_scoreboard_image->parent[childnum].pid, ap_scoreboard_image->parent[childnum].generation, childnum, MPM_CHILD_EXITED); ap_scoreboard_image->parent[childnum].pid = 0; } static void prefork_note_child_started(int slot, pid_t pid) { ap_scoreboard_image->parent[slot].pid = pid; ap_run_child_status(ap_server_conf, ap_scoreboard_image->parent[slot].pid, retained->mpm->my_generation, slot, MPM_CHILD_STARTED); } /* a clean exit from a child with proper cleanup */ static void clean_child_exit(int code) __attribute__ ((noreturn)); static void clean_child_exit(int code) { retained->mpm->mpm_state = AP_MPMQ_STOPPING; + apr_signal(SIGHUP, SIG_IGN); + apr_signal(SIGTERM, SIG_IGN); + if (pchild) { apr_pool_destroy(pchild); } if (one_process) { prefork_note_child_killed(/* slot */ 0, 0, 0); } ap_mpm_pod_close(my_bucket->pod); chdir_for_gprof(); exit(code); } static apr_status_t accept_mutex_on(void) { apr_status_t rv = apr_proc_mutex_lock(my_bucket->mutex); if (rv != APR_SUCCESS) { const char *msg = "couldn't grab the accept mutex"; if (retained->mpm->my_generation != @@ -682,40 +685,47 @@ my_bucket = &all_buckets[bucket]; #ifdef HAVE_BINDPROCESSOR /* by default AIX binds to a single processor * this bit unbinds children which will then bind to another cpu */ int status = bindprocessor(BINDPROCESS, (int)getpid(), PROCESSOR_CLASS_ANY); if (status != OK) { ap_log_error(APLOG_MARK, APLOG_DEBUG, errno, ap_server_conf, APLOGNO(00160) "processor unbind failed"); } #endif RAISE_SIGSTOP(MAKE_CHILD); AP_MONCONTROL(1); /* Disable the parent's signal handlers and set up proper handling in * the child. */ apr_signal(SIGHUP, just_die); apr_signal(SIGTERM, just_die); + /* Ignore SIGINT in child. This fixes race-condition in signals + * handling when httpd is runnning on foreground and user hits ctrl+c. + * In this case, SIGINT is sent to all children followed by SIGTERM + * from the main process, which interrupts the SIGINT handler and + * leads to inconsistency. + */ + apr_signal(SIGINT, SIG_IGN); /* The child process just closes listeners on AP_SIG_GRACEFUL. * The pod is used for signalling the graceful restart. */ apr_signal(AP_SIG_GRACEFUL, stop_listening); child_main(slot, bucket); } ap_scoreboard_image->parent[slot].bucket = bucket; prefork_note_child_started(slot, pid); return 0; } /* start up a bunch of children */ static void startup_children(int number_to_start) { int i; for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {