Handle ${run} returning more data than OS pipe buffer size.
authorPhil Pennock <pdp@exim.org>
Sun, 28 Aug 2011 20:27:01 +0000 (16:27 -0400)
committerPhil Pennock <pdp@exim.org>
Sun, 28 Aug 2011 20:27:01 +0000 (16:27 -0400)
Patch from Holger Weiß.
fixes bug 1131

doc/doc-txt/ChangeLog
src/src/expand.c

index a8e886836f4b85dfa5a668ecd6c7ef7ecd6382c4..23a18cf2f9b93f65d4ecf0d29c118308fcc2e667 100644 (file)
@@ -104,7 +104,10 @@ PP/06 Stop make process more reliably on build failure.
       Bugzilla 1087.  Patch from Heiko Schlittermann.
 
 PP/07 Make maildir_use_size_file an _expandable_ boolean.
       Bugzilla 1087.  Patch from Heiko Schlittermann.
 
 PP/07 Make maildir_use_size_file an _expandable_ boolean.
-      Bugzilla 1089.  Patch Heiko Schlittermann.
+      Bugzilla 1089.  Patch from Heiko Schlittermann.
+
+PP/08 Handle ${run} returning more data than OS pipe buffer size.
+      Bugzilla 1131.  Patch from Holger Weiß.
 
 
 Exim version 4.76
 
 
 Exim version 4.76
index fb6d6922b551b40bb095f0db678968807c445e38..ec4dd71f94392407f12a78208b6af1c107825871 100644 (file)
@@ -4404,13 +4404,24 @@ while (*s != 0)
 
         (void)close(fd_in);
 
 
         (void)close(fd_in);
 
+        /* Read the pipe to get the command's output into $value (which is kept
+        in lookup_value). Read during execution, so that if the output exceeds
+        the OS pipe buffer limit, we don't block forever. */
+
+        f = fdopen(fd_out, "rb");
+        sigalrm_seen = FALSE;
+        alarm(60);
+        lookup_value = cat_file(f, lookup_value, &lsize, &lptr, NULL);
+        alarm(0);
+        (void)fclose(f);
+
         /* Wait for the process to finish, applying the timeout, and inspect its
         return code for serious disasters. Simple non-zero returns are passed on.
         */
 
         /* Wait for the process to finish, applying the timeout, and inspect its
         return code for serious disasters. Simple non-zero returns are passed on.
         */
 
-        if ((runrc = child_close(pid, 60)) < 0)
+        if (sigalrm_seen == TRUE || (runrc = child_close(pid, 30)) < 0)
           {
           {
-          if (runrc == -256)
+          if (sigalrm_seen == TRUE || runrc == -256)
             {
             expand_string_message = string_sprintf("command timed out");
             killpg(pid, SIGKILL);       /* Kill the whole process group */
             {
             expand_string_message = string_sprintf("command timed out");
             killpg(pid, SIGKILL);       /* Kill the whole process group */
@@ -4426,14 +4437,6 @@ while (*s != 0)
 
           goto EXPAND_FAILED;
           }
 
           goto EXPAND_FAILED;
           }
-
-        /* Read the pipe to get the command's output into $value (which is kept
-        in lookup_value). */
-
-        f = fdopen(fd_out, "rb");
-        lookup_value = NULL;
-        lookup_value = cat_file(f, lookup_value, &lsize, &lptr, NULL);
-        (void)fclose(f);
         }
 
       /* Process the yes/no strings; $value may be useful in both cases */
         }
 
       /* Process the yes/no strings; $value may be useful in both cases */