?? sdriver.pl.svn-base
字號:
#!/usr/bin/perl#!/usr/local/bin/perluse 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 <n> Sleep for <n> seconds# ######################################################################## usage - print help message and terminate#sub usage { printf STDERR "$_[0]\n"; printf STDERR "Usage: $0 [-hv] -t <trace> -s <shellprog> -a <args>\n"; printf STDERR "Options:\n"; printf STDERR " -h Print this message\n"; printf STDERR " -v Be more verbose\n"; printf STDERR " -t <trace> Trace file\n"; printf STDERR " -s <shell> Shell program to test\n"; printf STDERR " -a <args> Shell arguments\n"; printf STDERR " -g Generate output for autograder\n"; die "\n" ;}# Parse the command line argumentsgetopts('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 scriptopen 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 pidif ($grade) { print ("pid=$pid\n");}# # Parent reads a trace file, sends commands to the child shell. #while (<INFILE>) { $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 = <Reader>) { print $line;}close Reader;# Finally, parent reaps childwait;if ($verbose) { print "$0: Shell terminated\n";}exit;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -