Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
Directions
Overview
You may freely use any functions in string.h. Please be aware of the accuracy of your output contents, especially because the autograder will take into consideration whitespace for correctness. Even if the functionality is correct, the autograder will mark your submission incorrectly if the output contents are not accurate.
You are provided with starter code for the most of the functionality listed in the Background section. Read through the section carefully to understand what the starter code is accomplishing.
This project is divided into three 3 parts:
Advice
This is a large and complex assignment, using arcane and compactly documented APIs. We do not expect you to be able to complete it without relying on some outside references. That said, we do expect you to struggle a lot, which is how you will learn about systems programming, by doing things yourself.
Even though the project is quite challenging, it is also gratifying based on past experience as long as you pass the learning curve. To be an efficient learner, please make good use of the C - Refresher, GDB tutorial (week 3), TA hours, Open Office Hours, and Recitations. They are excellent supplements to the lectures and have many practical system programming tips to improve your project. If you feel that the current TA hour set-up does not fit your schedule well, please let us know.
Moreover, you are highly encouraged to utilize Ed Discussion to discuss the project with classmates and TAs. Before asking the question, please search in Ed Discussion to see if there are any similar questions asked before. If you plan to ask about your code/implementation, please consider filling in the following template to make the communication efficient. We are here to help you and make sure you get the most out of the course!
1 Background
The following is an example of input that should invoke the catch-phrase:
Here, penn-shredder was executed with a timeout argument of 10 seconds, and any program that runs longer than 10 seconds will be killed (or shredded). The cat program executed without arguments runs indefinitely, and thus was killed after exceeding the timeout. Conversely, pwd returns quickly and was not killed, upsetting shredder and his henchman.
As described previously, a shell is just a loop performing the same procedure over and over again. Essen tially, that procedure can be completed with these four system calls:
The program, in pseudo-code, looks roughly like this:
This may seem simple, but there are many, many things that can go wrong. You should spend some time carefully reading the entire man page for all four of these systems calls. To do so, in a terminal type:
bash# man 2 read
1.2 Executing a Program
The execve(2) system call is the base of a larger collection of functions; however, you may not use those other functions. Explicitly, you may not use execl(3), execv(3)), or any other function listed in the exec(3) manual page. As a result, the user of your shell must specify the entire path to a program to execute it. To learn where a program lives (i.e., its path), use the which program in your non-penn-shredder shell.
1.3 Ctrl-C behavior
Note: The above command ˆC/bin/pwd does not exactly match a real shell program but is the ex pected output for penn-shredder. If you’re curious what that does in a real shell, try it out!
In the starter code, we provide an example of SIGINT signal handler so that the parent process (penn shredder) will kill the child process when it receives Ctrl-C. However, when the child process executes a command, the execve(2) system call will reset the behavior of a handled signal to default as described in signal(7) manual page:
By default, SIGINT will terminate the process so the child process will also get killed by SIGINT in the child process. A command like ”/bin/cat” followed by Ctrl-C could lead to a race condition that both the parent process and the child process try to kill the child process. In the worst case, it may cause an error if the parent process tries to kill a child process which has already been terminated. One way to avoid the race condition is to ignore SIGINT in the child process since the dispositions of ignored signals won’t be changed. You can ignore a signal by setting the disposition of the signal to SIG IGN via the signal(2) system call.
We will not test your signal handling in part A to simplify the learning objectives but we will test it in part B.
1.4 Ctrl-D behavior
For Ctrl-D without text, it is straightforward it should exit the shell if it is not currently running any other process.
For Ctrl-D with text (valid command plus Ctrl-D), i.e. /bin/ls Ctrl-D it should not exit shell without completing current running process and it should go back to ”penn-shredder# ”prompt. The auto-grader will give you a the points as long as your Shredder dose not exit or crash after /bin/ls Ctrl-D. But it would be even better if your Shredder returns the result of /bin/ls.
bash# ./penn-shredder
Note that Ctrl-D is not a signal; while we will only test signal handling in part B, this is not strictly a signal and we will test for Ctrl-D handling in part A.Project 1
2 Project Milestones and Submission
2.1 Part 1A: Do more than ‘ls’!
2.1.1 Prompting and I/O
In programming your shell, you will only use system calls and nothing from the C standard library (except string.h). This includes input and output functions like printf(3) and fgets(3). Instead you will use the read(2) and write(2) system calls. Consult the manual pages for these functions’ specification.
Your shell must prompt the user for input as follows:
Note that the prompt has a white space after the octothorpe, so if a user begins typing, they would see:
This part is already in the starter code.
2.1.2 Submission
Separately, create a tar-ball of your submission. This can be done by going to the directory above project 1, and then typing in the Linux command: tar -zcvf project1a.tar.gz project1a.
Upload this tar-ball onto the Canvas submission site for project 1. The submission of this tar ball will trigger execution of an auto-grader. You may submit as often as you would like. We encourage you to start the project early so that you can validate your output against our auto-grader.
2.2 Part 1B: Hit the kill-switch!
The kill(2) system call delivers a signal to a process. Despite its morbid name, it will only kill (or terminate) a program if the right signal is delivered. One such signal will always do just that, SIGKILL.
The SIGKILL signal has the special property that it cannot be handled or ignored, so no matter the program your shell executed it must heed the signal.
2.2.1 Timing is Everything
To time a running program your shell will employ the alarm(2) system call. The alarm(2) system call simply tells the operating system to deliver a SIGALRM signal after a specified time. The SIGALRM signalmust be handled by your shell; otherwise, your shell will exit.Project 1
To handle a signal a signal handing function must be registered with the operating system via the signal(2) system call. When the signal is delivered, the operating system will preempt your shells current operations (e.g., waiting for the program to finish) and execute the signal handler.
To best understand signal handling, here are some questions you could try and answer:
You should also spend time carefully reading the entire man page for these systems calls and references in APUE regarding signals and signal handling.
2.3 Interrupt Signalling
2.3.1 Submission
Separately, create a tar-ball of your submission. This can be done by going to the directory above project 1, and then typing in the Linux command tar -zcvf project1b.tar.gz project1b. Upload this tar-ball onto the Canvas submission site for project 1. As before, the submission of this tar ball will trigger execution of an auto-grader.
2.4 Part 1C: Peer review
Resources Module to guide your review of your peer’s code.Project 1
Submit Your Code
You need to submit your Project 1b code in a tar.gz file to Canvas before reviewing others’ work. Op tionally, you can beautify your code before submitting for the peer review. This is a chance for you to focus on the code layout after your functionality is working. Note that this is optional – you can also submit your code as it is in Project 1b for peer review.
Some of the peer review questions appear to be asking questions about our starter-code. You may be won dering why. The reason is that, even though you did not write that code, we want to draw your attention to code you did not write, and we want you to be thinking about why we wrote that code in a certain way.
You will need to run a memory leak detection tool to look for memory errors in your peers’ code. We have a short introduction about Valgrind in the next section. Also, we prepared a demo video, called
Introducing Errors, in Week 1: Lesson 5: C-Refresher, to demonstrate how to detect memory errors with Valgrind.
1. By the due date given in the Ed Discussion announcement about 1c, submit your 1b code to the 1c assignment. Extensions are not permitted for this part of the assignment. You will need to wait to review your peers’ code until after this deadline has passed and the Course Manager has assigned your peer reviews.
4. You will be manually graded, based on the below criterion, after all peer reviews have been completed.
Grading
We will give full credit to students who submit 3 reviews, regardless of how their code has been reviewed by other students. This project is meant to have students learn and exchange ideas with each other without grading pressures.
3 Guidelines
3.1 Error Handling
3.2 Code Organization
3.3 Memory Leaks
In this class, we introduce you Valgrind, a very nice tool to help you identify leaks. However, there is no guarantee it will find all memory leaks in your code, especially those that rely on user input! Also, you still need to find and fix any bugs that these tools locate by yourself.
To clarify, having memory leaks will not cause you to lose points, as long as your shell otherwise functions correctly. Our autograder will catch many memory leaks and give you feedback (but will not take points off). In the peer review, you will check each other’s shells for memory leaks, but again you will not be penalized. Still, we strongly encourage you to fix your memory leaks and post on Ed Discussion if you need help to ensure that your shell does not have any bugs and for the best learning experience.
3.4 Memory Errors
Our autograder will be checking for the most common types of memory errors: for example, buffer overflow and the usage of uninitialised variables. These types of memory management errors can lead to difficult to trace bugs because they may only occur with certain inputs or sequences of events.
Based on our experience, most students will encounter at least one of two common memory management errors in this course:
// allocates space on the stack by moving the stack pointer
int i;
int j = 0;
// allocates space on the stack and writes the return value to memory
int k = someFunction();
C does not check if you write outside the defined limits of an array. Be careful to check the length of data structures using the sizeof operator and use safe functions that prevent writing past a buffer’s allocated space (e.g. strncpy vs strcpy).
3.4.1 Using valgrind
Note that just because you get this type of summary one time does not mean that you will get it every time. You should test your shell very thoroughly, with an extensive set of inputs to cover all possible cases that could cause memory leaks. There may only be one particular set of inputs that cause memory leaks. You should identify these inputs and resolve the memory leaks in your code.
Is it okay to have ”Still Reachable” memory? We do not want you to have ”Still Reachable” memory.
While ”Still Reachable” memory is memory to which there is still a pointer to upon termination and can be freed correctly under the hood, it still means that you are not freeing memory correctly when exiting. For example, a common mistake is not freeing the memory allocated in your getCommandFromInput() function when exiting on Ctrl + D (of course, you should also be freeing the memory correctly for all other inputs).
Using the --track-origins=yes option will show a stack trace of the error where the memory was allocated.
4 Acceptable Library Functions
5 Developing Your Code
We highly recommend you use the course-standardized virtual machine given by course staff because all grading will be done on the course virtual machine. Please do not develop on macOS as there are significant enough differences between macOS and Unix variants such as Ubuntu Linux. If you decide to develop on a different machine anyway, you must compile and test your penn-shredder on the course standardized virtual machine to ensure your penn-shredder runs as you expect.
This is a large and complex assignment, using arcane and compactly documented APIs. We do not expect you to be able to complete it without relying on some outside references. That said, we do expect you to struggle a lot, which is how you will learn about systems programming, by doing things yourself.
Having said that, the starter code is designed to aid you in aiding, and you will not need to add new .c or .h files.
Your programs will be graded on the course-standardized virtual machines, and must execute as specified there. Although you may develop and test on your local machine, you should always test that your program functions properly there.