aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2016-03-27 13:30:25 +1000
committerSteve Bennett <steveb@workware.net.au>2016-03-27 13:34:40 +1000
commitc2e1a3bcbbb25a09fca7c27c2d518f3601b8e2b1 (patch)
tree4fb28a14bc1a9e447854e6be15293a51e3d1535b
parent62f87df83456d87289f3e01f97009c0a806e5fcb (diff)
downloadjimtcl-c2e1a3bcbbb25a09fca7c27c2d518f3601b8e2b1.zip
jimtcl-c2e1a3bcbbb25a09fca7c27c2d518f3601b8e2b1.tar.gz
jimtcl-c2e1a3bcbbb25a09fca7c27c2d518f3601b8e2b1.tar.bz2
exec: read output from pipe before waiting for children
It is necessary to read output from the pipe before waiting for children to exit to avoid the output filling up and blocking. The error results still needs to be read after the children have exited, since it is read from a temp file, not a pipe. Increase the length of the input to test exec-8.1 to catch the problem. Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim-exec.c19
-rw-r--r--tests/exec.test10
2 files changed, 12 insertions, 17 deletions
diff --git a/jim-exec.c b/jim-exec.c
index 4d704d8..f64f5cc 100644
--- a/jim-exec.c
+++ b/jim-exec.c
@@ -453,18 +453,9 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
result = JIM_OK;
- /* Wait for children to finish. Any abnormal results are appended to childErrObj */
- childErrObj = Jim_NewStringObj(interp, "", 0);
- Jim_IncrRefCount(childErrObj);
- if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
- result = JIM_ERR;
- }
-
- /*
- * Start with an empty result
- */
errStrObj = Jim_NewStringObj(interp, "", 0);
+ /* Read from the output pipe until EOF */
if (outputId != JIM_BAD_FD) {
if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
result = JIM_ERR;
@@ -472,6 +463,14 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
+ /* Now wait for children to finish. Any abnormal results are appended to childErrObj */
+ childErrObj = Jim_NewStringObj(interp, "", 0);
+ Jim_IncrRefCount(childErrObj);
+
+ if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
+ result = JIM_ERR;
+ }
+
/*
* Read the child's error output (if any) and put it into the result.
*
diff --git a/tests/exec.test b/tests/exec.test
index 50dc706..441681e 100644
--- a/tests/exec.test
+++ b/tests/exec.test
@@ -218,14 +218,10 @@ test exec-7.2 {multiple I/O redirections} {
# Long input to command and output from command.
-set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
-set a [concat $a $a $a $a]
-set a [concat $a $a $a $a]
-set a [concat $a $a $a $a]
-set a [concat $a $a $a $a]
+set a [string repeat a 1000000]
test exec-8.1 {long input and output} {
- exec cat << $a
-} $a
+ string length [exec cat << $a]
+} 1000000
# More than 20 arguments to exec.