+
+ if ($kill_on_failure) {
+ # Filter output.
+ my ($buf) = "";
+ my ($boots) = 0;
+ local ($|) = 1;
+ for (;;) {
+ if (waitpid ($pid, WNOHANG) != 0) {
+ # Subprocess died. Pass through any remaining data.
+ print $buf while sysread ($in, $buf, 4096) > 0;
+ last;
+ }
+
+ # Read and print out pipe data.
+ my ($len) = length ($buf);
+ waitpid ($pid, 0), last
+ if sysread ($in, $buf, 4096, $len) <= 0;
+ print substr ($buf, $len);
+
+ # Remove full lines from $buf and scan them for keywords.
+ while ((my $idx = index ($buf, "\n")) >= 0) {
+ local $_ = substr ($buf, 0, $idx + 1, '');
+ next if defined ($cause);
+ if (/(Kernel PANIC|User process ABORT)/ ) {
+ $cause = "\L$1\E";
+ alarm (5);
+ } elsif (/Pintos booting/ && ++$boots > 1) {
+ $cause = "triple fault";
+ alarm (5);
+ } elsif (/FAILED/) {
+ $cause = "test failure";
+ alarm (5);
+ }
+ }
+ }
+ } else {
+ waitpid ($pid, 0);
+ }