Lab 3 - The Shell, System Calls and IPC

In this lab, you will write a small program to illustrate the use of multiple processes and pipes in a shell utility. You will be required to submit the code you have written along with a short report answering a few questions.

Lab Material

  1. Slides
  2. Materials


Write a program to simulate how the shell interprets the command:

find $1 -name '*'.[ch] | xargs grep -c $2 | sort -t : +1.0 -2.0 --numeric --reverse | head --lines=$3

This command will search through the directory given by the first argument for files ending in .c or .h and return the N files (where N is the third argument) which contain the most occurrences of the string given by the second argument. You can use the lab's Makefile to run a bash script with this command:

make find

You can use the finder.c file in the lab's archive as starter code for your program. When you have finished the program, use the build target in the lab's Makefile to compile it. The output of the correct program will match with the output of the script which is also present in the lab's archive. You can use the test target in the lab's Makefile to check it against the expected output.

Please note that you must use execv system call (and not other members of the exec family e.g. execl, execve, execp etc.) to run a new program inside a child process after a fork call for the purpose of this lab.


  1. Consider the following code segment:
    	pid = fork();
    	if (pid == 0) {
    		/* Child Process */
    		char 	*cmd = (char *)malloc (128);
    		memset (cmd, 0, 128);
    		sprintf (cmd, “%s %s”, “ls”, “ll”);
    		execl (“/bin/bash”, “bash”, “-c”, cmd, (char *)NULL);
    		/* Free the memory allocated for command buffer */
    		free (cmd);
    Is there a memory leak in the above program? Why or why not? (5-Points)
    If there is a memory leak, is the leak dangerous? (10-Points)
  2. Consider the following two ways of executing an “ls” job in a process:
    	execl (“/bin/bash”, “bash”, “-c”, “ls -ll”, (char *)NULL);
    	execl (“/bin/ls”, "ls", "-ll", (char *)NULL);
    Do the above two commands produce the same output? Try running them in a sample program to verify your answer. (5-Points)
    Are the two commands above equivalent in terms of the processes which get invoked after executing each of them? (5-Points)
  3. While performing the “exec” command to run a c-program, why is the first argument always the same as the program name? (5-Points)
  4. What would happen if a program tries to read from an empty pipe? (5-Points)
  5. Consider a producer and a consumer program connected to each other through a named pipe in Linux. Assume that the producer is pushing data into the pipe at a much faster rate than the consumer’s rate of removing data from the pipe. Is there a limit to how much data can be buffered in the pipe by the producer without affecting the producer’s operation? (5-Points)


The total grade for this lab will be awarded based on your submitted code [60%] and the lab report [40%]. You should submit two files on blackboard:


Please ensure that all the changes you have implemented in this lab are limited to the finder.c file. You can use the archive target in the Lab's Makefile to create

< Back to the Lab Home Page