W4118 Fall 2017
UPDATED: Monday 9/11/2017 at 6:55pm EDT
DUE: Wednesday 9/20/2017 at 11:59pm EDT
All homework submissions are to be made via Git.
You must submit a detailed list of references as part your homework
submission indicating clearly what sources you referenced for each
homework problem. You do not need to cite the course textbooks and
instructional staff. All other sources must be cited.
You will be using Git via GitHub for course submissions for the class.
Please make sure you sign up for a GitHub account if you do not yet
have one, and follow the
the W4118 GitHub organization, including filling out the Google Form
listed there so that we can associate your GitHub username with your
Once you have a GitHub account and login, you can create your GitHub
repository for this assignment.
The GitHub repository you will use can be cloned using
git clone email@example.com:W4118/f17-hmwk1-UserName.git (Replace UserName with your
own GitHub username).
Be aware that commits pushed after the deadline will not be
Refer to the homework policy section on the
site for further details.
Exercise numbers refer to the course textbook, Operating
System Concepts Essentials. Each problem is worth 3 points.
- Exercise 1.4
- Exercise 1.6
- Exercise 1.13
- Exercise 1.19
- Exercise 1.21
- Exercise 2.1
- Exercise 2.12
- Exercise 2.16
- Exercise 2.18
- Exercise 2.24
For all programming problems you will be required to submit
source code, a makefile, a README file documenting your files and code,
and a test run of your programs. The README should explain any way in
which your solution differs from what was assigned, and any
assumptions you made. Refer to the homework submission page on the
class web site for additional submission instructions.
The shell is just another program. For example, the Bash shell is an executable named bash that is usually located in the /bin directory. So, /bin/bash.
Try running /bin/bash or just bash on a Linux (or BSD-based, such as Mac OS X) operating system's command line, and you'll likely discover that it will successfully run just like any other program. Type exit to end your shell session and return to your usual shell.
(If your system doesn't have Bash, try running sh instead.)
When you log into a computer, this is essentially what happens: Bash is executed. The only special thing about logging in is that a special entry in /etc/passwd determines what shell runs at log in time.
Write a simple shell in C. The requirements are as follows.
- Your shell executable should be named w4118_sh. Your shell source code should be mainly in shell.c, but you are free to add additional source code files as long as your Makefile works, and compiles an executable named w4118_sh.
- The shell should run continuously, and display a prompt when waiting for input. The prompt should be EXACTLY '$'. No spaces, no extra characters. Example with a command:
$/bin/ls -lha /home/w4118/my_docs
- Your shell should read a line from stdin one at a time. This line should be parsed out into a command and all its arguments. In other words, tokenize it.
- You may assume that the only supported delimiter is the whitespace character (ASCII character number 32).
- You do not need to handle "special" characters. Do not worry about handling quotation marks, backslashes, and tab characters. This means your shell will be unable support arguments with spaces in them. For example, your shell will not support file paths with spaces in them.
- You may set a reasonable maximum on the number of command line arguments, but your shell should handle input lines of any length.
- After parsing and lexing the command, your shell should execute it. A command can either be a reference to an executable OR a built-in shell command (see Part 2). For Part 1, just focus on running executables, and not on built-in commands.
- Executing commands that are not shell built-ins and are just the executable name (and not a full path to the executable) is done by invoking fork() and then invoking exec().
- You may NOT use the system() function, as it just invokes the /bin/sh shell to do all the work.
- exit - Simply exits your shell after performing any necessary clean up.
- cd [dir] - Short for "change directory", and will be used to change the current working directory of your shell. Do not worry about implementing the command line options that the real cd command has in Bash. Just implement cd such that it takes a single command line parameter: The directory to change to.
- history [-c] [offset] - Similar to the Bash built-in history command, but much simpler.
- Augment your shell to be capable of executing a sequence of
programs that communicate through a pipe. For example, if the user
types /bin/ls | /usr/bin/wc, your program should fork the two
programs, which together will calculate the number of files in the
directory. For this you will need to replace stdin and
stdout with pipe file descriptors using dup2.
- While this example shows two
processes communicating through a pipe, your shell should support
pipes between multiple processes, not just two.
- You should also support built-in commands to work with pipes. In this case, you will need to handle built-in commands in a different manner as they are not separate programs that need to be forked.
- Error messages should be printed using exactly one of two string formats. The first format is for errors where errno is set. The second format is for when errno is not set, in which case you may provide any error text message you like on a single line.
"error: %s\n", strerror(errno)
"error: %s\n", "your error message"
So for example, you would likely use: fprintf(stderr, "error: %s\n", strerror(errno));.
- Check the return values of all functions utilizing system resources. Do not blithely assume all requests for memory will succeed and all writes to a file will occur correctly. Your code should handle errors properly. Many failed function calls should not be fatal to a program.
Typically, a system call will return -1 in the case of an error (malloc will return NULL). If a function call sets the errno variable (see the function's man page to find out if it does), you should use the first error message as described above. As far as system calls are concerned, you will want to use one of the mechanisms described in Reporting Errors or Error Reporting.
- A testing script skeleton will be
provided in a GitHub repository to help you with testing
your program. You should make sure your program
works correct with this script. For grading purposes, we will
conduct much more extensive testing than what is provided with
the testing skeleton, so you should make sure to write additional test
cases yourself to test your code.
- All code (including test programs) must be written in C.
- Make at least ten commits with Git. The point is to make
incremental changes and use an iterative development cycle.
- Follow the following coding style rules:
- Tab size: 8 spaces.
- Do not have more that 3 levels of indentations (unless the
function is extremely simple).
- Do not have lines that goes after the 80th column (with rare
- Do not comment your code to say obvious things. Use /* ... */
and not // ...
kernel coding style.
Use checkpatch, a script which checks coding style rules.
- Use a makefile to control the compilation of your code. The
makefile should have at least a default target that builds all assigned
- When using gcc to compile your code, use the -Wall switch to ensure that all warnings are displayed. Do not
be satisfied with code that merely compiles; it should compile with no
warnings. You will lose points if your code produces warnings when
- Check the return values of all functions utilizing system
resources for all parts of the programming assignment.
- Your code should not have memory leaks and should handle errors gracefully.
- Per the
Class Collaboration/Copying Policy, please
include in your submission a
separate references.txt file with a
list of references to materials that you used to complete your
assignment, including URLs to websites and names of other students
you asked for help.
- For this assignment, your primary reference will be Programming in C. You might also find the Glibc Manual useful.
- Many questions about functions and system behaviour can be found in the system manual pages; type in man function to get more information about function. If function is a system call, man 2 function can ensure that you receive the correct man page, rather than one for a system utility of the same name.
- If you are having trouble with basic Unix/Linux behavior, you
might want to check out the resources section of the class webpage.
- A lot of your problems have happened to other people. If you
have a strange error message, you might want to try searching for the
message on Google.