]> granicus.if.org Git - apache/commitdiff
PR#39332: fix for segfault problem with mod_cgid on Solaris
authorNick Kew <niq@apache.org>
Sat, 27 Dec 2008 02:13:47 +0000 (02:13 +0000)
committerNick Kew <niq@apache.org>
Sat, 27 Dec 2008 02:13:47 +0000 (02:13 +0000)
Patch by Masaoki Kobayashi

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@729579 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/generators/mod_cgid.c

diff --git a/CHANGES b/CHANGES
index fde51eb253dcd5043a73acd0b979545d5921b084..683bbbb481a0b4e3fe8e367a4d80d63642ea13c7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 Changes with Apache 2.3.1
 [ When backported to 2.2.x, remove entry from this file ]
 
+ *) mod_cgid: fix segfault problem on solaris.
+    PR 39332 [Masaoki Kobayashi <masaoki techfirm.co.jp>]
+
  *) mod_proxy_scgi: Added. [AndrĂ© Malo]
 
  *) mod_cache: Introduce 'no-cache' per-request environment variable
@@ -17,7 +20,7 @@ Changes with Apache 2.3.1
      PR 46380 [Ruediger Pluem]
 
   *) scoreboard: Remove unused sb_type from process_score.
-     [Torsten Foertsch <torsten.foertsch@gmx.net>, Chris Darroch]
+     [Torsten Foertsch <torsten.foertsch gmx.net>, Chris Darroch]
 
   *) mod_ssl: Add SSLRenegBufferSize directive to allow changing the
      size of the buffer used for the request-body where necessary
index 7270652bac022841b59fc6bdacedd98d655950b3..0496e38028c8bf5bc976c589d67f4c195beacaf9 100644 (file)
@@ -342,6 +342,33 @@ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size)
     return APR_SUCCESS;
 }
 
+static apr_status_t sock_writev(int fd, request_rec *r, int count, ...)
+{
+    va_list ap;
+    int rc;
+    struct iovec *vec;
+    int i;
+    int total_bytes = 0;
+
+    vec = (struct iovec *)apr_palloc(r->pool, count * sizeof(struct iovec));
+    va_start(ap, count);
+    for(i=0; i<count; i++) {
+        vec[i].iov_base = va_arg(ap, caddr_t);
+        vec[i].iov_len  = va_arg(ap, int);
+        total_bytes += vec[i].iov_len;
+    }
+    va_end(ap);
+
+    do {
+        rc = writev(fd, vec, count);
+    } while (rc < 0 && errno == EINTR);
+    if (rc < 0) {
+        return errno;
+    }
+
+    return APR_SUCCESS;
+}
+
 static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
                             cgid_req_t *req)
 {
@@ -470,31 +497,31 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env,
     req.loglevel = r->server->loglevel;
 
     /* Write the request header */
-    if ((stat = sock_write(fd, &req, sizeof(req))) != APR_SUCCESS) {
-        return stat;
+    if (req.args_len) {
+        stat = sock_writev(fd, r, 5,
+                           &req, sizeof(req),
+                           r->filename, req.filename_len,
+                           argv0, req.argv0_len,
+                           r->uri, req.uri_len,
+                           r->args, req.args_len);
+    } else {
+        stat = sock_writev(fd, r, 4,
+                           &req, sizeof(req),
+                           r->filename, req.filename_len,
+                           argv0, req.argv0_len,
+                           r->uri, req.uri_len);
     }
 
-    /* Write filename, argv0, uri, and args */
-    if ((stat = sock_write(fd, r->filename, req.filename_len)) != APR_SUCCESS ||
-        (stat = sock_write(fd, argv0, req.argv0_len)) != APR_SUCCESS ||
-        (stat = sock_write(fd, r->uri, req.uri_len)) != APR_SUCCESS) {
+    if (stat != APR_SUCCESS) {
         return stat;
     }
-    if (req.args_len) {
-        if ((stat = sock_write(fd, r->args, req.args_len)) != APR_SUCCESS) {
-            return stat;
-        }
-    }
 
     /* write the environment variables */
     for (i = 0; i < req.env_count; i++) {
         apr_size_t curlen = strlen(env[i]);
 
-        if ((stat = sock_write(fd, &curlen, sizeof(curlen))) != APR_SUCCESS) {
-            return stat;
-        }
-
-        if ((stat = sock_write(fd, env[i], curlen)) != APR_SUCCESS) {
+        if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen),
+                                env[i], curlen)) != APR_SUCCESS) {
             return stat;
         }
     }