1. Homepage
  2. Programming
  3. CS537 Introduction to Operating Systems - Project 3: Build a Unix Shell - wsh

CS537 Introduction to Operating Systems - Project 3: Build a Unix Shell - wsh

Engage in a Conversation
WISCCS537Introduction to Operating SystemsBuild a Unix ShellwshCC++

title: CS 537 Project 3 layout: default CourseNana.COM


CS537 Fall 2024, Project 3

Updates

  • TBD

Administrivia

  • A few sample tests are provided in the project repository. To run them, execute run-tests.sh in the tests/ directory. Try run-tests.sh -h to learn more about the testing script. Note these test cases are not complete, and you are encouraged to create more on your own.
  • Handing it in: Copy the whole project, including solution and tests folder, to ~cs537-1/handin/$login/p3 where $login is your CS login.
  • Slip Days: CourseNana.COM

    • In case you need extra time on projects, you each will have 2 slip days for the first 3 projects and 2 more for the final three. After the due date we will make a copy of the handin directory for on time grading. CourseNana.COM

    • To use a slip days or turn in your assignment late you will submit your files with an additional file that contains only a single digit number, which is the number of days late your assignment is (e.g. 1, 2, 3). Each consecutive day we will make a copy of any directories which contain one of these slipdays.txt files. This file must be present when you submit you final submission, or we won't know to grade your code. CourseNana.COM

    • We will track your slip days and late submissions from project to project and begin to deduct percentages after you have used up your slip days. CourseNana.COM

    • After using up your slip days you can get up to 90% if turned in 1 day late, 80% for 2 days late, and 70% for 3 days late, but for any single assignment we won't accept submissions after the third days without an exception. This means if you use both of your individual slip days on a single assignment you can only submit that assignment one additional day late for a total of 3 days late with a 10% deduction. CourseNana.COM

    • Any exception will need to be requested from the instructors. CourseNana.COM

    • Example of slipdays.txt: CourseNana.COM

$ cat slipdays.txt
1

⚠️Warnings⚠️

  • This project will be checked for memory leaks!
  • This project will be examined during in-person code review sessions!
  • This project is time consuming, start now!

Before you start - Makefile

The first task in this project is to create a Makefile. A Makefile is an easy and powerful way to define complex operations in your project and execute them using make in a simple way. You can read more about make and Makefiles in GNU's Make Manual, Makefile Tutorial and Lab Tutorial. CourseNana.COM

Your Makefile must include at least following variables: CourseNana.COM

  • CC specifying the compiler. Please use gcc or clang.
  • CFLAGS specifying the arguments for compilation. Use at least the following: -Wall -Wextra -Werror -pedantic -std=gnu18
  • LOGIN specifying you login.
  • SUBMITPATH specifying the path where you handin your files.
  • $@ has to be used at least once.
  • $< or $^ has to be used at least once.

Your Makefile must include at least following targets: CourseNana.COM

  • all is the first target in your Makefile and runs wsh and wsh-dbg targets. all is a .PHONY target. Creating all target as a first target is a common convention, since the first target is executed when make is called without a target.
  • wsh is a target which depends on wsh.c and wsh.h and builds the wsh binary with the compiler specified in CC and compiler flags in CFLAGS. The compilation must produce -O2 optimized binary. Hence make wsh will compile your code and create wsh binary.
  • wsh-dbg is a target which depends on wsh.c and wsh.h and builds the wsh-dbg binary with the compiler specified in CC and compiler flags in CFLAGS. This binary is not optimized and is to be used for debugging with gdb. I.e. use -Og -ggdb flags. make wsh-dbg will compile your code and create wsh-dbg binary.
  • clean removes binaries from the current directory. I.e. it just keeps source files. Must be called before submission.
  • submit target automatically submits your solution according to the submission instructions above. This means, that you should submit your project simply by typing make submit.

We encourage you to create your own simple tests while developing your shell. It is very helpful to create a test target in your Makefile, which will compile your code and run all your tests. Like this, you can speed up your development and make sure, that every change in your source code still passes your tests (i.e. after every change of you source code, you can just type make test and the shell will be compiled and tested). CourseNana.COM

Before beginning: Read man 3p fork and man 3p exec. CourseNana.COM

Unix Shell

In this project, you’ll build a simple Unix shell. The shell is the heart of the command-line interface, and thus is central to the Unix/C programming environment. Mastering use of the shell is necessary to become proficient in this world; knowing how the shell itself is built is the focus of this project. CourseNana.COM

There are three specific objectives to this assignment: CourseNana.COM

  • To further familiarize yourself with the Linux programming environment.
  • To learn how processes are created, destroyed, and managed.
  • To gain exposure to the necessary functionality in shells.

Overview

