]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* server/log.c (ap_log_pid): Use a temporary file, then rename once
authorJoe Orton <jorton@apache.org>
Fri, 13 Mar 2020 14:34:18 +0000 (14:34 +0000)
committerJoe Orton <jorton@apache.org>
Fri, 13 Mar 2020 14:34:18 +0000 (14:34 +0000)
  successfully written; also add error checking.  Avoids startup
  failures if a previous httpd invocation crashed while writing the
  pidfile.

Submitted by: Nicolas Carrier <carrier.nicolas0 gmail.com>, 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

CHANGES
docs/log-message-tags/next-number
server/log.c

diff --git a/CHANGES b/CHANGES
index a2c48e60277aee28364fc015fc1f753b5e3e78fc..1b31b9c4455f64dfab022f44a53bb0362dae5e67 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) core: Use a temporary file when writing the pid file, avoiding
+     startup failure if an empty pidfile is left over from a
+     previous crashed or aborted invocation of httpd.  PR 63140.
+     [Nicolas Carrier <carrier.nicolas0 gmail.com>, Joe Orton]
+
   *) mod_http2: Fixes issue where mod_unique_id would generate non-unique request
      identifier under load, see <https://github.com/icing/mod_h2/issues/195>.
      [Michael Kaufmann, Stefan Eissing]
index 90cbf74d5b184c61b2af9ec898c3bddf7c774014..63b3cf1c42d7b5370aac9d41028a33f4abed458d 100644 (file)
@@ -1 +1 @@
-10231
+10232
index cb84024bbc736b420870d0f3d97ba61586d641e1..07fb358a2af5f118d6b9448e77b54465a8170c6a 100644 (file)
@@ -1524,6 +1524,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;
@@ -1552,19 +1555,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;
 }