]> granicus.if.org Git - apache/blobdiff - modules/generators/mod_cgid.c
very minor tweaks:
[apache] / modules / generators / mod_cgid.c
index 900a8f4ca5ffa2d8df3355550726bfd3e1cbf125..c279b30e8fa2cb7f99ea684ccad50c9de17462e5 100644 (file)
 
 module AP_MODULE_DECLARE_DATA cgid_module; 
 
-static void cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server); 
+static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server); 
 static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec *r,
                        ap_filter_t *f, apr_bucket *head_ptr, apr_bucket **inserted_head);
 
@@ -146,8 +146,6 @@ static int is_scriptaliased(request_rec *r)
 #define DEFAULT_BUFBYTES 1024 
 #define DEFAULT_SOCKET "logs/cgisock"
 
-#define SHELL_PATH "/bin/sh"
-
 #define CGI_REQ 1
 #define SSI_REQ 2
 
@@ -238,10 +236,10 @@ static void cgid_maint(int reason, void *data, apr_wait_t status)
         case APR_OC_REASON_LOST:
             /* it would be better to restart just the cgid child
              * process but for now we'll gracefully restart the entire 
-             * server by sending SIGWINCH to ourself, the httpd parent
-             * process
+             * server by sending AP_SIG_GRACEFUL to ourself, the httpd 
+             * parent process
              */
-            kill(getpid(), SIGWINCH);
+            kill(getpid(), AP_SIG_GRACEFUL);
             break;
         case APR_OC_REASON_RESTART:
             apr_proc_other_child_unregister(data);
@@ -507,11 +505,11 @@ static int cgid_server(void *data)
         char *argv0; 
         char **env; 
         const char * const *argv; 
-        apr_int32_t   in_pipe  = APR_CHILD_BLOCK;
-        apr_int32_t   out_pipe = APR_CHILD_BLOCK;
-        apr_int32_t   err_pipe = APR_CHILD_BLOCK;
-        apr_cmdtype_e cmd_type = APR_PROGRAM;
-        request_rec *r; 
+        apr_int32_t in_pipe;
+        apr_int32_t out_pipe;
+        apr_int32_t err_pipe;
+        apr_cmdtype_e cmd_type;
+        request_rec *r;
         apr_procattr_t *procattr = NULL;
         apr_proc_t *procnew = NULL;
         apr_file_t *inout;
@@ -524,7 +522,7 @@ static int cgid_server(void *data)
             if (errno != EINTR) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, errno, 
                              (server_rec *)data,
-                             "Error accepting on cgid socket.");
+                             "Error accepting on cgid socket");
             }
             continue;
         }
@@ -542,6 +540,12 @@ static int cgid_server(void *data)
             err_pipe = APR_NO_PIPE;
             cmd_type = APR_SHELLCMD;
         }
+        else {
+            in_pipe  = APR_CHILD_BLOCK;
+            out_pipe = APR_CHILD_BLOCK;
+            err_pipe = APR_CHILD_BLOCK;
+            cmd_type = APR_PROGRAM;
+        }
 
         if (((rc = apr_procattr_create(&procattr, ptrans)) != APR_SUCCESS) ||
             ((req_type == CGI_REQ) && 
@@ -566,8 +570,8 @@ static int cgid_server(void *data)
         else {
             argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args);
 
-           /* We want to sd2 close for new CGI process too.
-            * If it's remained open it'll make ap_pass_brigade() block
+           /* We want to close sd2 for the new CGI process too.
+            * If it is left open it'll make ap_pass_brigade() block
             * waiting for EOF if CGI forked something running long.
             * close(sd2) here should be okay, as CGI channel
             * is already dup()ed by apr_procattr_child_{in,out}_set()
@@ -589,7 +593,7 @@ static int cgid_server(void *data)
     return -1; 
 } 
 
-static void cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, 
+static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, 
                       server_rec *main_server) 
 { 
     pid_t pid; 
@@ -611,10 +615,10 @@ static void cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
         for (m = ap_preloaded_modules; *m != NULL; m++)
             total_modules++;
 
-
         if ((pid = fork()) < 0) {
             ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, 
                          "Couldn't spawn cgid daemon process"); 
+            /* XXX should we return a failure here ? */
         }
         else if (pid == 0) {
             apr_pool_create(&pcgi, p); 
@@ -640,6 +644,7 @@ static void cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
             cgid_pfn_reg_with_ssi("exec", handle_exec);
         }
     }
