Author: markt
Date: Wed Dec 30 10:45:34 2009
New Revision: 894580

URL: http://svn.apache.org/viewvc?rev=894580&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48454
Give the stderr reader a chance to finish before terminating the CGI process. 
This avoids "Bad file descriptor" errors. The period to wait is configurable.
Based on a patch by Markus Grieder

Modified:
    tomcat/trunk/conf/web.xml
    tomcat/trunk/java/org/apache/catalina/servlets/CGIServlet.java
    tomcat/trunk/webapps/docs/cgi-howto.xml

Modified: tomcat/trunk/conf/web.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/conf/web.xml?rev=894580&r1=894579&r2=894580&view=diff
==============================================================================
--- tomcat/trunk/conf/web.xml (original)
+++ tomcat/trunk/conf/web.xml Wed Dec 30 10:45:34 2009
@@ -301,6 +301,10 @@
   <!--                                                                      -->
   <!--   passShellEnvironment Should the shell environment variables (if    -->
   <!--                        any) be passed to the CGI script? [false]     -->
+  <!--                                                                      -->
+  <!--   stderrTimeout        The time (in milliseconds) to wait for the    -->
+  <!--                        reading of stdErr to complete before          -->
+  <!--                        terminating the CGI process. [2000]           -->
 
 <!--
     <servlet>

Modified: tomcat/trunk/java/org/apache/catalina/servlets/CGIServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/CGIServlet.java?rev=894580&r1=894579&r2=894580&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/CGIServlet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/CGIServlet.java Wed Dec 30 
10:45:34 2009
@@ -261,8 +261,14 @@
     private String cgiExecutable = "perl";
     
     /** the encoding to use for parameters */
-    private String parameterEncoding = System.getProperty("file.encoding",
-                                                          "UTF-8");
+    private String parameterEncoding =
+        System.getProperty("file.encoding", "UTF-8");
+
+    /**
+     * The time (in milliseconds) to wait for the reading of stdErr to complete
+     * before terminating the CGI process.
+     */
+    private long stderrTimeout = 2000;
 
     /** object used to ensure multiple threads don't try to expand same file */
     static Object expandFileLock = new Object();
@@ -309,6 +315,11 @@
             parameterEncoding = 
getServletConfig().getInitParameter("parameterEncoding");
         }
 
+        if (getServletConfig().getInitParameter("stderrTimeout") != null) {
+            stderrTimeout = Long.parseLong(getServletConfig().getInitParameter(
+                    "stderrTimeout"));
+        }
+
     }
 
 
@@ -1588,6 +1599,7 @@
             BufferedReader cgiHeaderReader = null;
             InputStream cgiOutput = null;
             BufferedReader commandsStdErr = null;
+            Thread errReaderThread = null;
             BufferedOutputStream commandsStdIn = null;
             Process proc = null;
             int bufRead = -1;
@@ -1645,12 +1657,13 @@
                     (new InputStreamReader(proc.getErrorStream()));
                 final BufferedReader stdErrRdr = commandsStdErr ;
 
-                new Thread() {
+                errReaderThread = new Thread() {
                     @Override
                     public void run () {
                         sendToLog(stdErrRdr) ;
                     }
-                }.start() ;
+                };
+                errReaderThread.start();
 
                 InputStream cgiHeaderStream =
                     new HTTPHeaderInputStream(proc.getInputStream());
@@ -1743,6 +1756,14 @@
                         log ("Exception closing output stream " + ioe);
                     }
                 }
+                // Make sure the error stream reader has finished
+                if (errReaderThread != null) {
+                    try {
+                        errReaderThread.join(stderrTimeout);
+                    } catch (InterruptedException e) {
+                        log ("Interupted waiting for stderr reader thread");
+                    }
+                }
                 if (debug > 4) {
                     log ("Running finally block");
                 }

Modified: tomcat/trunk/webapps/docs/cgi-howto.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/cgi-howto.xml?rev=894580&r1=894579&r2=894580&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/cgi-howto.xml (original)
+++ tomcat/trunk/webapps/docs/cgi-howto.xml Wed Dec 30 10:45:34 2009
@@ -83,6 +83,9 @@
 <li><strong>passShellEnvironment</strong> - Should the shell environment
 variables (if any) be passed to the CGI script? Default is
 <code>false</code>.</li>
+<li><strong>stderrTimeout</strong> - The time (in milliseconds) to wait for
+the reading of stderr to complete before terminating the CGI process? Default
+is 2000.</li>
 </ul>
 </p>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to