Out: March 25, 2020 Due: April 8, 2020

CENG 251 Lab 5 Part I: Fork (14 marks)

1. In class we demonstrated 3 different styles of forking a were used. Use a different style for each experiment a-c.

a. Creating an orphan process: (2 marks)

A who’s parent has died is known as an orphan process. Write a short program that creates a single child. Have the main process die right away but leave the child still executing in an infinite loop.

When the main program has completed:

Run the shell command: ps -u $USER –O ppid What is the process id of this child’s parent? What is the State of the child? Kill the child when you are done.

The --format and -o (lower case ‘o’) flags list only the fields you specify. The -O ppid command adds fields to the default heading of PID, S (state), TTY, TIME and COMMAND

ie: ps -u $USER - -format pid,state,tty,time,command reproduces the same output as ps -u $USER

The link on the course web site contains a reasonable discussion of the command. Try out a few variations.

b. Creating a : (2 marks)

When a child process completes a record is kept in the system’s process table. A zombie process is a child process that has died without it’s code being picked up by the parent. Write a short program that creates a single child. Have the child process die right away but leave the parent running either in a loop or an extended sleep. Do not use a statement to wait for the child.

Run the command: ps -u $USER –O ppid (type in the letters ppid literally, not a parent process id) and examine the column headings:

What is the process id of the child’s parent? What is the State of the child.

c. Reaping a process: (2 marks)

Write a short program that creates a single child. i. The child should output its process id and exit with a non-zero exit code. ie: exit(17)

ii. The parent should wait for the child to complete and report the pid of the child and the reason (status code) that it exited by recovering it from the status variable passed to the wait function call. Use the macro WEXITSTATUS to obtain the status. The wait function itself returns the pid of the child.

2. Managing Multiple Child Processes

a. Write a main process that loops and creates a 10 children one after another passing each a random number between 4 million and 7 million. Your sequence of actions inside this loop should be:

i. Create a random number first ii. Create a child process iii. Call a function and pass the random number to it. The function never return to the main program. iv. Repeat – this guarantees that each child will have a unique #.

Do this carefully – make sure the children go off to a function that never returns or you’ll wind up with a situation like forkDemo5. All children will use the same function.

As a recommended precaution, when you log in set your process limit to 50:

ulimit -u 50 (2 marks)

If needed you will still have enough spare processes to log in again and kill a runaway process creator. (2 marks)

b. The function called by your child process should: (2 marks) i. Announce it’s process id, parent process id, process group and session id ii. Create and save an environment variable Process.pid and set it to the random number that was passed to the function. You’re going to have to use sprintf or asprintf to convert the numbers to strings. Retrieve and display the environment variable to verify that it was saved. iii. Go to usleep for the number of nanoseconds microseconds specified and then exit with a random return code between 1 and 127. The idea here is that the children will wake up in a different order than they were created and with different exit codes.

c. In the parent process (4 marks) i. Before creating any children, use mkstemp to create a temporary file. Write the name of the file into the file and to the screen. As each child is created write their pid and the current time in milliseconds to the file and to the screen. (The times will likely be the same.) ii. After the loop that creates the children, write another loop, completely outside the first, and wait for the children. Report the dead child’s pid, use strerror to report the meaning of the error, the current time in milliseconds and attempt to display the value of the environment variable. (The discussion of inheritDemo.c on April 1st will relate to this.)

Part II: Dealing with Different Time Representations (11 marks)

1) In a single program demonstrate the use of time functions dealing with the time of day.

a) Use the data structure struct tm (see the man pages for strftime and ctime) to create a variable and initialize the fields so that it represents the day you were born. Play close attention to the year field or you might not be born for another 1900 years!!! If you don’t know the time of day you were born, call your mom if she’s available (tell her you need to know it for an assignment) or make up your own time. (1)

b) Use mktime to convert this time to seconds since the epoch and print out the result. Use ctime, and asctime to print out the result as string. (1)

c) Use strftime to create a string and print out your birthday using at least 6 time related format codes. The output should preserve the day, month, year and hour that you were born but can be presented in any order. The format codes for this are identical to the Unix date command.

Repeat using a different format with the information in a different order. (2 marks)

d) Use gmtime to convert the time to Greenwich Mean Time and then print it out. How many hours difference is there? Record the answer. (1)

2) Both time and are wrapper functions in that the are used to change the behaviour of some other program. The code for nohup can be found in sigDemo8, which will be explained on in the 2nd week. The technique of measuring the real, user and cpu time can be found in the example doCalc2, which will also be covered in the 2nd week. Another example timeOut.c has been added to the web site.

Write a wrapper program that behaves identically to the time command. It should display the elapsed real time, user cpu time and kernel time of the wrapped command.

ie: myTimer program arg1 arg2 arg3 ......

myTimer should record the time it starts, then use execvp to launch program with each of its arguments. When program ends, myTimer reaps the process and displays the elapsed times.

Write the code and devise 3 tests, one of which uses doCalc, the other to use other programs or commands that you choose, which have non-zero execution times. In your writeup compare the result to the Unix command time. (6 marks, 1.5 for testing )