首页 > > 详细

COMP 3430 - Operating Systems Assignment 2

General submission requirements
Submissions that violate any of the following will not be evaluated (i.e., you will receive a score of 0 for the assignment):
All solutions must be written in C. No other languages are accepted.
All solutions must include a working Makefile.
oForget how to make a Makefile? Never knew how to make a Makefile? Thankfully, you can go to https://makefiletutorial.com and find some very easy to use basic examples.
oYour Makefile should contain a clean rule. When
make clean
is run in your directory, all the temporary files, including the executable should be removed (e.g., rm -f my_prog).
All solutions must be compiled by issuing the command make in the directory containing the Makefile. No other build commands are acceptable, even if documented in the README.md.
All solutions must include a Markdown-formatted README.md file that minimally describes how to run your submission.
oForget how to make a README.md? Never knew how to make README.md? Thankfully, you can go to https://readme.so/ and build a nice, Markdown-formatted README.md with a nice preview and some handy buttons to help you build it.
All solutions must run to successful completion. Premature termination for any reason (no obvious output, Segmentation Fault, Bus Error, etc.) is considered to be a solution implementation that does not run.
Code that runs for an unreasonably long time (e.g., > 30 seconds) without terminating is also considered to be a solution implementation that does not run.
All solutions must compile. Code that does not compile will not be evaluated.
Programs must produce no errors when compiled with the flags
-Wall -Wpedantic -Wextra -Werror
Note that -Werror prevents your code from being compiled when warnings are present.
If these flags are not in your Makefile, your submission will be treated as though it does not compile.
Your code must compile and run on a machine on aviary.cs.umanitoba.ca.
No late submissions will be accepted. The assignment deadline is enforced electronically. Submissions will not be accepted by e-mail.
Reminder: All submitted code will be evaluated using an automated similarity testing tool, alongside commonly available online solutions for problems.
Question 1: The really not at all very good shell ™
Description
If you put your ear to the code and listen really well, you can hear the ocean! (Public Domain)
Operating systems generally come with a shell, some kind of an interface for interacting with the operating system. We’re using command-line shells extensively in this course. When you’re connected to aviary, you’re almost certainly using TCSH (“tee-see-shell”). If you’re using WSL, you’re almost certainly using GNU Bash. If you’re using any recent version of macOS, you’re almost certainly using Zsh (“zee-shell”, but I can’t bring myself to say it, so I always refer to it as “zed-shell”). When you’re looking at my terminal in class, I’m using fish.
Almost universally, you can figure out what command-line shell you’re using by running a command:
echo $SHELL
These shells are all interactive, meaning that there’s a “prompt”, where the shell is waiting for you (the user) to type something in (a command). The shell interprets that command, then does the normal fork(), exec(), wait() dance. When the process it fork()ed finishes, the shell prints out that prompt again, patiently waiting for you to enter another command.
All of these shells also have the ability to execute scripts — you write a sequence of commands into a text file, and run the shell as a program with that file as an argument:
bash my-script.sh
While there still may be some interactivity when running these scripts (prompting you to enter a value), generally these kinds of scripts are non-interactive. A non-interactive invocation of a shell script will just run to completion without ever asking you for input.
Task
Your job is to implement a non-interactive shell with pipe and redirection support. Your program will be provided with a script, where each line is a sequence of commands that may have pipes (|) or redirection operators (< redirect file to standard input and > redirect standard output to file). Your program has the responsibility of doing the fork(), pipe(), exec(), wait() dance for all of the commands in the line of the script.
So, for example, the command
sort -R /usr/share/dict/words | head -5 > random.txt
will invoke the sort command with the arguments -R and /usr/share/dict/words, pipe its standard output to the head command (which was invoked with the argument -5), and the head command will have its standard output written to a file named random.txt. The contents of random.txt in this pipeline will be a random selection of 5 words from /usr/share/dict/words.
You must implement this pipeline from scratch using the appropriate system calls (e.g., pipe(), fork(), dup2(), exec*(), and wait()). When working with pipes, you should explicitly use the read() and write() system calls. When working with files (reading the script and handling the redirection operators < and >), you can safely use the I/O functions from the standard C library (e.g., fopen, fgets, fwrite). You’re also permitted to use the standard string processing functions for deconstructing the command into its components (e.g., strtok, strdup, strchr, etc).
You are explicitly not permitted to pass your script to another shell and have the other shell do the work.
System calls
You’ve used fork(), and wait() in assignment 1.
Our textbook describes using the exec*() family of system calls in Chapter 5, and the pipe() and dup2() system calls are described in Shichao’s notes.
Both of these families of system calls are also well documented in the manual pages.
In terms of the exec*() family of system calls, you’re going to want to use either execve() or execvp(), since they both allow you to pass command-line arguments to the program that you’re exec-ing.
In terms of pipe() and dup2(): you should read the manual page for dup2() but, in summary, you can use this system call to effectively replace a file descriptor. For the purposes of this assignment, you’re going to need to repeatedly replace STDIN_FILENO and STDOUT_FILENO in the child processes that you create using pipes and the dup2() system call (STDIN_FILENO and STDOUT_FILENO are in unistd.h).
The strategy here is: create a pipe in the parent, create the processes on either side of the pipe in the command sequence, then replace the STD{IN,OUT}_FILENO file descriptors on both sides just before running exec*().
Running your program
Your program should take one argument as input, which is the name of the script script it should evaluate.
./trnaavgsh script.sh
Script files
Here is a sample script file that you can use to test your implementation. The sequence of commands increase in complexity as you get further down in the file.
touch touched.txt
ln -sf /usr/share/dict/words
head -5 words > first5words.txt
cat /proc/self/status | grep nonvol > nonvoluntaryswitches.txt
sort -R < words | head -5 > rand5words.txt
sort -R < words | head -5 | sort -d > randsort5words.txt
The commands above depend on each other (e.g., ln -sf has to be run before head -5 words), so the sequence of execution is important.
Assumptions
You can make the following assumptions about script files:
Each a line in a script file will never have more than 100 characters, each sequence of commands will fit completely on one line (i.e., you don’t have to handle commands that continue onto the next line).
Each individual command will be a valid command (e.g., you will never have an individual command that has multiple redirect file to standard in < operators, the name of the program will be an actual program).
If a command within a pipeline has redirection operators (>, <), it will only have one of those kinds of operators. In other words, a command won’t have a file redirected to its standard input and redirect its standard output to a file.
The only command with the redirect standard input operator < will be the first command, and the only command with the redirect standard output operator > will be the last command.
Program names will be separated from their arguments using single whitespace characters.
Checking your output
Since these are just regular commands, you can just run each of them in your actual shell and see what the output is.
Evaluation
Implementation
5 points are awarded for code quality and design. “High quality” is defined as code that follows the standards and best practices that you can find in the “Standards and Best Practices” folder at the root of the Assignments section on UM Learn:
Level Description
0 The code is very poor quality (e.g., no comments at all, no functions, poor naming conventions for variables, etc).
1–3 The code is low quality, while some coding standards are applied, their use is inconsistent (e.g., inconsistent use of comments, some functions but functions might do too much, code is repeated that should be in a function, etc).
This is the maximum level you can earn if the implementation of your program is substantially incomplete.
4–5 the code is high quality, coding standards are applied consistently throughout the code base.
10 points are awarded for implementation (5 × 2):
Level Description
0 Submitted code does not run or compile.
1–2 Submitted code is substantially incomplete (e.g., parsing is implemented, redirection operators may work, pipes may work).
3–4 Submitted code is substantially complete, but still incomplete (e.g., parsing is implemented, redirection operators work, pipes don’t always work correctly).
5 Submitted code is complete and accurate. All scripts appear to work.
Submitting your assignment
Submissions will be made using the handin command available on all CS UNIX systems.
You should be submitting at least the following files:
A Makefile.
A README.md that includes a summary of how to compile and run your programs (compiling should be “run make”, but you should explicitly tell the grader how to run your program, e.g., what arguments to pass to the program on the command line).
Your solution for question 1 (probably just 1 .c file).
If your files are in a folder named my_a1, you would run the command:
handin 3430 a2 my_a2
You can see man handin if you need more information.
General Advice
Here’s some general advice that you can choose to follow or ignore:
1.The debugger is your best friend. Don’t even start trying to solve these problems until you’re comfortable with a debugger (either lldb or gdb). The first question I’m going to ask when you come to ask me for help is: “Have you tried running it through the debugger yet?” If you answer “no”, I’ll send you away to do that first, then come back.
2.Source control is your second best friend. The department hosts an instance of GitLab that you can use to store private projects. You’re also welcome to use private repositories on GitHub.
 
联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!