From 97179bb75cbfc43d94a10a34410a8f9752090aaa Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 13 Aug 2026 14:51:00 +0000 Subject: update --- autograder/sdriver.pl | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ autograder/trace01.txt | 5 ++ autograder/trace02.txt | 5 ++ autograder/trace03.txt | 5 ++ autograder/trace04.txt | 5 ++ autograder/trace05.txt | 11 +++ autograder/trace06.txt | 8 ++ autograder/trace07.txt | 14 ++++ autograder/trace08.txt | 14 ++++ autograder/trace09.txt | 20 +++++ autograder/trace10.txt | 22 ++++++ autograder/trace11.txt | 12 +++ autograder/trace12.txt | 17 ++++ autograder/trace13.txt | 23 ++++++ autograder/trace14.txt | 47 +++++++++++ autograder/trace15.txt | 46 +++++++++++ autograder/trace16.txt | 16 ++++ sdriver.pl | 210 ------------------------------------------------- trace01.txt | 5 -- trace02.txt | 5 -- trace03.txt | 5 -- trace04.txt | 5 -- trace05.txt | 11 --- trace06.txt | 8 -- trace07.txt | 14 ---- trace08.txt | 14 ---- trace09.txt | 20 ----- trace10.txt | 22 ------ trace11.txt | 12 --- trace12.txt | 17 ---- trace13.txt | 23 ------ trace14.txt | 47 ----------- trace15.txt | 46 ----------- trace16.txt | 16 ---- tsh.cc | 10 ++- 35 files changed, 488 insertions(+), 482 deletions(-) create mode 100755 autograder/sdriver.pl create mode 100644 autograder/trace01.txt create mode 100644 autograder/trace02.txt create mode 100644 autograder/trace03.txt create mode 100644 autograder/trace04.txt create mode 100644 autograder/trace05.txt create mode 100644 autograder/trace06.txt create mode 100644 autograder/trace07.txt create mode 100644 autograder/trace08.txt create mode 100644 autograder/trace09.txt create mode 100644 autograder/trace10.txt create mode 100644 autograder/trace11.txt create mode 100644 autograder/trace12.txt create mode 100644 autograder/trace13.txt create mode 100644 autograder/trace14.txt create mode 100644 autograder/trace15.txt create mode 100644 autograder/trace16.txt delete mode 100755 sdriver.pl delete mode 100644 trace01.txt delete mode 100644 trace02.txt delete mode 100644 trace03.txt delete mode 100644 trace04.txt delete mode 100644 trace05.txt delete mode 100644 trace06.txt delete mode 100644 trace07.txt delete mode 100644 trace08.txt delete mode 100644 trace09.txt delete mode 100644 trace10.txt delete mode 100644 trace11.txt delete mode 100644 trace12.txt delete mode 100644 trace13.txt delete mode 100644 trace14.txt delete mode 100644 trace15.txt delete mode 100644 trace16.txt diff --git a/autograder/sdriver.pl b/autograder/sdriver.pl new file mode 100755 index 0000000..852bf3d --- /dev/null +++ b/autograder/sdriver.pl @@ -0,0 +1,210 @@ +#!/usr/bin/perl +#!/usr/local/bin/perl +use Getopt::Std; +use FileHandle; +use IPC::Open2; + +####################################################################### +# sdriver.pl - Shell driver +# +# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. +# May not be used, modified, or copied without permission. +# +# The driver runs a student's shell program as a child, sends +# commands and signals to the child as directed by a trace file, +# and captures and displays the output produced by the child. +# +# Tracefile format: +# +# The tracefile consists of text lines that are either blank lines, +# comment lines, driver commands, or shell commands. Blank lines are +# ignored. Comment lines begin with "#" and are echo'd without change +# to stdout. Driver commands are intepreted by the driver and are not +# passed to the child shell. All other lines are shell commands and +# are passed without modification to the shell, which reads them on +# stdin. Output produced by the child on stdout/stderr is read by +# the parent and printed on its stdout. +# +# Driver commands: +# TSTP Send a SIGTSTP signal to the child +# INT Send a SIGINT signal to the child +# QUIT Send a SIGQUIT signal to the child +# KILL Send a SIGKILL signal to the child +# CLOSE Close Writer (sends EOF signal to child) +# WAIT Wait() for child to terminate +# SLEEP Sleep for seconds +# +###################################################################### + +# +# usage - print help message and terminate +# +sub usage +{ + printf STDERR "$_[0]\n"; + printf STDERR "Usage: $0 [-hv] -t -s -a \n"; + printf STDERR "Options:\n"; + printf STDERR " -h Print this message\n"; + printf STDERR " -v Be more verbose\n"; + printf STDERR " -t Trace file\n"; + printf STDERR " -s Shell program to test\n"; + printf STDERR " -a Shell arguments\n"; + printf STDERR " -g Generate output for autograder\n"; + die "\n" ; +} + +# Parse the command line arguments +getopts('hgvt:s:a:'); +if ($opt_h) { + usage(); +} +if (!$opt_t) { + usage("Missing required -t argument"); +} +if (!$opt_s) { + usage("Missing required -s argument"); +} +$verbose = $opt_v; +$infile = $opt_t; +$shellprog = $opt_s; +$shellargs = $opt_a; +$grade = $opt_g; + +# Make sure the input script exists and is readable +-e $infile + or die "$0: ERROR: $infile not found\n"; +-r $infile + or die "$0: ERROR: $infile is not readable\n"; + +# Make sure the shell program exists and is executable +-e $shellprog + or die "$0: ERROR: $shellprog not found\n"; +-x $shellprog + or die "$0: ERROR: $shellprog is not executable\n"; + + +# Open the input script +open INFILE, $infile + or die "$0: ERROR: Couldn't open input file $infile: $!\n"; + +# +# Fork a child, run the shell in it, and connect the parent +# and child with a pair of unidirectional pipes: +# parent:Writer -> child:stdin +# child:stdout -> parent:Reader +# +$pid = open2(\*Reader, \*Writer, "$shellprog $shellargs"); +Writer->autoflush(); + +# The autograder will want to know the child shell's pid +if ($grade) { + print ("pid=$pid\n"); +} + +# +# Parent reads a trace file, sends commands to the child shell. +# +while () { + $line = $_; + chomp($line); + + # Comment line + if ($line =~ /^#/) { + print "$line\n"; + } + + # Blank line + elsif ($line =~ /^\s*$/) { + if ($verbose) { + print "$0: Ignoring blank line\n"; + } + } + + # Send SIGTSTP (ctrl-z) + elsif ($line =~ /TSTP/) { + if ($verbose) { + print "$0: Sending SIGTSTP signal to process $pid\n"; + } + kill 'TSTP', $pid; + } + + # Send SIGINT (ctrl-c) + elsif ($line =~ /INT/) { + if ($verbose) { + print "$0: Sending SIGINT signal to process $pid\n"; + } + kill 'INT', $pid; + } + + # Send SIGQUIT (whenever we need graceful termination) + elsif ($line =~ /QUIT/) { + if ($verbose) { + print "$0: Sending SIGQUIT signal to process $pid\n"; + } + kill 'QUIT', $pid; + } + + # Send SIGKILL + elsif ($line =~ /KILL/) { + if ($verbose) { + print "$0: Sending SIGKILL signal to process $pid\n"; + } + kill 'KILL', $pid; + } + + # Close pipe (sends EOF notification to child) + elsif ($line =~ /CLOSE/) { + if ($verbose) { + print "$0: Closing output end of pipe to child $pid\n"; + } + close Writer; + } + + # Wait for child to terminate + elsif ($line =~ /WAIT/) { + if ($verbose) { + print "$0: Waiting for child $pid\n"; + } + wait; + if ($verbose) { + print "$0: Child $pid reaped\n"; + } + } + + # Sleep + elsif ($line =~ /SLEEP (\d+)/) { + if ($verbose) { + print "$0: Sleeping $1 secs\n"; + } + sleep $1; + } + + # Unknown input + else { + if ($verbose) { + print "$0: Sending :$line: to child $pid\n"; + } + print Writer "$line\n"; + } +} + +# +# Parent echoes the output produced by the child. +# +close Writer; +if ($verbose) { + print "$0: Reading data from child $pid\n"; +} +while ($line = ) { + print $line; +} +close Reader; + +# Finally, parent reaps child +wait; + +if ($verbose) { + print "$0: Shell terminated\n"; +} + +exit; diff --git a/autograder/trace01.txt b/autograder/trace01.txt new file mode 100644 index 0000000..9c8561e --- /dev/null +++ b/autograder/trace01.txt @@ -0,0 +1,5 @@ +# +# trace01.txt - Properly terminate on EOF. +# +CLOSE +WAIT diff --git a/autograder/trace02.txt b/autograder/trace02.txt new file mode 100644 index 0000000..e97643b --- /dev/null +++ b/autograder/trace02.txt @@ -0,0 +1,5 @@ +# +# trace02.txt - Process builtin quit command. +# +quit +WAIT diff --git a/autograder/trace03.txt b/autograder/trace03.txt new file mode 100644 index 0000000..be8869c --- /dev/null +++ b/autograder/trace03.txt @@ -0,0 +1,5 @@ +# +# trace03.txt - Run a foreground job. +# +/bin/echo tsh> quit +quit diff --git a/autograder/trace04.txt b/autograder/trace04.txt new file mode 100644 index 0000000..554df0e --- /dev/null +++ b/autograder/trace04.txt @@ -0,0 +1,5 @@ +# +# trace04.txt - Run a background job. +# +/bin/echo -e tsh> ./myspin 1 \046 +./myspin 1 & diff --git a/autograder/trace05.txt b/autograder/trace05.txt new file mode 100644 index 0000000..03c1876 --- /dev/null +++ b/autograder/trace05.txt @@ -0,0 +1,11 @@ +# +# trace05.txt - Process jobs builtin command. +# +/bin/echo -e tsh> ./myspin 2 \046 +./myspin 2 & + +/bin/echo -e tsh> ./myspin 3 \046 +./myspin 3 & + +/bin/echo tsh> jobs +jobs diff --git a/autograder/trace06.txt b/autograder/trace06.txt new file mode 100644 index 0000000..bfa3890 --- /dev/null +++ b/autograder/trace06.txt @@ -0,0 +1,8 @@ +# +# trace06.txt - Forward SIGINT to foreground job. +# +/bin/echo -e tsh> ./myspin 4 +./myspin 4 + +SLEEP 2 +INT diff --git a/autograder/trace07.txt b/autograder/trace07.txt new file mode 100644 index 0000000..259a285 --- /dev/null +++ b/autograder/trace07.txt @@ -0,0 +1,14 @@ +# +# trace07.txt - Forward SIGINT only to foreground job. +# +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +/bin/echo -e tsh> ./myspin 5 +./myspin 5 + +SLEEP 2 +INT + +/bin/echo tsh> jobs +jobs diff --git a/autograder/trace08.txt b/autograder/trace08.txt new file mode 100644 index 0000000..49be19f --- /dev/null +++ b/autograder/trace08.txt @@ -0,0 +1,14 @@ +# +# trace08.txt - Forward SIGTSTP only to foreground job. +# +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +/bin/echo -e tsh> ./myspin 5 +./myspin 5 + +SLEEP 2 +TSTP + +/bin/echo tsh> jobs +jobs diff --git a/autograder/trace09.txt b/autograder/trace09.txt new file mode 100644 index 0000000..340d998 --- /dev/null +++ b/autograder/trace09.txt @@ -0,0 +1,20 @@ +# +# trace09.txt - Process bg builtin command +# +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +/bin/echo -e tsh> ./myspin 5 +./myspin 5 + +SLEEP 2 +TSTP + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> bg %2 +bg %2 + +/bin/echo tsh> jobs +jobs diff --git a/autograder/trace10.txt b/autograder/trace10.txt new file mode 100644 index 0000000..e7de996 --- /dev/null +++ b/autograder/trace10.txt @@ -0,0 +1,22 @@ +# +# trace10.txt - Process fg builtin command. +# +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +SLEEP 1 +/bin/echo tsh> fg %1 +fg %1 + +SLEEP 1 +TSTP + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> fg %1 +fg %1 + +/bin/echo tsh> jobs +jobs + diff --git a/autograder/trace11.txt b/autograder/trace11.txt new file mode 100644 index 0000000..d2f8663 --- /dev/null +++ b/autograder/trace11.txt @@ -0,0 +1,12 @@ +# +# trace11.txt - Forward SIGINT to every process in foreground process group +# +/bin/echo -e tsh> ./mysplit 4 +./mysplit 4 + +SLEEP 2 +INT + +/bin/echo tsh> /bin/ps a +/bin/ps a + diff --git a/autograder/trace12.txt b/autograder/trace12.txt new file mode 100644 index 0000000..88455e3 --- /dev/null +++ b/autograder/trace12.txt @@ -0,0 +1,17 @@ +# +# trace12.txt - Forward SIGTSTP to every process in foreground process group +# +/bin/echo -e tsh> ./mysplit 4 +./mysplit 4 + +SLEEP 2 +TSTP + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> /bin/ps a +/bin/ps a + + + diff --git a/autograder/trace13.txt b/autograder/trace13.txt new file mode 100644 index 0000000..d734cbc --- /dev/null +++ b/autograder/trace13.txt @@ -0,0 +1,23 @@ +# +# trace13.txt - Restart every stopped process in process group +# +/bin/echo -e tsh> ./mysplit 4 +./mysplit 4 + +SLEEP 2 +TSTP + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> /bin/ps a +/bin/ps a + +/bin/echo tsh> fg %1 +fg %1 + +/bin/echo tsh> /bin/ps a +/bin/ps a + + + diff --git a/autograder/trace14.txt b/autograder/trace14.txt new file mode 100644 index 0000000..8086580 --- /dev/null +++ b/autograder/trace14.txt @@ -0,0 +1,47 @@ +# +# trace14.txt - Simple error handling +# +/bin/echo tsh> ./bogus +./bogus + +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +/bin/echo tsh> fg +fg + +/bin/echo tsh> bg +bg + +/bin/echo tsh> fg a +fg a + +/bin/echo tsh> bg a +bg a + +/bin/echo tsh> fg 9999999 +fg 9999999 + +/bin/echo tsh> bg 9999999 +bg 9999999 + +/bin/echo tsh> fg %2 +fg %2 + +/bin/echo tsh> fg %1 +fg %1 + +SLEEP 2 +TSTP + +/bin/echo tsh> bg %2 +bg %2 + +/bin/echo tsh> bg %1 +bg %1 + +/bin/echo tsh> jobs +jobs + + + diff --git a/autograder/trace15.txt b/autograder/trace15.txt new file mode 100644 index 0000000..2cc780e --- /dev/null +++ b/autograder/trace15.txt @@ -0,0 +1,46 @@ +# +# trace15.txt - Putting it all together +# + +/bin/echo tsh> ./bogus +./bogus + +/bin/echo tsh> ./myspin 10 +./myspin 10 + +SLEEP 2 +INT + +/bin/echo -e tsh> ./myspin 3 \046 +./myspin 3 & + +/bin/echo -e tsh> ./myspin 4 \046 +./myspin 4 & + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> fg %1 +fg %1 + +SLEEP 2 +TSTP + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> bg %3 +bg %3 + +/bin/echo tsh> bg %1 +bg %1 + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> fg %1 +fg %1 + +/bin/echo tsh> quit +quit + diff --git a/autograder/trace16.txt b/autograder/trace16.txt new file mode 100644 index 0000000..822ba14 --- /dev/null +++ b/autograder/trace16.txt @@ -0,0 +1,16 @@ +# +# trace16.txt - Tests whether the shell can handle SIGTSTP and SIGINT +# signals that come from other processes instead of the terminal. +# + +/bin/echo tsh> ./mystop 2 +./mystop 2 + +SLEEP 3 + +/bin/echo tsh> jobs +jobs + +/bin/echo tsh> ./myint 2 +./myint 2 + diff --git a/sdriver.pl b/sdriver.pl deleted file mode 100755 index 852bf3d..0000000 --- a/sdriver.pl +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/perl -#!/usr/local/bin/perl -use Getopt::Std; -use FileHandle; -use IPC::Open2; - -####################################################################### -# sdriver.pl - Shell driver -# -# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. -# May not be used, modified, or copied without permission. -# -# The driver runs a student's shell program as a child, sends -# commands and signals to the child as directed by a trace file, -# and captures and displays the output produced by the child. -# -# Tracefile format: -# -# The tracefile consists of text lines that are either blank lines, -# comment lines, driver commands, or shell commands. Blank lines are -# ignored. Comment lines begin with "#" and are echo'd without change -# to stdout. Driver commands are intepreted by the driver and are not -# passed to the child shell. All other lines are shell commands and -# are passed without modification to the shell, which reads them on -# stdin. Output produced by the child on stdout/stderr is read by -# the parent and printed on its stdout. -# -# Driver commands: -# TSTP Send a SIGTSTP signal to the child -# INT Send a SIGINT signal to the child -# QUIT Send a SIGQUIT signal to the child -# KILL Send a SIGKILL signal to the child -# CLOSE Close Writer (sends EOF signal to child) -# WAIT Wait() for child to terminate -# SLEEP Sleep for seconds -# -###################################################################### - -# -# usage - print help message and terminate -# -sub usage -{ - printf STDERR "$_[0]\n"; - printf STDERR "Usage: $0 [-hv] -t -s -a \n"; - printf STDERR "Options:\n"; - printf STDERR " -h Print this message\n"; - printf STDERR " -v Be more verbose\n"; - printf STDERR " -t Trace file\n"; - printf STDERR " -s Shell program to test\n"; - printf STDERR " -a Shell arguments\n"; - printf STDERR " -g Generate output for autograder\n"; - die "\n" ; -} - -# Parse the command line arguments -getopts('hgvt:s:a:'); -if ($opt_h) { - usage(); -} -if (!$opt_t) { - usage("Missing required -t argument"); -} -if (!$opt_s) { - usage("Missing required -s argument"); -} -$verbose = $opt_v; -$infile = $opt_t; -$shellprog = $opt_s; -$shellargs = $opt_a; -$grade = $opt_g; - -# Make sure the input script exists and is readable --e $infile - or die "$0: ERROR: $infile not found\n"; --r $infile - or die "$0: ERROR: $infile is not readable\n"; - -# Make sure the shell program exists and is executable --e $shellprog - or die "$0: ERROR: $shellprog not found\n"; --x $shellprog - or die "$0: ERROR: $shellprog is not executable\n"; - - -# Open the input script -open INFILE, $infile - or die "$0: ERROR: Couldn't open input file $infile: $!\n"; - -# -# Fork a child, run the shell in it, and connect the parent -# and child with a pair of unidirectional pipes: -# parent:Writer -> child:stdin -# child:stdout -> parent:Reader -# -$pid = open2(\*Reader, \*Writer, "$shellprog $shellargs"); -Writer->autoflush(); - -# The autograder will want to know the child shell's pid -if ($grade) { - print ("pid=$pid\n"); -} - -# -# Parent reads a trace file, sends commands to the child shell. -# -while () { - $line = $_; - chomp($line); - - # Comment line - if ($line =~ /^#/) { - print "$line\n"; - } - - # Blank line - elsif ($line =~ /^\s*$/) { - if ($verbose) { - print "$0: Ignoring blank line\n"; - } - } - - # Send SIGTSTP (ctrl-z) - elsif ($line =~ /TSTP/) { - if ($verbose) { - print "$0: Sending SIGTSTP signal to process $pid\n"; - } - kill 'TSTP', $pid; - } - - # Send SIGINT (ctrl-c) - elsif ($line =~ /INT/) { - if ($verbose) { - print "$0: Sending SIGINT signal to process $pid\n"; - } - kill 'INT', $pid; - } - - # Send SIGQUIT (whenever we need graceful termination) - elsif ($line =~ /QUIT/) { - if ($verbose) { - print "$0: Sending SIGQUIT signal to process $pid\n"; - } - kill 'QUIT', $pid; - } - - # Send SIGKILL - elsif ($line =~ /KILL/) { - if ($verbose) { - print "$0: Sending SIGKILL signal to process $pid\n"; - } - kill 'KILL', $pid; - } - - # Close pipe (sends EOF notification to child) - elsif ($line =~ /CLOSE/) { - if ($verbose) { - print "$0: Closing output end of pipe to child $pid\n"; - } - close Writer; - } - - # Wait for child to terminate - elsif ($line =~ /WAIT/) { - if ($verbose) { - print "$0: Waiting for child $pid\n"; - } - wait; - if ($verbose) { - print "$0: Child $pid reaped\n"; - } - } - - # Sleep - elsif ($line =~ /SLEEP (\d+)/) { - if ($verbose) { - print "$0: Sleeping $1 secs\n"; - } - sleep $1; - } - - # Unknown input - else { - if ($verbose) { - print "$0: Sending :$line: to child $pid\n"; - } - print Writer "$line\n"; - } -} - -# -# Parent echoes the output produced by the child. -# -close Writer; -if ($verbose) { - print "$0: Reading data from child $pid\n"; -} -while ($line = ) { - print $line; -} -close Reader; - -# Finally, parent reaps child -wait; - -if ($verbose) { - print "$0: Shell terminated\n"; -} - -exit; diff --git a/trace01.txt b/trace01.txt deleted file mode 100644 index 9c8561e..0000000 --- a/trace01.txt +++ /dev/null @@ -1,5 +0,0 @@ -# -# trace01.txt - Properly terminate on EOF. -# -CLOSE -WAIT diff --git a/trace02.txt b/trace02.txt deleted file mode 100644 index e97643b..0000000 --- a/trace02.txt +++ /dev/null @@ -1,5 +0,0 @@ -# -# trace02.txt - Process builtin quit command. -# -quit -WAIT diff --git a/trace03.txt b/trace03.txt deleted file mode 100644 index be8869c..0000000 --- a/trace03.txt +++ /dev/null @@ -1,5 +0,0 @@ -# -# trace03.txt - Run a foreground job. -# -/bin/echo tsh> quit -quit diff --git a/trace04.txt b/trace04.txt deleted file mode 100644 index 554df0e..0000000 --- a/trace04.txt +++ /dev/null @@ -1,5 +0,0 @@ -# -# trace04.txt - Run a background job. -# -/bin/echo -e tsh> ./myspin 1 \046 -./myspin 1 & diff --git a/trace05.txt b/trace05.txt deleted file mode 100644 index 03c1876..0000000 --- a/trace05.txt +++ /dev/null @@ -1,11 +0,0 @@ -# -# trace05.txt - Process jobs builtin command. -# -/bin/echo -e tsh> ./myspin 2 \046 -./myspin 2 & - -/bin/echo -e tsh> ./myspin 3 \046 -./myspin 3 & - -/bin/echo tsh> jobs -jobs diff --git a/trace06.txt b/trace06.txt deleted file mode 100644 index bfa3890..0000000 --- a/trace06.txt +++ /dev/null @@ -1,8 +0,0 @@ -# -# trace06.txt - Forward SIGINT to foreground job. -# -/bin/echo -e tsh> ./myspin 4 -./myspin 4 - -SLEEP 2 -INT diff --git a/trace07.txt b/trace07.txt deleted file mode 100644 index 259a285..0000000 --- a/trace07.txt +++ /dev/null @@ -1,14 +0,0 @@ -# -# trace07.txt - Forward SIGINT only to foreground job. -# -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -/bin/echo -e tsh> ./myspin 5 -./myspin 5 - -SLEEP 2 -INT - -/bin/echo tsh> jobs -jobs diff --git a/trace08.txt b/trace08.txt deleted file mode 100644 index 49be19f..0000000 --- a/trace08.txt +++ /dev/null @@ -1,14 +0,0 @@ -# -# trace08.txt - Forward SIGTSTP only to foreground job. -# -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -/bin/echo -e tsh> ./myspin 5 -./myspin 5 - -SLEEP 2 -TSTP - -/bin/echo tsh> jobs -jobs diff --git a/trace09.txt b/trace09.txt deleted file mode 100644 index 340d998..0000000 --- a/trace09.txt +++ /dev/null @@ -1,20 +0,0 @@ -# -# trace09.txt - Process bg builtin command -# -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -/bin/echo -e tsh> ./myspin 5 -./myspin 5 - -SLEEP 2 -TSTP - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> bg %2 -bg %2 - -/bin/echo tsh> jobs -jobs diff --git a/trace10.txt b/trace10.txt deleted file mode 100644 index e7de996..0000000 --- a/trace10.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# trace10.txt - Process fg builtin command. -# -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -SLEEP 1 -/bin/echo tsh> fg %1 -fg %1 - -SLEEP 1 -TSTP - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> fg %1 -fg %1 - -/bin/echo tsh> jobs -jobs - diff --git a/trace11.txt b/trace11.txt deleted file mode 100644 index d2f8663..0000000 --- a/trace11.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# trace11.txt - Forward SIGINT to every process in foreground process group -# -/bin/echo -e tsh> ./mysplit 4 -./mysplit 4 - -SLEEP 2 -INT - -/bin/echo tsh> /bin/ps a -/bin/ps a - diff --git a/trace12.txt b/trace12.txt deleted file mode 100644 index 88455e3..0000000 --- a/trace12.txt +++ /dev/null @@ -1,17 +0,0 @@ -# -# trace12.txt - Forward SIGTSTP to every process in foreground process group -# -/bin/echo -e tsh> ./mysplit 4 -./mysplit 4 - -SLEEP 2 -TSTP - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> /bin/ps a -/bin/ps a - - - diff --git a/trace13.txt b/trace13.txt deleted file mode 100644 index d734cbc..0000000 --- a/trace13.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# trace13.txt - Restart every stopped process in process group -# -/bin/echo -e tsh> ./mysplit 4 -./mysplit 4 - -SLEEP 2 -TSTP - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> /bin/ps a -/bin/ps a - -/bin/echo tsh> fg %1 -fg %1 - -/bin/echo tsh> /bin/ps a -/bin/ps a - - - diff --git a/trace14.txt b/trace14.txt deleted file mode 100644 index 8086580..0000000 --- a/trace14.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# trace14.txt - Simple error handling -# -/bin/echo tsh> ./bogus -./bogus - -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -/bin/echo tsh> fg -fg - -/bin/echo tsh> bg -bg - -/bin/echo tsh> fg a -fg a - -/bin/echo tsh> bg a -bg a - -/bin/echo tsh> fg 9999999 -fg 9999999 - -/bin/echo tsh> bg 9999999 -bg 9999999 - -/bin/echo tsh> fg %2 -fg %2 - -/bin/echo tsh> fg %1 -fg %1 - -SLEEP 2 -TSTP - -/bin/echo tsh> bg %2 -bg %2 - -/bin/echo tsh> bg %1 -bg %1 - -/bin/echo tsh> jobs -jobs - - - diff --git a/trace15.txt b/trace15.txt deleted file mode 100644 index 2cc780e..0000000 --- a/trace15.txt +++ /dev/null @@ -1,46 +0,0 @@ -# -# trace15.txt - Putting it all together -# - -/bin/echo tsh> ./bogus -./bogus - -/bin/echo tsh> ./myspin 10 -./myspin 10 - -SLEEP 2 -INT - -/bin/echo -e tsh> ./myspin 3 \046 -./myspin 3 & - -/bin/echo -e tsh> ./myspin 4 \046 -./myspin 4 & - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> fg %1 -fg %1 - -SLEEP 2 -TSTP - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> bg %3 -bg %3 - -/bin/echo tsh> bg %1 -bg %1 - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> fg %1 -fg %1 - -/bin/echo tsh> quit -quit - diff --git a/trace16.txt b/trace16.txt deleted file mode 100644 index 822ba14..0000000 --- a/trace16.txt +++ /dev/null @@ -1,16 +0,0 @@ -# -# trace16.txt - Tests whether the shell can handle SIGTSTP and SIGINT -# signals that come from other processes instead of the terminal. -# - -/bin/echo tsh> ./mystop 2 -./mystop 2 - -SLEEP 3 - -/bin/echo tsh> jobs -jobs - -/bin/echo tsh> ./myint 2 -./myint 2 - diff --git a/tsh.cc b/tsh.cc index 6c291ab..a0d425c 100644 --- a/tsh.cc +++ b/tsh.cc @@ -363,9 +363,15 @@ void do_bgfg(char **argv) { LOG << "fg" << endl; j->state = FG; + + sigset_t prev_with_sigchld_blocked = prev; + sigaddset(&prev_with_sigchld_blocked, SIGCHLD); + sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL); kill(-(j->pid), SIGCONT); - sigprocmask(SIG_SETMASK, &prev, NULL); + waitfg(j->pid); + + sigprocmask(SIG_SETMASK, &prev, NULL); } else // bg { LOG << "bg" << endl; @@ -388,7 +394,7 @@ void waitfg(pid_t pid) { sigset_t prev_with_sigchld_unblocked; // get current blocked signals - sigprocmask(0, NULL, &prev_with_sigchld_unblocked); + sigprocmask(0, nullptr, &prev_with_sigchld_unblocked); sigdelset(&prev_with_sigchld_unblocked, SIGCHLD); LOG << "waiting for pid "<< fgpid(jobs) << endl; while (fgpid(jobs) != 0) -- cgit v1.3.1-4-g156e