CS 3733 Operating Systems Assignment 1


You are required to submit your work through UTSA Learn (f. Blackboard or BB)  !!! No e-mail submissions !!!

!!!! Please carefully check the DUE DATE on BB Learn !!!!

!!!! NO LATE SUBMISSION WILL BE ACCEPTED !!!



Overview
This assignment is about process Process Creation and File Operations.
You will write two programs (say, wordcount.c and multiple_wordcount.c).

The first program wordcount.c will take the name of an input file as a command line argument and open file argv[1] to read. If the file does not exist or cannot be opened, print an error message and return/exit with an exit code of 1, indicating there was one error. If the file is opened successfully, count/print the number of words in file argv[1] and return/exit with an exit code of 0, indicating there was no error. The typical format to run the first program with input parameter is as follows:

./wordcount An_Input_File

wordcount with process id of ..... counted words in An_Input_File: number of words is ...

The second program multiple_wordcount.c will take the names of multiple input files as command line arguments. For each file, it creates a child that can execute the above program wordcount to count/print the number of words in that file. Specifically, the program multiple_wordcount.c will first determine the number of files to be processed. Then, the program will create multiple child processes with each process being responsible for one file to count its words. The typical format to run the program with input parameters is as follows:

./multiple_wordcount File_1 File_2 ... File_n

Here is a sample output (note one child may finish before the other child so your output lines may be in different order). Also each child should print actual pid and filename instead of pid_x File_x below:

wordcount with process id of ..... counted words in File_1: number of words is ...
wordcount with process id of ..... counted words in File_2: number of words is ...
wordcount with process id of ..... cannot open File_3
...
wordcount with process id of ..... counted words in File_n: number of words is ...

Note that, no inter-process communication is required for child processes to send their count to the parent! Individually, they print their results on the screen, as shown above. However, by exiting with exit code 0 or 1 (as described above), they respectively inform the parent if they were sucessful or not successful when opening files. The parent will know about these exit codes when it waits for the child processes. After wating for all child processes and inspecting their exit codes, the parent prints how many files are counted successfully and how many files did not exist. So here is a sample output:

Parent process pid created ..n.. child processes to count words in ..n.. files
  ..x.. files have been counted sucessfully!
  ..y.. files did not exist


Click here for a zip file containing templates for wordcount.c, multiple-wordcount.c, makefile, and sample input files.

Details
In your wordcount.c program, you can read the file line-by-line by using a modified version of your ReadLine() function from previous assignment so that it can read a line from the given file without worrying about the length of the line. Then you can count the words in each line and sum them up. For word counting, simply use the following white-space characters: ' ', '\t', '\n', '\r' as the delimiter or you can use int isspace(char c) to check for white-space char. Anything that are not separated by the white-space characters (' ', '\t', '\n', '\r') will be counted as a single word. Make sure the spaces at the beginning or end of lines don't cause a problem. For instance, the example “ The first program is a Hello-world. ” will be reported as 6 words (where Hello-world is counted as a single word). You could compare your results using the wc utility that is available on Linux machines.

The multiple-wordcount program gets the file names as command line arguments. It then creates n = argc - 1 child processes using fork() in a loop and expects each child process to execute wordcount program to count/print the number of words in each file on the screen. Basically, here is the general structure of multiple-wordcount.c.  

for(i=1; i < argc; i++) {
   cpid = fork();
   if (cpid == -1) { ... }
   if (cpid == 0) {
     // this part is for child process
     // exec(...) the wordcount program with argv[i] as a paramenter
     // if exec() is sucessfull, the child process will be replaced by wordcount
     // BUT, if exec() fails, the child will continue executing statments here!
     // So, print an error message here and
     // return/exit with an exit code of 2, indicating that exec failed.
     // Otherwise (if you don't exit), what will hapen?
   }
   // this part is for parent process ! But, DO NOT WAIT FOR A CHILD HERE !
}

// after the parent creates all children, it comes to this part
for( ; ; ) {
   // ! WAIT HERE FOR ALL CHILD PROCESSES and CHECK THEIR EXIT CODES !
}

With the first for-loop, the parent continue to create child processes while each child process simply executes the wordcount program to count/print the number of words in the given file argv[i].
As described above: If the given file exists, the child process counts the words, prints out the count, and returns 0; or exit(0); indicating sucess.
If the file does not exist, it prints an error message and returns 1; or exit(1); indicating an error happened. 

With the second for-loop, the parent process WAITs for all child processes and GET EXIT code for each child using wait() system call. By INSPECTING the exit code for each child, parent can count how many child processes were succesful or failed. It then generates the above sample output.

Deliverables