CSC 2405 -- Creating and Running Processes in Unix

 

The goal of this assignment is to get more practice with creating and executing processes in Unix using the following system calls:

 
       fork, wait and exit
       execv and execl   

 

In your csc2405/forkexec Unix directory, write code solutions for the five exercises below.

 


Exercise 1.

Write a program pfork.c that does the following:

 

Have your program print a message in case the command line is invalid:

 
        if(argc < 3)
        {
               printf("Invalid command line: please supply two integer values\n");
               exit(1);
        }

 

Here is all you need to know about printf. Use the atoi function to covert strings to their integer value.

(a) Sample output (assumming command line pfork 12 16):

        [Child  1235]: Difference of 12 and 16 is -4.
        [Parent 1234]: Sum of 12 and 16 is 28.
 
or 
        [Parent 1234]: Sum of 12 and 16 is 28.
        [Child  1235]: Difference of 12 and 16 is -4.    
 

Exercise 2.

Step 1. At the shell prompt, try the command

 

        ps -f

 

A list of your own processes currently running will be displayed:

Very likely, your only process currently running is the bash shell. For a list all processes in the system, execute

 
       ps -e -f

 

Optionally, for more information on ps, use the Unix manual pages (type in man ps at the shell prompt).

Step 2. Copy the program from Exercise 1 into a new file pexec.c. Extend the code for the child to do the following:

    
    char * cmd[] = {"/bin/ps", "-e", "-f", 0};    // in the variable declaration section
    ...
    execv(cmd[0], cmd);                           // in the code section of the program

Sample output (assumming command line pexec 12 16):

        [Parent 1234]: Sum of 12 and 16 is 28.
        [Child  1235]: Difference of 12 and 16 is -4.
 
        UID     PID   PPID   C    STIME TTY      TIME CMD
        mdamian 22686 22684  0 14:12:26 pts/5    0:01 -bin/bash
        mdamian 22826 22686  0 15:11:49 pts/5    0:00 pexec
        mdamian 22827 22826  0 15:11:49 pts/5    0:00 ps

Note: Make sure the parent waits for the child to finish.

Step 3. Answer the following question: Is it possible to have the child execute ps –e -f first, and then print out the difference value? Why or why not?


Exercise 3.

This exercise asks you to experiment with various versions of execv.

     
     execl("/bin/ps", "/bin/ps", "-f", 0); 
 

Note that the argument "/bin/ps" appears twice: the first occurence accounts for cmd[0], while the rest of arguments account for all values in the array cmd, as used in execv. Try it out.

       
       char * cmd[] = {"ps", "-f", 0};  // in the variable declaration section
       ...
       execvp(cmd[0], cmd);             // in the code section of the program

 

Modify the code from Exercise 2 to include the lines of code above. Does it produce the same output?


Exercise 4.

The word count program  wc  can take its input from a file whose name is specified in the command line. For instance, the Unix command

 

wc filename

 

will print out the number of lines in the file with name filename.  Write a small program linecount.c that takes any number of file names as command line parameters.  For each filename in the command line, the program should create a child process that does the following:

 

a)     prints out the name of the file

b)    uses execlp to execute the program wc on that file

 

The parent process should not exit until all processes have exited. 

 

Sample output (user input is in italics, aa and bb are two files in the same directory as linecount):

 

bash$ ./linecount aa bb

aa

       3       2       9   aa

bb

       5       6      41   bb

 

For each file, the first column lists the total number of lines, the second column list the total number of words and the third column lists the total number of characters.

 


Exercise 5.

Write your own system function with the following prototype:

 

void mysystem(char * cmd);

 

Your function should behave exactly like the system function, but should not call the system function. You’ll need to implement the following steps:

 

a)     tokenize the command argument and save each string in an array of strings

b)    the main process invokes  fork to create a child process, then waits for the child to finish

c)     the child process invokes execv with arguments taken from the array of strings

 

Write a test program for your mysystem function.

 


What to turn in:

Hand in a printout of the source code for exercises 1, 2, 4 and 5, along with a sample output for each of these exercises. Leave the source code for all exercises in your directory csc2405/forkexec, and do not make any changes to this code past the due date for this assignment.