CMSC 216 Project #6 Spring 2019A Simple Shell Fri May 3, 11:30PM, Tue May 7, 11:30PM1 OverviewIn this project, you will write the guts of a shell that will support boolean operations, pipes, and file redirection.The project has two deadlines: Fri May 3, 11:30PM - Your code must pass the following public tests: public00/01/02/06/07/11. That isthe only requirement for this deadline. We will not grade the code for style. This first part is worth .5%of your course grade (NOT .5% of this project grade). Notice you can still submit late for this part. Tue May 7, 11:30PM - Final deadline for the project. Notice you can still submit late (as usual).2 Procedure2.1 Obtain the project filesWe have supplied several files for your use in this project:command.h defines the tree structure that the parser will produce from a command line, and the conjunctionsthat join commands into a line.d8sh.c is the main shell loop. You need not modify this file, but it may be useful to inspect for generating testcases.executor.c is where you must implement the function int execute(struct tree *t), which will take a treefrom the parser and execute the commands in the tree. The return value of execute may be used as youlike, e.g., for exit status or for a process id, if you choose to call execute recursively.executor.h is the declaration of execute, used by the parser.lexer.c is the lexer, which splits a command line into tokens, generated by flex.lexer.h declares lexer related functions referenced by d8sh.parser.tab.c is the parser, which assembles tokens into a parsed tree, generated by bison.parser.tab.h is a part of the parser, generated by bison, referenced by lexer.c.run-all-tests.csh checks for Makefile and d8sh, then compares the output of your d8sh using the commandlines in the testing subdirectory.These files are contained in ~/216public/project6. Your code for this project should be contained in your~/216/project6 subdirectory.2.2 Create a MakefileCreate a Makefile that we will use to build your shell. Section 3.1 lists the targets you are required to implement,as well as other requirements for your Makefile.2.3 Implement and test the shellYou must implement your shell program by supplying the necessary code in executor.c. As you implementvarious features of the shell, you can test them by either interactively running d8sh while typing in commands,or you can create text files with one command per line, and use redirection to feed them as input to your shell.The video https://tinyurl.com/yadjttla can help you understand what you need to implement for thisproject. Start watching the video at time 19:13.13 Specifications3.1 MakefileYour Makefile should be set up so that all programs are built using separate compilation (i.e., source files areturned into object files, which are then linked together in a separate step). All object files should be built usingthe class flags.You must have the following targets in your Makefile:1. all: make all executables2. clean: delete all object files and executables3. lexer.o, parser.tab.o, executor.o, and d8sh.o, the object files for the parsing code and shell code4. d8sh: the executable created by linking the parsing object file with the shell object files and linked withthe readline library using -lreadline.We will use the Makefile you provide to build the public test executables on the submit server; if there is noMakefile, your shell program will not be built, and you will not receive credit for any tests.You may have other targets, for example “test”.3.2 The ShellThe shell you will implement will include some, but not all features, of the shell you use on grace. The featuresyour shell supports will include pipes, input and output redirection, and the “&&” operator.The parser may permit a few more operations that you need not support. In particular, the “||” and “;”operators exist in the format, but need not be supported by your code.To invoke the parser, d8sh uses readline(), then yy_scan_string(buffer), followed by yyparse(). (Typically,a bison parser would load a file such as your C source. Here, we are using this system to operate on astring.) When the parser constructs a complete tree from a command line, it invokes your execute() function.You are given the main shell program in d8sh.c: your task is to implement the execute() function called bymain(). Once the full d8sh program is linked together from the four object files, d8sh should function as anormal shell, with some limitations as described below.The syntax for the features we want you to implement is very similar to the shell syntax you should be familiarwith from your experience working with the Unix environment. These are the specific features your shell mustprovide:1. File redirection: by using the tokens, a user should be able to redirect standard input and outputin the same manner as is done in the tcsh and bash shells.If a file is created by output redirection, the file should be created using permissions 0664.In the case of a multi-program pipeline, file input redirection may be applied to the first program (beforethe first pipe character), and file output redirection may be applied to the final program. A shell mustprint “Ambiguous input redirect.” or “Ambiguous output redirect.” if a user tries to provide a redirectedfile and a pipe at the same time. For example, the following is illegal “echo hello > x | cat”.2. Piping: if programs are separated by pipe characters (“|”) on a command line, then the standard outputof the program to the left of the pipe character is to be connected to the standard input of the programto the right of the pipe character, creating a pipeline.When running a pipeline, the shell must start all of the processes, but not return to print another promptuntil all processes have exited. You will need to determine how to fork all the processes piped togetherand then wait for them all to finish.23. Subshells: when expressions are surrounded by parentheses, the command is executed in its own shell,forked from the parent. This ensures that environment changes (such as changing the current directory)are contained to the subshell.As you can see from the code in d8sh.c, the shell prompts the user for a command, parses the command, andthen attempts to execute the command. To execute the command, you must use the struct tree * parameterto see which options are set, and perform the steps necessary to execute the command as requested.Should you encounter any errors in executing the command, your shell must not terminate – children ofthe shell may terminate, but the code you write in execute() must not cause the parent (shell) process toterminate. A user should not cause the shell to die because he/she, for example, mistyped the name of aprogram to execute.If your shell cannot exec any process, it should print, “Failed to execute %s” with the name of the programthat failed. Other failed system calls should print using perror, e.g., perror(fork). The shell is alreadyconfigured for parse errors to print as “Parse error: %s” via the yyerror() function.4 Example TreesYou may want to print out the contents of each parse tree you work on. Here are some examples.�echo hello && echo goodbye | grep ooNote that the pipe operation has a higher precedencethan and. As a result, “hello” is printed to stdoutand does not pass through grep. The grep commandprints all lines that include a given string, so willprint “goodbye” because it includes “oo”.�cat command.h | cat | cat | cat | catThe “cat” tool can either read input from argumentsor from stdin, then pass it to stdout. Using pipe, fork,dup2, and exec to build pipelines in tree for代写CMSC 216作业、c/c++程序语言作业调试、代写Shell留学生作业、代做c/c++课程设计作业 调试Matlm can besubtle. The contents of command.h should appearon the output. (This is a better example than it is atest; tests may use tac instead of cat to reverse thefile.)�l rtrue && false && [ -e a.c ] && echo 2-1 | bc && [ -x b.c ]Again, pipe has a higher precedence. Executionshould stop at the first false. true runs the/usr/bin/true program, whose only purpose is toexit(0), a successful result. (See: “man true” and“man false” for more information. There are a fewtrivial programs like this, for example, “yes” and“seq”. You must use the wait() or waitpid() functionsto determine whether the program exited successfully).SUBSHELL�(head -2 && head -2) Note how the shell prints the first four lines of lexer.hif given this command. Beware, however, the firsthead command might use buffered I/O and therebyslurp more data than just the first two lines, leavingthe second head command to print two lines fromthe middle of a longer file. (It does work on graceand submit.) More reliable would be to redirect outputinstead of input.�pwd && cd .. && pwdThis will output the current directory, change to itsparent, and output the parent. For the next command,the current directory will be the parent.�(pwd && cd ..) && pwdThis will output the current directory and change toits parent in a subshell, then output the current directoryagain (unchanged). For the next command,the current directory will unchanged.mkdir ../bkup && tar cf - . | (cd ../bkup && tar xf -)This is an example of using cd in a subshell in practiceto backup a directory. The cd affects only thesecond tar (extract rather than create). This creates adirectory, ../otherdir, then copies the contents of thecurrent directry into it using tar. The current workingdirectory after this command is unchanged (notbkup). From a subshell, environment (working directory)changes do not escape.�(cd ../bkup && tar cf - .) | tar xf -If the previous example created a backup, this onerestores it. The cd affects only the first tar, leavingthe current working directory for the next commandwhere it was. The command will fail if “bkup” is notpresent.55 Important Points and Hints1. Start by handling nodes with conjunction NONE, i.e., no pipes, no ands. Add redirection, pipes, and theand operation incrementally.2. execute() must implement internally the commands “cd” and “exit”. The “cd” command should changeto the user’s home directory (getenv(HOME)) if given no arguments.3. Be sure to wait for all child processes of your shell to complete; failing to do so will cause a collection ofzombie processes to accumulate and tie up Grace system resources.4. Be careful that any fork loops you write terminate at some point, before a Grace system administratorhas to kill them.5. You may wish to print the contents of the tree before execution. Each node is either an internal node ofthe tree, representing a PIPE or an AND, or a leaf node, representing a command with argv set. Anynode, including internal nodes may have input and output redirection. Your shell should mimic realshells for the following commands:(head && head) (head (cat command.h | cat - command.h)(cat 6. You are permitted to translate the tree structure into whatever representation you prefer. (This is notencouraged.)7. You need not free the data or nodes in the parse tree. Yes, this will leak memory.8. Closing the correct file descriptors for a pipe at the correct time can be tricky. All the file descriptors forwriting must be closed before a reader will see the end of file and exit. If the shell hangs, there’s probablya process waiting for more input that will never come.9. Don’t get excited and modify the shell prompt to make it look more shell like; that may have bad consequenceson the submit server.10. Please consider using git locally to track your changes; for example, supporting AND may break yourdesign for PIPE, and it may be useful to go back in time to find your working solution.11. Make sure your executor.c file has your student id (e.g., 111XXX...) NOT your directory id. There aretests that check for the presence of this id.12. Make sure you code compiles without warnings, otherwise you will lose credit. Make sure you commentout the print tree function provided with executor.c once you have no longer use for it. There are teststhat check for warnings.13. You need to add to executor.c any .h files that allow you to fork, exec*, etc.14. The message ”Failed to execute %s” ... should be sent to standard error.15. Use standard output for ambiguous output redirect and ambiguous input redirect messages.16. If chdir fails, use perror to print an error message. For example, perror(location) where location is thedirectory.17. If both ambiguous input and output redirect take place, only one message will be printed ( ”Ambiguousoutput redirect.” )6 Grading CriteriaYour project grade will be determined by the following formula:Results of public tests 40%Results of secret tests 60%6The public tests will be made available shortly after the project is released. You can find out your results onthese tests by checking the submit server a few minutes after submitting your project. Secret tests, and theirresults, will not be released until after the project’s late deadline has passed.Public tests for this project consist of input files to be read by your shell via standard input, and checkedagainst the expected output, for example like this:./d8sh We’ve put the public tests in the testing subdirectory, and some of these tests use extra input files from thecurrent directory. The run-all-tests.csh script temporarily links those files to the current directory. Considerinspecting that script for more examples of booleans in shell commands.7 Submission7.1 DeliverablesThe only files we will grade are (a) your Makefile; and (b) executor.c, which contains your shell implementation.We will use our versions of all other files to build tests, so do not make any changes to other files.7.2 ProcedureTo limit the number of processes your shell implementation can create when you run it on the Grace machines,ensure that the line limit maxproc 20 is present in the .cshrc.mine file in your home directory. This is partof the 216 setup script. Run “limit” to check that it is set.1As for previous projects, executing “submit” in your project directory will submit your project. We encourageyou to run public tests on Grace rather than submitting to the submit server and waiting for your submissionto be evaluated; it is much faster for you to see your results if you run the tests yourself, and the submit serverworks much more quickly if the class makes fewer submissions.8 Other Notes8.1 Academic IntegrityAs noted in the syllabus, any evidence of cheating will be referred to the Student Honor Council and mayresult in a grade of XF in this course. Submissions will be checked with an automated source code comparisontool to look for evidence of copying, collaborative work, and use of prohibited online materials.8.2 DeadlinesSubmission deadlines are strictly enforced by the submit server, and we will not extend them for events suchas network outages. Extensions may be given on a case-by-case basis, but will likely only be granted formedical or other unforseeable cases. Therefore, you should start work on this project soon, as last-minutetechnical problems are not an excuse for missing either the on-time or late deadline.1If you use bash instead of tcsh, the command is ulimit -u 20 .7转自:http://ass.3daixie.com/2019050213374712.html