COM324 – System Programming Lab 04 – Fork() & Execve() Introduction
Total Page:16
File Type:pdf, Size:1020Kb
COM324 – System Programming Spring 201-2011 Computer Engineering Department Near East University Lab 04 – fork() & execve() Week of April 18, 2011 Introduction In this lab, we will be working on processes, and you will learn how a process is created and terminated. In addition, you will learn how a program can run other (external) programs. For example, a shell is a user-level program that runs other programs available on the system such as /bin/ls or any such command that one uses in the shell environment. How does the shell work though? The user types commands, and the shell runs each command, assuming the command has been correctly specified, for the user, except, in a few cases, the commands are built into the shell, for example, the cd command (Try man cd ). Other than this case, the programs executed by the user exist as separate executables, ready to be run (Try which ls or which chmod ). Getting Ready Before you start working, you must create a subdirectory for COM324. Do this with the following command: mkdir ~/com324 • PLEASE WORK UNDER THIS DIRECTORY!!! • PLEASE DO NOT DELETE ANYTHING ELSE ON THE HARD DISK!!! There are two major calls this lab concentrates on, namely, system calls fork() and execve(). Download the source code archive from the course website, and unarchive it using the following command: tar zxvf code.lab05.tar.gz This command will create a subdirectory called code under which you will find a subdirectory named fork for Task 1 and another subdirectory named execve for Task 2. Task 1 The first task involves a program that creates subprocesses or new processes using the fork() system call. Do man 2 fork to find more about this function. 1. After downloading and unarchiving the source code from the course website, change the working directory to code/fork and type make to build the fork example, fork-example. The fork-example program is a demonstration of how to create a child process, run some code in it (not an external program). Using the optional arguments, you can also create a normal, orphan, or zombie child process. A normal child is one for which the parent waits. That is, even if parent has finished its work, it will wait for the child to end before exiting, thereby allowing proper cleanup of the processes. An orphan process is a process that is executing but its parent has already died or finished executing. In the below program, if <child_type> is specified as 1, the child process created will be an orphan, from the time the parent process exits until it ends itself. A zombie process is different from an orphan process. A zombie process is created if a child exits while its parent does not have the chance to run a wait() or waitpid() call on it. To create a zombie, <child_type> must be 2. The program is used as follows: ./fork-example [<sleep_seconds> [<child_type>]] Both command-line arguments are optional. The first optional argument, <sleep_seconds>, is used to specify how many seconds either child or the parent will sleep (whether the parent or the child will sleep depends on the specified/default setting for <child_type>). The second optional argument, <child_type>, controls the mode of the execution, that is, what kind of a child is to be created. Note that, you must specify the first optional argument in order to be able to specify the second. By default, the value of <sleep_seconds> is 5 (seconds), and the value of <child_type> is 0 (create a normal child). 2. Before running the executable that will be created in the previous step, open a different terminal window and type watch -n 1 ps el in it to see information about the fork-example process. You will notice that, for example, in the last example, the zombie process will be indicated with a ”Z” in the ”STAT” column of the output. The above watch command runs the ps command with the el options every 1 second. 3. Now run the program as follows: ./fork-example The above command will create a normal child. The parent will wait for the child process to end before it exits, even though the child will take much longer to finish its task due to the sleep() call. 4. Next, run the program using the command below: ./fork-example 15 1 This command will create an orphan, because the parent will not wait for the child, but the child will be executing for a much longer time as an orpan (a child process without an executing parent.) 5. Finally, as an example, run the following command to create a zombie: ./fork-example 20 2 The child process will be listed with a ”Z” in the ”STAT” column in the other terminal window, since the child will exit while the parent is not running a wait() or waitpid() call. 6. Observe the output of the program and study its behavior in each of the three cases. Self-Exercise 1 Trace the execution of each of these runs. Can you explain the behavior of this program in each case? Task 2 The second task involves a program that runs external programs from within an existing or newly created child process using the execve() system call. Do man 2 execve to find more about this function. As in the previous task, the fork() call is used to create a child process that runs alongside its parent but independent of it. In addition, this program calls execve() in the child process to execute an external program. This is what the command shell in Unix|GNU/Linux systems does. 1. After downloading and unarchiving the source code from the course website, change the working directory to code/execve and type make to build the fork example, execve-example. The program takes a single command-line argument, which must be a command available as a separate executable on the system. However, the command must be speicified with its full path. To find out the path of an executable, use the which command. For example, type which ls to get the full path to the ls executable file. 2. Now, run the program: ./execve-example /bin/ls Then the run the program with an argument to the ls command: ./execve-example /bin/ls -al For example, try this: ./execve-example /bin/cat Makefile 3. Observe the outputs of the program. Exercise 1 Can you explain the behavior of this program? Exercise 2 Come up with five (5) other commands that you can run with this program. Write the programs for each. Note that you only need to modify the original program a tiny bit to get each different command to run! 4. Note that, this program has been implemented in a simplistic fashion in order to demonstrate the use of execve(). That means, commands that require more than a single argument on the command-line cannot be executed correctly. Therefore, more programming is required to be able to run any command with any number of options. Task 3 Exercise 3 Write a short C program that uses the fork() system call to print the messages Hello from child process 1 and and Hello from child process 2 . This means you will have to create two child processes and print these messages from each. Submission: EMAIL SUBMISSION REQUIRED You must attend the lab and do the required work to get credit for this lab. Your lab assistant will check that you did so. You must submit your answer to the Exercise s (not the Self-Exercise s) via email to your lab assistant by the end of the lab session. No late work will be accepted. Send an email with your source code files/answers/results for each exercise to the lab assistant at [email protected] . You must follow the format COM324: <StudentID> <FirstName> <LastName> - Lab 3 Exercises in the Subject line of your email. For example, if your name is Bob Johnson and your student ID is 20092398, then your Subject line should be: COM324: 20092398 Bob Johnson - Lab 3 Exercises Make sure you have your name and your student ID at the top of your email message in the following general format: Name: <FirstName> <LastName> Student ID: <YourStudentID> For example, Name: Bob Johnson Student ID: 20092398.