<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>runtee</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -48,7 +48,7 @@ while [ -n &quot;$did_something&quot; ]; do
 		did_something=1
 		echo &quot;Building $branch: $ref&quot;
 		set -m
-		./run-build.sh $ref &amp;
+		./runtee log.out ./run-build.sh $ref &amp;
 		XPID=$!
 		trap &quot;echo 'Killing (SIGINT)';  kill -TERM -$XPID; exit 1&quot; SIGINT
 		trap &quot;echo 'Killing (SIGTERM)'; kill -TERM -$XPID; exit 1&quot; SIGTERM</diff>
      <filename>autobuilder.sh</filename>
    </modified>
    <modified>
      <diff>@@ -12,7 +12,6 @@ mkdir -p out/fail out/pass
 
 log()
 {
-	# (echo &quot;$@&quot;) &gt;&amp;2
 	(echo; echo &quot;&gt;&gt;&gt; $@&quot;) # log file
 }
 
@@ -52,9 +51,13 @@ go()
 {
 	echo $ref &gt;out/.doing
 	rm -f out/pass/$ref out/fail/$ref
-	run $ref | perl -pe 's/\r/\n/g; s/\n+/\n/g;' \
-		| tee log.out
+	run $ref
 	CODE=${PIPESTATUS[0]}
+	
+	# This whole program's output is being dumped in log.out.  Unix
+	# lets us rename open files, so we can do that here.
+	# FIXME: it would be cleaner if the caller renamed the output
+	# file based on our result code, however.
 	if [ &quot;$CODE&quot; = 0 ]; then
 		echo PASS
 		mv -v log.out out/pass/$ref
@@ -65,6 +68,7 @@ go()
 
 	echo &quot;Done: $ref&quot;
 	rm -f out/.doing
+	return $CODE
 }
 
 set -m
@@ -72,6 +76,5 @@ go &amp;
 XPID=$!
 trap &quot;echo 'Killing (SIGINT)';  kill -TERM -$XPID; exit 1&quot; SIGINT
 trap &quot;echo 'Killing (SIGTERM)'; kill -TERM -$XPID; exit 1&quot; SIGTERM
-wait; wait
-
-exit 0
+wait $XPID
+# return exit code from previous command</diff>
      <filename>run-build.sh</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,16 @@
 #!/usr/bin/perl -w
+#
+# A simple script that runs the specified command only if the given lockfile
+# is not locked.  If it *is* locked, we just return 0, considering that
+# a success (after all, the command probably is running successfully; it's
+# just not us that ran it!)
+#
+# If it is *not* currently locked, we lock it, run the command, and return
+# its result.
+#
+# We also make an extra effort to handle signals correctly and cleanup our
+# subprocess and lock file when we receive one.
+#
 use strict;
 use LockFile::Simple;
 
@@ -24,7 +36,7 @@ if (defined($lock)) {
 	}	
 	my $ret = $?;
 	$lock-&gt;release;
-	exit $? &gt;&gt; 8;
+	exit $ret &gt;&gt; 8;
     } else {
 	# child
 	exec(@ARGV);</diff>
      <filename>runlock</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b84691b7c888ccca68c1590f5e0a3e1eea2309bc</id>
    </parent>
  </parents>
  <author>
    <name>Avery Pennarun</name>
    <email>apenwarr@gmail.com</email>
  </author>
  <url>http://github.com/apenwarr/gitbuilder/commit/6e065448fca4aabb8043d5e0003ba0379e6b8278</url>
  <id>6e065448fca4aabb8043d5e0003ba0379e6b8278</id>
  <committed-date>2008-10-20T15:09:41-07:00</committed-date>
  <authored-date>2008-10-20T15:09:41-07:00</authored-date>
  <message>Add and use 'runtee' to avoid hangs due to long-running subprocesses.

If build.sh ended up launching a daemon or other program that ran in the
background, the autobuild cycle would hang, because that daemon might keep
its stdout open, and thus the &quot;tee&quot; it was feeding into would never exit.

Of course, daemons are supposed to close their stdout/stderr when forking
into the background, for exactly this reason.  But since we're an
autobuilder, we have no guarantee that the daemons we end up launching are
actually well-written and bug free, so we can't rely on this working.

Instead, runtee exits as soon as its subprogram dies *and* the input pipe
is empty.  It doesn't wait for the input pipe to *close*, however.</message>
  <tree>569b72660e205896811001546310433966021e40</tree>
  <committer>
    <name>Avery Pennarun</name>
    <email>apenwarr@gmail.com</email>
  </committer>
</commit>
