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 ++++ 17 files changed, 480 insertions(+) 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 (limited to 'autograder') 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 + -- cgit v1.3.1-4-g156e