]> granicus.if.org Git - apache/blobdiff - support/htcacheclean.c
Make sure the pidfile is deleted on close.
[apache] / support / htcacheclean.c
index 9d2a3a04f24bb4969682e475f1314e67e1900bda..43d5117dd2f021916e592b32c50fe0e9d468f428 100644 (file)
@@ -342,7 +342,7 @@ static int process_dir(char *path, apr_pool_t *pool)
             }
         }
 
-        /* this may look strange but apr_stat() may return errno which
+        /* this may look strange but apr_stat() may return an error which
          * is system dependent and there may be transient failures,
          * so just blindly retry for a short while
          */
@@ -708,8 +708,8 @@ static void usage(const char *error)
     }
     apr_file_printf(errfile,
     "%s -- program for cleaning the disk cache."                             NL
-    "Usage: %s [-Dvtrn] -pPATH -lLIMIT"                                      NL
-    "       %s [-nti] -dINTERVAL -pPATH -lLIMIT"                             NL
+    "Usage: %s [-Dvtrn] -pPATH -lLIMIT [-PPIDFILE]"                          NL
+    "       %s [-nti] -dINTERVAL -pPATH -lLIMIT [-PPIDFILE]"                 NL
                                                                              NL
     "Options:"                                                               NL
     "  -d   Daemonize and repeat cache cleaning every INTERVAL minutes."     NL
@@ -735,6 +735,8 @@ static void usage(const char *error)
                                                                              NL
     "  -p   Specify PATH as the root directory of the disk cache."           NL
                                                                              NL
+    "  -P   Specify PIDFILE as the file to write the pid to."                NL
+                                                                             NL
     "  -l   Specify LIMIT as the total disk cache size limit. Attach 'K'"    NL
     "       or 'M' to the number for specifying KBytes or MBytes."           NL
                                                                              NL
@@ -750,6 +752,12 @@ static void usage(const char *error)
 }
 #undef NL
 
+static void usage_repeated_arg(apr_pool_t *pool, char option) {
+    usage(apr_psprintf(pool, 
+                       "The option '%c' cannot be specified more than once",
+                       option));
+}
+
 /*
  * main
  */
@@ -764,7 +772,7 @@ int main(int argc, const char * const argv[])
     int retries, isdaemon, limit_found, intelligent, dowork;
     char opt;
     const char *arg;
-    char *proxypath, *path;
+    char *proxypath, *path, *pidfile;
     char errmsg[1024];
 
     interrupted = 0;
@@ -780,6 +788,7 @@ int main(int argc, const char * const argv[])
     intelligent = 0;
     previous = 0; /* avoid compiler warning */
     proxypath = NULL;
+    pidfile = NULL;
 
     if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) {
         return 1;
@@ -801,7 +810,7 @@ int main(int argc, const char * const argv[])
     apr_getopt_init(&o, pool, argc, argv);
 
     while (1) {
-        status = apr_getopt(o, "iDnvrtd:l:L:p:", &opt, &arg);
+        status = apr_getopt(o, "iDnvrtd:l:L:p:P:", &opt, &arg);
         if (status == APR_EOF) {
             break;
         }
@@ -812,42 +821,42 @@ int main(int argc, const char * const argv[])
             switch (opt) {
             case 'i':
                 if (intelligent) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 intelligent = 1;
                 break;
 
             case 'D':
                 if (dryrun) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 dryrun = 1;
                 break;
 
             case 'n':
                 if (benice) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 benice = 1;
                 break;
 
             case 't':
                 if (deldirs) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 deldirs = 1;
                 break;
 
             case 'v':
                 if (verbose) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 verbose = 1;
                 break;
 
             case 'r':
                 if (realclean) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 realclean = 1;
                 deldirs = 1;
@@ -855,7 +864,7 @@ int main(int argc, const char * const argv[])
 
             case 'd':
                 if (isdaemon) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 isdaemon = 1;
                 repeat = apr_atoi64(arg);
@@ -865,7 +874,7 @@ int main(int argc, const char * const argv[])
 
             case 'l':
                 if (limit_found) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 limit_found = 1;
 
@@ -898,20 +907,28 @@ int main(int argc, const char * const argv[])
 
             case 'p':
                 if (proxypath) {
-                    usage(apr_psprintf(pool, "The option '%c' cannot be specified more than once", (int)opt));
+                    usage_repeated_arg(pool, opt);
                 }
                 proxypath = apr_pstrdup(pool, arg);
                 if ((status = apr_filepath_set(proxypath, pool)) != APR_SUCCESS) {
                     usage(apr_psprintf(pool, "Could not set filepath to '%s': %s",
-                               proxypath, apr_strerror(status, errmsg, sizeof errmsg)));
+                                       proxypath, apr_strerror(status, errmsg, sizeof errmsg)));
+                }
+                break;
+
+            case 'P':
+                if (pidfile) {
+                    usage_repeated_arg(pool, opt);
                 }
+                pidfile = apr_pstrdup(pool, arg);
                 break;
+
             } /* switch */
         } /* else */
     } /* while */
 
     if (argc <= 1) {
-       usage(NULL);
+        usage(NULL);
     }
 
     if (o->ind != argc) {
@@ -940,7 +957,7 @@ int main(int argc, const char * const argv[])
 
     if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) {
         usage(apr_psprintf(pool, "Could not get the filepath: %s",
-                       apr_strerror(status, errmsg, sizeof errmsg)));
+                           apr_strerror(status, errmsg, sizeof errmsg)));
     }
     baselen = strlen(path);
 
@@ -951,6 +968,21 @@ int main(int argc, const char * const argv[])
     }
 #endif
 
+    if (pidfile) {
+        apr_file_t *file;
+        pid_t mypid = getpid();
+        if (APR_SUCCESS == (status = apr_file_open(&file, pidfile, APR_WRITE
+                | APR_CREATE | APR_TRUNCATE | APR_DELONCLOSE,
+                APR_UREAD | APR_UWRITE | APR_GREAD, pool))) {
+            apr_file_printf(file, "%" APR_PID_T_FMT APR_EOL_STR, mypid);
+        }
+        else if (!isdaemon) {
+            apr_file_printf(errfile,
+                    "Could not write the pid file '%s': %s" APR_EOL_STR,
+                    pidfile, apr_strerror(status, errmsg, sizeof errmsg));
+        }
+    }
+
     do {
         apr_pool_create(&instance, pool);