From 5b95d256387b45fbe33f7ee7890ae35afdd5c371 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Fri, 13 Mar 2020 14:34:18 +0000 Subject: [PATCH] * server/log.c (ap_log_pid): Use a temporary file, then rename once successfully written; also add error checking. Avoids startup failures if a previous httpd invocation crashed while writing the pidfile. Submitted by: Nicolas Carrier , jorton Github: closes #100, closes #69 PR: 63140 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1875153 13f79535-47bb-0310-9956-ffa450edef68 Signed-off-by: Nicolas Carrier --- server/log.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/server/log.c b/server/log.c index f0bde6e4b8..8d54b4e057 100644 --- a/server/log.c +++ b/server/log.c @@ -1598,6 +1598,9 @@ AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename) pid_t mypid; apr_status_t rv; const char *fname; + char *temp_fname; + apr_fileperms_t perms; + char pidstr[64]; if (!filename) { return; @@ -1626,19 +1629,35 @@ AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename) fname); } - if ((rv = apr_file_open(&pid_file, fname, - APR_WRITE | APR_CREATE | APR_TRUNCATE, - APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p)) - != APR_SUCCESS) { + temp_fname = apr_pstrcat(p, fname, ".XXXXXX", NULL); + rv = apr_file_mktemp(&pid_file, temp_fname, + APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, p); + if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00099) - "could not create %s", fname); + "could not create %s", temp_fname); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00100) "%s: could not log pid to file %s", ap_server_argv0, fname); exit(1); } - apr_file_printf(pid_file, "%" APR_PID_T_FMT APR_EOL_STR, mypid); - apr_file_close(pid_file); + + apr_snprintf(pidstr, sizeof pidstr, "%" APR_PID_T_FMT APR_EOL_STR, mypid); + + perms = APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD; + rv = apr_file_perms_set(temp_fname, perms); + if (rv == APR_SUCCESS) + rv = apr_file_write_full(pid_file, pidstr, strlen(pidstr), NULL); + if (rv == APR_SUCCESS) + rv = apr_file_close(pid_file); + if (rv == APR_SUCCESS) + rv = apr_file_rename(temp_fname, fname, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(10231) + "%s: Failed creating pid file %s", + ap_server_argv0, temp_fname); + exit(1); + } + saved_pid = mypid; } -- 2.25.2