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 "pod.h" 18 19#if APR_HAVE_UNISTD_H 20#include <unistd.h> 21#endif 22 23AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t * p, ap_pod_t ** pod) 24{ 25 apr_status_t rv; 26 27 *pod = apr_palloc(p, sizeof(**pod)); 28 rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); 29 if (rv != APR_SUCCESS) { 30 return rv; 31 } 32/* 33 apr_file_pipe_timeout_set((*pod)->pod_in, 0); 34*/ 35 (*pod)->p = p; 36 37 /* close these before exec. */ 38 apr_file_inherit_unset((*pod)->pod_in); 39 apr_file_inherit_unset((*pod)->pod_out); 40 41 return APR_SUCCESS; 42} 43 44AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t * pod) 45{ 46 char c; 47 apr_os_file_t fd; 48 int rc; 49 50 /* we need to surface EINTR so we'll have to grab the 51 * native file descriptor and do the OS read() ourselves 52 */ 53 apr_os_file_get(&fd, pod->pod_in); 54 rc = read(fd, &c, 1); 55 if (rc == 1) { 56 switch (c) { 57 case RESTART_CHAR: 58 return AP_RESTART; 59 case GRACEFUL_CHAR: 60 return AP_GRACEFUL; 61 } 62 } 63 return AP_NORESTART; 64} 65 66AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t * pod) 67{ 68 apr_status_t rv; 69 70 rv = apr_file_close(pod->pod_out); 71 if (rv != APR_SUCCESS) { 72 return rv; 73 } 74 75 rv = apr_file_close(pod->pod_in); 76 if (rv != APR_SUCCESS) { 77 return rv; 78 } 79 return rv; 80} 81 82static apr_status_t pod_signal_internal(ap_pod_t * pod, int graceful) 83{ 84 apr_status_t rv; 85 char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; 86 apr_size_t one = 1; 87 88 rv = apr_file_write(pod->pod_out, &char_of_death, &one); 89 if (rv != APR_SUCCESS) { 90 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, 91 "write pipe_of_death"); 92 } 93 return rv; 94} 95 96AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t * pod, int graceful) 97{ 98 return pod_signal_internal(pod, graceful); 99} 100 101AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t * pod, int num, int graceful) 102{ 103 int i; 104 apr_status_t rv = APR_SUCCESS; 105 106 for (i = 0; i < num && rv == APR_SUCCESS; i++) { 107 rv = pod_signal_internal(pod, graceful); 108 } 109} 110