From: Phil Pennock Date: Sun, 28 Aug 2011 20:27:01 +0000 (-0400) Subject: Handle ${run} returning more data than OS pipe buffer size. X-Git-Tag: list_safety_merge_proposal~9 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/ac53fcdaf9c772ee8e70ca4f14ed19b39e12eb68?hp=555ae6af39312f43b1d38d8da05cf4368b933015 Handle ${run} returning more data than OS pipe buffer size. Patch from Holger Weiß. fixes bug 1131 --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index a8e886836..23a18cf2f 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 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 diff --git a/src/src/expand.c b/src/src/expand.c index fb6d6922b..ec4dd71f9 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -4404,13 +4404,24 @@ while (*s != 0) (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. */ - 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 */ @@ -4426,14 +4437,6 @@ while (*s != 0) 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 */