In this assignment, you will implement a command line interpreter (CLI) or, as it is more commonly known, a shell. The shell should operate in this basic way: when you type in a command (in response to its prompt), the shell creates a child process that executes the command you entered and then prompts for more user input when it has finished. CourseNana.COM

The shell you implement will be similar to, but simpler than, the one you run every day in Unix. If you don't know what shell you are running, it’s probably bash or zsh (try echo $SHELL). One thing you should do on your own time is to learn more about your shell, by reading the man pages or other online materials. Also, when you are in doubt about some behavior in this assignment, try the behavior in bash before you ask. Maybe it makes things clear. Or not, and you will come to office hours (preferably) or ask on Piazza. CourseNana.COM

Program Specifications

Basic Shell: wsh

Your basic shell, called wsh (short for Wisconsin Shell, naturally), is basically an interactive loop: it repeatedly prints a prompt wsh> (note the space after the greater-than sign), parses the input, executes the command specified on that line of input, and waits for the command to finish. This is repeated until the user types exit. The name of your final executable should be wsh. CourseNana.COM

The shell can be invoked with either no arguments or a single argument; anything else is an error. Here is the no-argument way: CourseNana.COM

prompt> ./wsh
wsh> 

At this point, wsh is running, and ready to accept commands. Type away! CourseNana.COM

The mode above is called interactive mode, and allows the user to type commands directly. The shell also supports a batch mode, which instead reads input from a batch file and executes commands from therein. Here is how you run the shell with a batch file named script.wsh: CourseNana.COM

prompt> ./wsh script.wsh

One difference between batch and interactive modes: in interactive mode, a prompt is printed (wsh>). In batch mode, no prompt should be printed. CourseNana.COM

You should structure your shell such that it creates a process for each new command (the exception are built-in commands, discussed below). Your basic shell should be able to parse a command and run the program corresponding to the command. For example, if the user types cp -r /tmp /tmp2, your shell should run the program /bin/cp with the given arguments -r, /tmp and /tmp2 (how does the shell know to run /bin/cp? It’s something called the shell path; more on this below). CourseNana.COM

Structure

Basic Shell

The shell is very simple (conceptually): it runs in a while loop, repeatedly asking for input to tell it what command to execute. It then executes that command. The loop continues indefinitely, until the user types the built-in command exit, at which point it exits. That’s it! CourseNana.COM

For reading lines of input, you should use strtok() and we guarantee that each token is delimited by a single space. Generally, the shell will be run in interactive mode, where the user types a command (one at a time) and the shell acts on it. However, your shell will also support batch mode, in which the shell is given an input file of commands; in this case, the shell should not read user input (from stdin) but rather from this file to get the commands to execute. CourseNana.COM

In either mode, if you hit the end-of-file marker (EOF), you should call exit(0) and exit gracefully. EOF can be generated by pressing Ctrl-D. CourseNana.COM

To execute commands, look into fork(), exec(), and wait()/waitpid(). See the man pages for these functions, and also read the relevant book chapter for a brief overview. CourseNana.COM

You will note that there are a variety of commands in the exec family; for this project, you must use execv. You should not use the system() library function call to run a command. Remember that if execv() is successful, it will not return; if it does return, there was an error (e.g., the command does not exist). The most challenging part is getting the arguments correctly specified. CourseNana.COM

Comments and executable scripts

In your shell, you should ignore all lines starting with #. Note that there can be spaces (`) in front of#. These lines serve as comments in most shells you will work with (bash, zsh`). CourseNana.COM