+    return OK;
 } 
 
 static void *create_cgid_config(apr_pool_t *p, server_rec *s) 
@@ -667,7 +672,7 @@ static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg)
     cgid_server_conf *conf = ap_get_module_config(s->module_config,
                                                   &cgid_module); 
 
-    conf->logname = arg; 
+    conf->logname = ap_server_root_relative(cmd->pool, arg);
     return NULL; 
 } 
 
@@ -726,10 +731,11 @@ static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret,
     ap_log_rerror(APLOG_MARK, log_flags, rv, r, 
                 "%s: %s", error, r->filename); 
 
+    /* XXX Very expensive mainline case! Open, then getfileinfo! */
     if (!conf->logname || 
-        ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) 
+        ((stat(conf->logname, &finfo) == 0) 
          && (finfo.st_size > conf->logbytes)) || 
-         (apr_file_open(&f, ap_server_root_relative(r->pool, conf->logname),
+         (apr_file_open(&f, conf->logname,
                   APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { 
         return ret; 
     } 
@@ -750,24 +756,27 @@ static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret,
 static int log_script(request_rec *r, cgid_server_conf * conf, int ret, 
                   char *dbuf, const char *sbuf, apr_file_t *script_in, apr_file_t *script_err) 
 { 
-    apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); 
-    apr_table_entry_t *hdrs = (apr_table_entry_t *) hdrs_arr->elts; 
+    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); 
+    const apr_table_entry_t *hdrs = (apr_table_entry_t *) hdrs_arr->elts; 
     char argsbuffer[HUGE_STRING_LEN]; 
     apr_file_t *f = NULL; 
     int i; 
     struct stat finfo; 
     char time_str[APR_CTIME_LEN];
 
+    /* XXX Very expensive mainline case! Open, then getfileinfo! */
     if (!conf->logname || 
-        ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) 
+        ((stat(conf->logname, &finfo) == 0) 
          && (finfo.st_size > conf->logbytes)) || 
-         (apr_file_open(&f, ap_server_root_relative(r->pool, conf->logname)
+         (apr_file_open(&f, conf->logname
                   APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { 
         /* Soak up script output */ 
-        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_in) == 0) 
+        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                             script_in) == APR_SUCCESS) 
             continue; 
         if (script_err) {
-            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_err) == 0) 
+            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                                 script_err) == APR_SUCCESS) 
                 continue; 
         }
         return ret; 
@@ -793,7 +802,7 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret,
 
     apr_file_puts("%response\n", f); 
     hdrs_arr = apr_table_elts(r->err_headers_out); 
-    hdrs = (apr_table_entry_t *) hdrs_arr->elts; 
+    hdrs = (const apr_table_entry_t *) hdrs_arr->elts; 
 
     for (i = 0; i < hdrs_arr->nelts; ++i) { 
         if (!hdrs[i].key) 
@@ -804,19 +813,22 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret,
     if (sbuf && *sbuf) 
         apr_file_printf(f, "%s\n", sbuf); 
 
-    if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_in) == 0) { 
+    if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_in) == APR_SUCCESS) { 
         apr_file_puts("%stdout\n", f); 
         apr_file_puts(argsbuffer, f); 
-        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_in) == 0) 
+        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                             script_in) == APR_SUCCESS) 
             apr_file_puts(argsbuffer, f); 
         apr_file_puts("\n", f); 
     } 
 
     if (script_err) {
-        if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_err) == 0) { 
+        if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                          script_err) == APR_SUCCESS) { 
             apr_file_puts("%stderr\n", f); 
             apr_file_puts(argsbuffer, f); 
-            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_err) == 0) 
+            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                                 script_err) == APR_SUCCESS) 
                 apr_file_puts(argsbuffer, f); 
             apr_file_puts("\n", f); 
         } 
