5 use POSIX qw(geteuid getegid isatty);
7 my $owner = getpwuid(geteuid());
8 my $group = getgrgid(getegid());
10 my ($OK, $FAILED) = ("ok", "failed");
11 if (isatty(fileno(STDOUT))) {
12 $OK = "\033[32m" . $OK . "\033[m";
13 $FAILED = "\033[31m\033[1m" . $FAILED . "\033[m";
16 my ($prog, $in, $out) = ([], [], []);
22 my $script = <>; $line++;
23 $script =~ s/\@OWNER\@/$owner/g;
24 $script =~ s/\@GROUP\@/$group/g;
25 next if (defined($script) && $script =~ /^!/);
26 if (!defined($script) || $script =~ s/^\$ ?//) {
28 #print "[$prog_line] \$ ", join(' ', @$prog), " -- ";
30 print "[$prog_line] \$ ", join(' ',
31 map { s/\s/\\$&/g; $_ } @$p), " -- ";
32 my $result = exec_test($prog, $in);
34 my $nmax = (@$out > @$result) ? @$out : @$result;
35 for (my $n=0; $n < $nmax; $n++) {
36 if (!defined($out->[$n]) || !defined($result->[$n]) ||
37 $out->[$n] ne $result->[$n]) {
41 #print "$out->[$n] != $result->[$n]";
45 $failed++ unless $good;
46 print $good ? $OK : $FAILED, "\n";
48 for (my $n=0; $n < $nmax; $n++) {
49 my $l = defined($out->[$n]) ? $out->[$n] : "~";
51 my $r = defined($result->[$n]) ? $result->[$n] : "~";
53 print sprintf("%-37s | %-39s\n", $l, $r);
57 #$prog = [ split /\s+/, $script ] if $script;
58 $prog = [ map { s/\\(.)/$1/g; $_ } split /(?<!\\)\s+/, $script ] if $script;
62 } elsif ($script =~ s/^> ?//) {
67 last unless defined($script);
69 my $status = sprintf("%d commands (%d passed, %d failed)",
70 $tests, $tests-$failed, $failed);
71 if (isatty(fileno(STDOUT))) {
73 $status = "\033[31m\033[1m" . $status . "\033[m";
75 $status = "\033[32m" . $status . "\033[m";
83 local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2);
85 if ($prog->[0] eq "umask") {
88 } elsif ($prog->[0] eq "cd") {
89 if (!chdir $prog->[1]) {
90 return [ "chdir: $prog->[1]: $!\n" ];
96 or die "Can't create pipe for reading: $!";
97 open *IN_DUP, "<&STDIN"
100 or die "Can't duplicate pipe for reading: $!";
103 open *OUT_DUP, ">&STDOUT"
104 or die "Can't duplicate STDOUT: $!";
106 or die "Can't create pipe for writing: $!";
107 open *STDOUT, ">&OUT2"
108 or die "Can't duplicate pipe for writing: $!";
111 *STDOUT->autoflush();
117 open *STDIN, "<&IN_DUP"
118 or die "Can't duplicate STDIN: $!";
120 or die "Can't close STDIN duplicate: $!";
122 open *STDOUT, ">&OUT_DUP"
123 or die "Can't duplicate STDOUT: $!";
125 or die "Can't close STDOUT duplicate: $!";
127 foreach my $line (@$in) {
132 or die "Can't close pipe for writing: $!";
143 or die "Can't close read end for input pipe: $!";
145 or die "Can't close write end for output pipe: $!";
147 or die "Can't close STDOUT duplicate: $!";
149 open ERR_DUP, ">&STDERR"
150 or die "Can't duplicate STDERR: $!";
151 open STDERR, ">&STDOUT"
152 or die "Can't join STDOUT and STDERR: $!";
154 #print ERR_DUP "<", join(' ', @$prog), ">\n";
156 print ERR_DUP $prog->[0], ": $!\n";