Furthermore, once you implement comments, you should be able to create wsh script, which can be directly executed. For example, if you put following script (let's call it script.wsh) into a directory with your compiled wsh binary, you must be able to run the script by typing ./script.wsh. CourseNana.COM

$ cat > script.wsh <<EOF
#!./wsh

echo hello
EOF

$ chmod +x script.wsh
$ ./script.wsh
hello

If you are curious, the first line in the script (#!./wsh) is called shebang and it tells OS how to deal with this executable. There is a wiki page about it. CourseNana.COM

Redirections

Our shell will also support redirections as for example bash does. Please check Redirections in Bash Manual to learn about this powerful feature. To simplify the assignment, wsh supports only following and we guarantee, that the redirection token is always the last one on the command line, i.e. after all the command parameters. Also there can be a at most one redirection per command. CourseNana.COM

  • Redirecting Input. The token always look like [n]<word. I.e. no spaces around <.
  • Redirecting Output. The token always look like [n]>word. I.e. no spaces around >.
  • Appending Redirected Output. The token always look like [n]>>word. I.e. no spaces around >>.
  • Redirecting Standard Output and Standard Error at once. The token always look like &>word. I.e. no spaces around &>.
  • Appending Standard Output and Standard Error at once. The token always look like &>>word. I.e. no spaces around &>>.

Examples of redirection: CourseNana.COM

wsh> echo hello &>>log.txt
wsh> cat <input.txt

Environment variables and shell variables

Every Linux process has its set of environment variables. These variables are stored in the environ extern variable. You should use man environ to learn more about this. CourseNana.COM

Some important things about environment are the following: CourseNana.COM

  1. When fork is called, the child process gets a copy of the environ variable.
  2. When a system call from the exec family of calls is used, the new process is either given the environ variable as its environment or a user specified environment depending on the exact system call used. See man 3 exec.
  3. There are functions such as getenv and setenv that allow you to view and change the environment of the current process. See the man environ for more details.

Shell variables are different from environment variables. They can only be used within shell commands, are only active for the current session of the shell, and are not inherited by any child processes created by the shell. CourseNana.COM

We use the built-in local command to define and set a shell variable: CourseNana.COM

local MYSHELLVARNAME=somevalue

The variable never contains space (`) hence there is no need nor special meaning of quotes (""`). CourseNana.COM

This variable can then be used in a command like so: CourseNana.COM

cd $MYSHELLVARNAME

which will translate to CourseNana.COM

cd somevalue

In our implementation of shell, a variable that does not exist should be replaced by an empty string. An assignment to an empty string will clear the variable. CourseNana.COM

Environment variables may be added or modified by using the built-in export command like so: CourseNana.COM

export MYENVVARNAME=somevalue

After this command is executed, the MYENVVARNAME variable will be present in the environment of any child processes spawned by the shell. CourseNana.COM

Variable substitution: Whenever the $ sign is used in a command, it is always followed by a variable name. Variable values should be directly substituted for their names when the shell interprets the command. Tokens in our shell are always separated by white space, and variable names and values are guaranteed to each be a single token. For example, given the command mv $ab $cd,, you would need to replace variables ab and cd. If a variable exists as both the environment variable and a shell variable, the environment variable takes precedence. CourseNana.COM

You can assume the following when handling variable assignment: CourseNana.COM

  • There will be at most one variable assignment per line.
  • Lines containing variable assignments will not include pipes or any other commands.
  • The entire value of the variable will be present on the same line, following the = operator. There will not be multi-line values; you do not need to worry about quotation marks surrounding the value.
  • Variable names and values will not contain spaces or = characters.
  • There is no limit on the number of variables you should be able to assign.

Displaying Variables: The env utility program (not a shell built-in) can be used to print the environment variables. For local variables, we use a built-in command in our shell called vars. Vars will print all of the local variables and their values in the format <var>=<value>, one variable per line. Variables should be printed in insertion order, with the most recently created variables printing last. Updates to existing variables will modify them in-place in the variable list, without moving them around in the list. Here's an example: CourseNana.COM

wsh> local a=b
wsh> local c=d
wsh> vars
a=b
c=d
wsh> 

Paths

In our original example in the beginning, the user typed cp and the shell knew it has to execute the program /bin/cp. How does your shell know this? CourseNana.COM

It turns out that the user must specify a path variable to describe the set of directories to search for executables; the set of directories that comprise the path are sometimes called the search path of the shell. The path variable contains the list of all directories to search, in order, when the user types a command. CourseNana.COM

Important: Note that the shell itself does not implement cp or other commands (except built-ins). All it does is find those executables in one of the directories specified by path and create a new process to run them. Try echo $PATH to see where your shell looks for executables. CourseNana.COM

To check if a particular file exists in a directory and is executable, consider the access() system call. For example, when the user types cp, and path is set to include both /usr/bin and /bin (assuming empty path list at first, /bin is added, then /usr/bin is added), try access("/usr/bin/cp", X_OK). If that fails, try /bin/cp. If that fails too, it is an error. CourseNana.COM

Your initial shell path should contain one directory: /bin CourseNana.COM

Of course, your shell still can execute programs specified by full path, e.g. /usr/bin/ls, or relative path, e.g. cd /usr; ./bin/ls or cd /usr; bin/ls. CourseNana.COM

In general, the priority what to execute is following, where 1 is the highest priority: CourseNana.COM

  1. Built-in.
  2. Full or relative path.
  3. Paths specified by $PATH.

History

Your shell will also keep track of the last five commands executed by the user. Use the history builtin command to show the history list as shown here. If the same command is executed more than once consecutively, it should only be stored in the history list once. The most recent command is number one. Builtin commands should not be stored in the history. CourseNana.COM

wsh> history
1)  man sleep
2)  man exec
3)  rm -rf a
4)  mkdir a
5)  ps

