Index: server/log.c =================================================================== --- server/log.c (revision 775288) +++ server/log.c (working copy) @@ -265,7 +265,8 @@ * stderr for the child will be the same as the stdout of the parent. * Otherwise the child will inherit the stderr from the parent. */ static int log_child(apr_pool_t *p, const char *progname, - apr_file_t **fpin, int dummy_stderr) + apr_file_t **fpin, apr_cmdtype_e cmdtype, + int dummy_stderr) { /* Child process code for 'ErrorLog "|..."'; * may want a common framework for this, since I expect it will @@ -277,8 +278,7 @@ apr_file_t *outfile, *errfile; if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) - && ((rc = apr_procattr_cmdtype_set(procattr, - APR_SHELLCMD_ENV)) == APR_SUCCESS) + && ((rc = apr_procattr_cmdtype_set(procattr, cmdtype)) == APR_SUCCESS) && ((rc = apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_NO_PIPE, @@ -325,12 +325,26 @@ if (*s->error_fname == '|') { apr_file_t *dummy = NULL; + apr_cmdtype_e cmdtype = APR_SHELLCMD_ENV; + fname = s->error_fname + 1; + /* In 2.4 favor PROGRAM_ENV, accept "||prog" syntax for compatibility + * and "|$cmd" to override the default. + * Any 2.2 backport would continue to favor SHELLCMD_ENV so there + * accept "||prog" to override, and "|$cmd" to ease conversion. + */ + if (*fname == '|') { + cmdtype = APR_PROGRAM_ENV; + ++fname; + } + if (*fname == '$') + ++fname; + /* Spawn a new child logger. If this is the main server_rec, * the new child must use a dummy stderr since the current * stderr might be a pipe to the old logger. Otherwise, the * child inherits the parents stderr. */ - rc = log_child(p, s->error_fname + 1, &dummy, is_main); + rc = log_child(p, fname, &dummy, cmdtype, is_main); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start ErrorLog process"); @@ -883,12 +897,12 @@ apr_status_t status; if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) || - ((status = apr_procattr_cmdtype_set(procattr, - APR_SHELLCMD_ENV)) != APR_SUCCESS) || + ((status = apr_procattr_cmdtype_set(procattr, pl->cmdtype)) + != APR_SUCCESS) || ((status = apr_procattr_child_in_set(procattr, ap_piped_log_read_fd(pl), ap_piped_log_write_fd(pl))) - != APR_SUCCESS) || + != APR_SUCCESS) || ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn)) != APR_SUCCESS) || ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) { @@ -1012,7 +1026,9 @@ } -AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) +AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, + const char *program, + apr_cmdtype_e cmdtype) { piped_log *pl; @@ -1020,6 +1036,7 @@ pl->p = p; pl->program = apr_pstrdup(p, program); pl->pid = NULL; + pl->cmdtype = cmdtype; if (apr_file_pipe_create(&ap_piped_log_read_fd(pl), &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) { return NULL; @@ -1045,13 +1062,15 @@ return APR_SUCCESS; } -AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) +AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, + const char *program, + apr_cmdtype_e cmdtype) { piped_log *pl; apr_file_t *dummy = NULL; int rc; - rc = log_child(p, program, &dummy, 0); + rc = log_child(p, program, &dummy, cmdtype, 0); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start piped log process"); @@ -1069,6 +1088,26 @@ #endif +AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, + const char *program) +{ + apr_cmdtype_e cmdtype = APR_SHELLCMD_ENV; + + /* In 2.4 favor PROGRAM_ENV, accept "||prog" syntax for compatibility + * and "|$cmd" to override the default. + * Any 2.2 backport would continue to favor SHELLCMD_ENV so there + * accept "||prog" to override, and "|$cmd" to ease conversion. + */ + if (*program == '|') { + cmdtype = APR_PROGRAM_ENV; + ++program; + } + if (*program == '$') + ++program; + + return ap_open_piped_log_ex(p, program, cmdtype); +} + AP_DECLARE(void) ap_close_piped_log(piped_log *pl) { apr_pool_cleanup_run(pl->p, pl, piped_log_cleanup); Index: include/ap_mmn.h =================================================================== --- include/ap_mmn.h (revision 775288) +++ include/ap_mmn.h (working copy) @@ -136,6 +136,8 @@ * 20051115.20 (2.2.11) Add ap_proxy_buckets_lifetime_transform to mod_proxy.h * 20051115.21 (2.2.11) Export mod_rewrite.h in the public API * 20051115.22 (2.2.12) Add ap_escape_html2 API, with additional option + * 20051115.23 (2.2.12) Add ap_open_piped_log_ex API, with cmdtype option, + * and conditional cmdtype member of piped_log struct */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -143,7 +145,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 21 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 23 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a Index: include/http_log.h =================================================================== --- include/http_log.h (revision 775288) +++ include/http_log.h (working copy) @@ -289,6 +289,8 @@ char *program; /** The pid of the logging process */ apr_proc_t *pid; + /** How to reinvoke program when it must be replaced */ + apr_cmdtype_e cmdtype; #endif }; @@ -297,10 +299,23 @@ * @param p The pool to allocate out of * @param program The program to run in the logging process * @return The piped log structure + * @tip The log program is invoked as APR_SHELLCMD_ENV, + * @see ap_open_piped_log_ex to modify this behavior */ AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program); /** + * Open the piped log process specifying the execution choice for program + * @param p The pool to allocate out of + * @param program The program to run in the logging process + * @param cmdtype How to invoke program, e.g. APR_PROGRAM, APR_SHELLCMD_ENV, etc + * @return The piped log structure + */ +AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, + const char *program, + apr_cmdtype_e cmdtype); + +/** * Close the piped log and kill the logging process * @param pl The piped log structure */