@@ -990,7 +1002,8 @@ static int cgid_handler(request_rec *r)
         if (location && location[0] == '/' && r->status == 200) { 
 
             /* Soak up all the script output */ 
-            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, tempsock) > 0) { 
+            while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                                 tempsock) == APR_SUCCESS) { 
                 continue; 
             } 
             /* This redirect needs to be a GET no matter what the original 
@@ -1086,20 +1099,26 @@ static int include_cgi(char *s, request_rec *r, ap_filter_t *next,
 
     rr_status = ap_run_sub_req(rr);
     if (ap_is_HTTP_REDIRECT(rr_status)) {
-        apr_size_t len_loc, h_wrt;
+        apr_size_t len_loc;
         const char *location = apr_table_get(rr->headers_out, "Location");
 
         location = ap_escape_html(rr->pool, location);
         len_loc = strlen(location);
 
+        /* XXX: if most of this stuff is going to get copied anyway,
+         * it'd be more efficient to pstrcat it into a single pool buffer
+         * and a single pool bucket */
+
         tmp_buck = apr_bucket_immortal_create("<A HREF=\"", sizeof("<A HREF=\""));
         APR_BUCKET_INSERT_BEFORE(head_ptr, tmp_buck);
-        tmp2_buck = apr_bucket_heap_create(location, len_loc, 1, &h_wrt);
+        tmp2_buck = apr_bucket_heap_create(location, len_loc, 1);
         APR_BUCKET_INSERT_BEFORE(head_ptr, tmp2_buck);
+        /* XXX: this looks like a bug: should be sizeof - 1 */
         tmp2_buck = apr_bucket_immortal_create("\">", sizeof("\">"));
         APR_BUCKET_INSERT_BEFORE(head_ptr, tmp2_buck);
-        tmp2_buck = apr_bucket_heap_create(location, len_loc, 1, &h_wrt);
+        tmp2_buck = apr_bucket_heap_create(location, len_loc, 1);
         APR_BUCKET_INSERT_BEFORE(head_ptr, tmp2_buck);
+        /* XXX: this looks like a bug: should be sizeof - 1 */
         tmp2_buck = apr_bucket_immortal_create("</A>", sizeof("</A>"));
         APR_BUCKET_INSERT_BEFORE(head_ptr, tmp2_buck);
 
@@ -1149,7 +1168,8 @@ static int include_cmd(include_ctx_t *ctx, apr_bucket_brigade **bb, char *comman
     char **env; 
     const char *location; 
     int sd;
-    int retval; 
+    apr_status_t rc = APR_SUCCESS; 
+    int retval;
     apr_bucket_brigade *bcgi;
     apr_bucket *b;
     struct sockaddr_un unix_addr;
@@ -1174,7 +1194,10 @@ static int include_cmd(include_ctx_t *ctx, apr_bucket_brigade **bb, char *comman
                                    "unable to connect to cgi daemon");
     } 
 
-    SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next);
+    SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next, rc);
+    if (rc != APR_SUCCESS) {
+        return rc;
+    }
 
     send_req(sd, r, command, env, SSI_REQ); 
 
@@ -1192,7 +1215,8 @@ static int include_cmd(include_ctx_t *ctx, apr_bucket_brigade **bb, char *comman
         char argsbuffer[HUGE_STRING_LEN]; 
 
         /* Soak up all the script output */ 
-        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, tempsock) > 0) { 
+        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, 
+                             tempsock) == APR_SUCCESS) { 
             continue; 
         } 
         /* This redirect needs to be a GET no matter what the original 
@@ -1265,8 +1289,14 @@ static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec
                     /* just in case some stooge changed directories */
                 }
                 else if (!strcmp(tag, "cgi")) {
+                    apr_status_t retval = APR_SUCCESS;
+
                     cgid_pfn_ps(r, tag_val, parsed_string, sizeof(parsed_string), 0);
-                    SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next);
+                    SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next, retval);
+                    if (retval != APR_SUCCESS) {
+                        return retval;
+                    }
+
                     if (include_cgi(parsed_string, r, f->next, head_ptr, inserted_head) == -1) {
                         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
                                     "invalid CGI ref \"%s\" in %s", tag_val, file);