]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_cgid: backport fix for segfault on (older) Solaris.
authorNick Kew <niq@apache.org>
Tue, 6 Jan 2009 19:20:58 +0000 (19:20 +0000)
committerNick Kew <niq@apache.org>
Tue, 6 Jan 2009 19:20:58 +0000 (19:20 +0000)
r729579, r731963, r731965
PR 39332

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@732067 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/generators/mod_cgid.c

diff --git a/CHANGES b/CHANGES
index 95584c19858d1f57c2b4e85f33df28d9f36282f8..85da92c82d626600dde31d36d52ee08749685e0f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.2.12
 
+  *) mod_cgid: fix segfault problem on solaris.
+     PR 39332 [Masaoki Kobayashi <masaoki techfirm.co.jp>, Jeff Trawick]
+
   *) mod_ldap: Avoid a segfault when result->rc is checked in uldap_connection_init
      when result is NULL. This could happen if LDAP initialization failed.
      PR 45994.  [Dan Poirier <poirier pobox.com>]
diff --git a/STATUS b/STATUS
index f8e1e51a5a2439049e5691e5b42074e7c415b195..89b1a8b2840656a4f0e759307d50c6581accc0f1 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -110,14 +110,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
     http://svn.apache.org/viewvc?view=rev&revision=730274
     +1: niq, rpluem
 
-  * mod_cgid: fix for segfault problem on solaris
-    PR 39332
-    http://svn.apache.org/viewvc?view=rev&revision=729579
-    +1: niq, rpluem
-    +1 with r731963 + r731965: trawick
-       (http://svn.apache.org/viewvc?view=rev&revision=731963,
-        http://svn.apache.org/viewvc?view=rev&revision=731965)
-
   * util_script (CGI): return 504 (Gateway timeout) rather than 500
     when a script times out before returning status line/headers.
     PR 42190
index 5ee3df074a94e891819b7291a2f73d9f72f70923..ca5309ed089276b80fbc7a7d693b03cbe18eef8d 100644 (file)
@@ -344,6 +344,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, apr_size_t);
+        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)
 {
@@ -472,31 +499,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;
         }
     }