diff --git a/.gitignore b/.gitignore index 96e9a1b..6acf8cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ # binaries -helpers/echo-signal helpers/echo-exit +helpers/echo-rot13 +helpers/echo-signal helpers/exit-status-0 -helpers/list-fds helpers/fd-perms +helpers/list-fds helpers/timeout diff --git a/helpers/echo-rot13.c b/helpers/echo-rot13.c new file mode 100755 index 0000000..365923e --- /dev/null +++ b/helpers/echo-rot13.c @@ -0,0 +1,35 @@ +#if 0 +set -x "$(dirname $0)/$(basename $0 .c)" +exec ${CC:-cc} ${CFLAGS:--Wall -Wextra -g} $0 -o $1 +#endif + +/* Echo our arguments, rot13'd. */ + +#include +#include +#include +#include +#include +#include +#include + +static void rot13(char *s) +{ + while (*s) { + char c = *s|32; + if (c >= 'a' && c <= 'm') *s += 13; + else if (c >= 'n' && c <= 'z') *s -= 13; + ++s; + } +} + +int main(int argc, char **argv) +{ + for (int i = 1; i < argc; ++i) + rot13(argv[i]); + if (argc > 1) printf("%s", argv[1]); + for (int i = 2; i < argc; ++i) + printf(" %s", argv[i]); + puts(""); + return 0; +} diff --git a/helpers/echo-signal.c b/helpers/echo-signal.c index fdbe9ff..f377c96 100755 --- a/helpers/echo-signal.c +++ b/helpers/echo-signal.c @@ -9,19 +9,33 @@ exec ${CC:-cc} ${CFLAGS:--Wall -Wextra -g} $0 -o $1 #include #include #include +#include #include -static void echo(int n) +static char *awaited; + +static int int_of_signal_name(char *name) +{ + if (!strcmp(name, "INT")) return SIGINT; + if (!strcmp(name, "TSTP")) return SIGTSTP; + if (!strcmp(name, "CONT")) return SIGCONT; + abort(); +} + +static void echo(int _) { - printf("%d\n", n); /* safe-ish because we don't do anything else. hah. */ + (void)_; + puts(awaited); /* never do stuff like this in signal handlers. */ } int main(int argc, char **argv) { struct sigaction action = { .sa_handler = echo }; if (2 != argc) abort(); - int sig = atoi(argv[1]); + int sig = int_of_signal_name(argv[1]); + awaited = argv[1]; sigaction(sig, &action, NULL); + puts("ready"); pause(); return 0; } diff --git a/helpers/harness.tcl b/helpers/harness.tcl index 7e226c2..2624131 100755 --- a/helpers/harness.tcl +++ b/helpers/harness.tcl @@ -95,7 +95,7 @@ while {![eof $test_file]} { seek $test_file 0 start log_user 0 -set send_slow { 10 .001 } +set send_slow { 1 .01 } setup_execution_environment if [catch {spawn $shell} err] {error $err} # waiting for first prompt can help @@ -125,12 +125,13 @@ proc not_ok {} { proc is {x} { uplevel 1 [list if $x {ok} {not_ok}]} proc expect_line {line} { - # NB: the \r\n at the start of the line here breaks fish, and - # makes this somewhat unreliable, but it's tricky to find an - # alternative that is as simple and stops cat from passing the - # tests. + # NB: this is fairly unreliable, and we should have some lint + # where we reject tests whose expected output would match the tail + # of their input. There doesn't seem to be a better way to deal + # with the output and timing differences between shells, short of + # going full ptrace as mentioned previously. set rv [expect { - "\r\n$line\r\n" {return 1} + "$line\r\n" {return 1} default {return 0} }] expect * diff --git a/stage_1/01-fork-exec.t b/stage_1/01-fork-exec.t index 8d1736d..0acce79 100644 --- a/stage_1/01-fork-exec.t +++ b/stage_1/01-fork-exec.t @@ -2,5 +2,7 @@ ← foo bar → tr a-z n-za-m⏎foo bar baz⏎^D ← sbb one onm +→ ./helpers/echo-rot13 foo bar⏎ +← sbb one → ./helpers/echo-exit ./helpers/successful-exit-status⏎ ← 0 diff --git a/stage_1/03-cd-changes-directory.t b/stage_1/03-cd-changes-directory.t index f91c2a0..295695f 100644 --- a/stage_1/03-cd-changes-directory.t +++ b/stage_1/03-cd-changes-directory.t @@ -1,5 +1,6 @@ → /bin/pwd⏎ ≠ /tmp → cd /tmp⏎ +→ cd ..⏎ → /bin/pwd⏎ -← /tmp +← / diff --git a/stage_1/04-semicolon-separates-commands.t b/stage_1/04-semicolon-separates-commands.t index 2507453..f70dd74 100644 --- a/stage_1/04-semicolon-separates-commands.t +++ b/stage_1/04-semicolon-separates-commands.t @@ -3,5 +3,5 @@ ← foobarbaz → cd /tmp; pwd⏎ ← /tmp -→ false; echo foo⏎ -← foo +→ false; echo-rot13 foo⏎ +← sbb diff --git a/stage_1/05-and-or-chaining.t b/stage_1/05-and-or-chaining.t index d181b88..9342429 100644 --- a/stage_1/05-and-or-chaining.t +++ b/stage_1/05-and-or-chaining.t @@ -1,13 +1,15 @@ # POSIX calls these AND Lists and OR Lists -→ true && echo foo⏎ -← foo -→ false && echo foo⏎ -≠ foo -→ true && false && echo foo⏎ -≠ foo -→ false || echo foo⏎ -← foo -→ true || false || echo foo⏎ -≠ foo -→ false || true && echo foo⏎ -← foo +→ true && echo-rot13 foo⏎ +← sbb +→ false && echo-rot13 foo⏎ +≠ sbb +→ true && false && echo-rot13 foo⏎ +≠ sbb +→ false || echo-rot13 foo⏎ +← sbb +→ true || false || echo-rot13 foo⏎ +≠ sbb +→ false || true && echo-rot13 foo⏎ +← sbb +→ nonexistent-command || echo-rot13 zim⏎ +← mvz diff --git a/stage_1/07-subshell.t b/stage_1/07-subshell.t index e03020e..838650d 100644 --- a/stage_1/07-subshell.t +++ b/stage_1/07-subshell.t @@ -4,7 +4,7 @@ ← /tmp → pwd⏎ ≠ /tmp -→ (exit 1) && echo foo⏎ -≠ foo -→ (exit 0 && exit 1) && echo foo⏎ -← foo +→ (exit 1) && echo-rot13 foo⏎ +≠ sbb +→ (exit 0 && exit 1) && echo-rot13 foo⏎ +← sbb diff --git a/stage_1/08-bang-negates-exit-code.t b/stage_1/08-bang-negates-exit-code.t index 1ae6748..4018a52 100644 --- a/stage_1/08-bang-negates-exit-code.t +++ b/stage_1/08-bang-negates-exit-code.t @@ -1,6 +1,6 @@ -→ ! false && echo foo⏎ -← foo -→ ! true && echo foo⏎ -≠ foo -→ ! true || echo foo⏎ -← foo +→ ! false && echo-rot13 foo⏎ +← sbb +→ ! true && echo-rot13 foo⏎ +≠ sbb +→ ! true || echo-rot13 foo⏎ +← sbb diff --git a/stage_1/10-multiline-list.t b/stage_1/10-multiline-list.t index c78e190..3f67029 100644 --- a/stage_1/10-multiline-list.t +++ b/stage_1/10-multiline-list.t @@ -1,2 +1,2 @@ -→ true &&⏎false ||⏎echo foo ||⏎echo bar⏎ -← foo +→ true &&⏎false ||⏎echo-rot13 foo ||⏎echo-rot13 bar⏎ +← sbb diff --git a/stage_2/02-redirections.t b/stage_2/02-redirections.t index 38c05ae..04b76a0 100644 --- a/stage_2/02-redirections.t +++ b/stage_2/02-redirections.t @@ -8,8 +8,8 @@ # NB echo -n isn't portable... → echo -n a > foo ; echo b >> foo ; cat foo⏎ ← ab -→ cat < /non-existent-file || echo foo⏎ -← foo +→ cat < /non-existent-file || echo-rot13 foo⏎ +← sbb → cat /non-existent-file 2>foo || grep -c . foo && cat < foo⏎ diff --git a/stage_2/04-ensure-pipes-are-closed.t b/stage_2/04-ensure-pipes-are-closed.t index 00def44..4004254 100644 --- a/stage_2/04-ensure-pipes-are-closed.t +++ b/stage_2/04-ensure-pipes-are-closed.t @@ -1,4 +1,4 @@ # This will hang in the case of a very common bug: you forget to close # the other ends of the pipe. -→ cat /dev/null | echo foo⏎ -← foo +→ cat /dev/null | echo-rot13 foo⏎ +← sbb diff --git a/stage_2/07-bang-only-at-start-of-pipelines.t b/stage_2/07-bang-only-at-start-of-pipelines.t index 56f87e7..7906a50 100644 --- a/stage_2/07-bang-only-at-start-of-pipelines.t +++ b/stage_2/07-bang-only-at-start-of-pipelines.t @@ -1,5 +1,5 @@ # Would prefer to test this but mksh doesn't agree #→ echo zim | ! tr z b | grep -qc bim || echo foo⏎ #≠ foo -→ ! echo zim | tr z b | grep -qc bim || echo foo⏎ -← foo +→ ! echo zim | tr z b | grep -qc bim || echo-rot13 foo⏎ +← sbb diff --git a/stage_2/08-builtin-in-pipeline.t b/stage_2/08-builtin-in-pipeline.t index 84ce145..4deef2d 100644 --- a/stage_2/08-builtin-in-pipeline.t +++ b/stage_2/08-builtin-in-pipeline.t @@ -1,4 +1,4 @@ → echo foo | cd /tmp | pwd⏎ ≠ /tmp -→ echo foo | cd /tmp | echo bar⏎ -← bar +→ echo foo | cd /tmp | echo-rot13 bar⏎ +← one diff --git a/stage_3/01-executed-command-receives-signals.t b/stage_3/01-executed-command-receives-signals.t index a7e64c5..61db2a6 100644 --- a/stage_3/01-executed-command-receives-signals.t +++ b/stage_3/01-executed-command-receives-signals.t @@ -1,10 +1,9 @@ # this would be nicer if we already had $@... -→ echo-signal 2⏎ +→ echo-signal INT⏎ +← ready → ^C⏎ -← 2 -→ cat⏎ -→ ^\⏎echo foo⏎ -← foo -→ echo-signal 20⏎ +← INT +→ echo-signal TSTP⏎ +← ready → ^Z⏎ -← 20 +← TSTP diff --git a/stage_3/02-job-control-with-fg-bg.t b/stage_3/02-job-control-with-fg-bg.t index 5f73fe6..4923564 100644 --- a/stage_3/02-job-control-with-fg-bg.t +++ b/stage_3/02-job-control-with-fg-bg.t @@ -1,12 +1,14 @@ -→ echo-signal 18⏎ +→ echo-signal CONT⏎ +← ready → ^Z -→ echo foo⏎ -← foo +→ echo-rot13 foo⏎ +← sbb → fg⏎ -← 18 -→ echo-signal 2 &⏎ -→ echo foo⏎ -← foo +← CONT +→ echo-signal INT &⏎ +← ready +→ echo-rot13 foo⏎ +← sbb → fg⏎ → ^C⏎ -← 2 +← INT diff --git a/stage_3/03-sequencing-with-suspend.t b/stage_3/03-sequencing-with-suspend.t index 5674a7a..3f7a2de 100644 --- a/stage_3/03-sequencing-with-suspend.t +++ b/stage_3/03-sequencing-with-suspend.t @@ -1,5 +1,6 @@ -→ echo-signal 2 & echo foo⏎ -← foo +→ echo-signal INT & sleep 1; echo-rot13 foo⏎ +← ready +← sbb → fg⏎ → ^C⏎ -← 2 +← INT diff --git a/stage_3/05-sigquit.t b/stage_3/05-sigquit.t index 0416c13..d97880a 100644 --- a/stage_3/05-sigquit.t +++ b/stage_3/05-sigquit.t @@ -1,2 +1,4 @@ -→ cat⏎^\⏎echo foo⏎ -← foo +→ cat⏎^\⏎echo-rot13 foo⏎ +← sbb +→ ^\^\echo-rot13 blah⏎ +← oynu diff --git a/stage_4/05-commands-can-be-quoted.t b/stage_4/05-commands-can-be-quoted.t index cad30f4..c261300 100644 --- a/stage_4/05-commands-can-be-quoted.t +++ b/stage_4/05-commands-can-be-quoted.t @@ -1,4 +1,6 @@ → e'ch'o foo⏎ ← foo -→ ''''""/"b"i'n/e'"c"ho''"" yup⏎ +→ ''''""/"b"i'n/e'"c"ho''"" yup; true⏎ ← yup +→ ""'echo'"-"rot1'3' yup⏎ +← lhc diff --git a/stage_4/10-tilde-expansion.t b/stage_4/10-tilde-expansion.t index 543b41f..b721a94 100644 --- a/stage_4/10-tilde-expansion.t +++ b/stage_4/10-tilde-expansion.t @@ -1,4 +1,4 @@ -→ echo ~⏎ +→ echo ~; true⏎ ≠ ~ # XXX this will vary by system; use magic. → echo ~root⏎ diff --git a/stage_5/01-tab-completion.t b/stage_5/01-tab-completion.t index a4c1ae6..ebc7194 100644 --- a/stage_5/01-tab-completion.t +++ b/stage_5/01-tab-completion.t @@ -1,4 +1,4 @@ # not POSIX → touch foo bar⏎ -→ ech^I f^I b^I⏎ -← foo bar +→ ech^I-rot^I f^I b^I⏎ +← sbb one diff --git a/stage_5/02-basic-history.t b/stage_5/02-basic-history.t index bde7318..f3409c1 100644 --- a/stage_5/02-basic-history.t +++ b/stage_5/02-basic-history.t @@ -1,5 +1,6 @@ -→ echo foo⏎ -← foo -→ echo bar⏎ +→ echo-rot13 foo⏎ +← sbb +→ echo-rot13 bar⏎ +← one → ⇑⇑⏎ -← foo +← sbb diff --git a/stage_5/03-search-with-control-r.t b/stage_5/03-search-with-control-r.t index d271b59..f92d742 100644 --- a/stage_5/03-search-with-control-r.t +++ b/stage_5/03-search-with-control-r.t @@ -1,7 +1,7 @@ → true⏎ -→ echo foo⏎ -← foo -→ echo bar⏎ -← bar +→ echo-rot13 foo⏎ +← sbb +→ echo-rot13 bar⏎ +← one → ^Rf⏎ -← foo +← sbb