By default, history should store up to five commands. The length of the history should be configurable, using history set <n>, where n is an integer. If there are fewer commands in the history than its capacity, simply print the commands that are stored (do not print blank lines for empty slots). If a larger history is shrunk using history set, drop the commands which no longer fit into the history. CourseNana.COM

To execute a command from the history, use history <n>, where n is the nth command in the history. For example, running history 1 in the above example should execute man sleep again. Commands in the history list should not be recorded in the history when executed this way. This means that successive runs of history n should run the same command repeatedly. CourseNana.COM

If history is called with an integer greater than the capacity of the history, or if history is called with a number that does not have a corresponding command yet, it will do nothing, and the shell should print the next prompt. CourseNana.COM

Built-in Commands

Whenever your shell accepts a command, it should check whether the command is a built-in command or not. If it is, it should not be executed like other programs. Instead, your shell will invoke your implementation of the built-in command. For example, to implement the exit built-in command, you simply call exit(0); in your wsh source code, which then will exit the shell. CourseNana.COM

Here is the list of built-in commands for wsh: CourseNana.COM

  • exit: When the user types exit, your shell should simply call the exit system call with 0 as a parameter. It is an error to pass any arguments to exit.
  • cd: cd always take one argument (0 or >1 args should be signaled as an error). To change directories, use the chdir() system call with the argument supplied by the user; if chdir fails, that is also an error.
  • export: Used as export VAR=<value> to create or assign variable VAR as an environment variable.
  • local: Used as local VAR=<value> to create or assign variable VAR as a shell variable.
  • vars: Described earlier in the "environment variables and shell variables" section.
  • history: Described earlier in the history section.
  • ls: Produces the same output as LANG=C ls -1, however you cannot spawn ls program because this is a built-in. This built-in does not implement any parameters.

Miscellaneous Hints

Remember to get the basic functionality of your shell working before worrying about all of the error conditions and end cases. For example, first get a single command running (probably first a command with no arguments, such as ps). CourseNana.COM

Next, add built-in commands. Then, try working on command history, redirections, and variables. Each of these requires a little more effort on parsing, but each should not be too hard to implement. It is recommended that you separate the process of parsing and execution - parse first, look for syntax errors (if any), and then finally execute the commands. CourseNana.COM

We simplify the parsing by having a single space ` as the only allowed delimiter. It means that any token on the command line will be delimited by a single space ` in our tests. CourseNana.COM

Check the return codes of all system calls from the very beginning of your work. This will often catch errors in how you are invoking these new system calls. It’s also just good programming sense. CourseNana.COM

Beat up your own code! You are the best (and in this case, the only) tester of this code. Throw lots of different inputs at it and make sure the shell behaves well. Good code comes through testing; you must run many different tests to make sure things work as desired. Don't be gentle – other users certainly won't be. CourseNana.COM

Finally, keep versions of your code. More advanced programmers will use a source control system such as git. You don't need to push the repository to the Internet, but you can still do commits and benefit from the history tracking (this approach is recommended). Minimally, when you get a piece of functionality working, make a copy of your .c file (perhaps a subdirectory with a version number, such as v1, v2, etc.). By keeping older, working versions around, you can comfortably work on adding new functionality, safe in the knowledge you can always go back to an older, working version if need be. CourseNana.COM

Error conditions should result in wsh terminating with an exit code of -1. Non-error conditions should result in an exit code of 0. CourseNana.COM

Get in Touch with Our Experts

WeChat (微信) WeChat (微信)
Whatsapp WhatsApp
WISC代写,CS537代写,Introduction to Operating Systems代写,Build a Unix Shell代写,wsh代写,C代写,C++代写,WISC代编,CS537代编,Introduction to Operating Systems代编,Build a Unix Shell代编,wsh代编,C代编,C++代编,WISC代考,CS537代考,Introduction to Operating Systems代考,Build a Unix Shell代考,wsh代考,C代考,C++代考,WISChelp,CS537help,Introduction to Operating Systemshelp,Build a Unix Shellhelp,wshhelp,Chelp,C++help,WISC作业代写,CS537作业代写,Introduction to Operating Systems作业代写,Build a Unix Shell作业代写,wsh作业代写,C作业代写,C++作业代写,WISC编程代写,CS537编程代写,Introduction to Operating Systems编程代写,Build a Unix Shell编程代写,wsh编程代写,C编程代写,C++编程代写,WISCprogramming help,CS537programming help,Introduction to Operating Systemsprogramming help,Build a Unix Shellprogramming help,wshprogramming help,Cprogramming help,C++programming help,WISCassignment help,CS537assignment help,Introduction to Operating Systemsassignment help,Build a Unix Shellassignment help,wshassignment help,Cassignment help,C++assignment help,WISCsolution,CS537solution,Introduction to Operating Systemssolution,Build a Unix Shellsolution,wshsolution,Csolution,C++solution,