CS 232 Project 1: System Calls

Part Uno


Unix uses the term signals for software-generated interrupts. In this project, we will learn about Unix signals, and some of the system calls Unix provides for manipulating them.


This project is to write a C program named prank that displays an annoying message every few seconds and that cannot be interrupted using Cntl-C. If one of your friends were to leave themselves logged in, you could play a prank on them by editing their .bashrc file and running this program in the background there, so that it would launch anytime they opened a new xterm/shell.

To complete this assignment, your program must use these system calls:

You should read the UNIX manual pages (section 2) for the details of these calls, especially what files must be #include-d to use them. There are also many WWW tutorials/examples available for each, that you may find useful.)

Command-line Switches.

For flexibility, your program should allow its invoker to control its execution using the following command-line switches:

To illustrate:
   prank -i
   prank -i +t 5
   prank +t 5 -i
should each display the annoying message every 5 seconds and disable interrupts; and
  prank +i +t 10
  prank +t 10 +i
should display the annoying message every 10 seconds without disabling interrupts. You will need to use the main function parameters argc and argv to process these command-line switches. The user should be able to specify the switches in any order.


Unix defines a number of standard software signals in the header file <signal.h>, including SIGALRM and SIGINT, the two signals we will use in this project.

Most of the signals have a default signal-handler associated with them. However Unix allows you to supply your own handler for most of the signals.

To bind a handler to a signal, the signal() system call can be used.

Unix also provides the alarm() system call. A process can use this call to tell the OS to send it SIGALRM signal after a given time interval has elapsed.

Another useful system call is the pause() call. A process executing this call will be suspended until it receives a signal.

Plan of Action.

1. Begin by reading up on argc and argv (these are covered inmost C books, and a number of on-line sites), and get a skeleton program working that correctly processes command-line switches. (Hint: Process the entire command-line before doing anything else, using the switches specified to set bool variables. Then use those bool variables to control your program.)

2. Next, read up on the signal-manipulating system calls, and modify your program so that it uses the SIGALRM signal and the system calls listed above to display the default annoying message every few seconds. (Do this before disabling Cntl-C so that you can still kill the program using Cntl-C.)

3. Modify your program again so that it correctly handles the -m switch, allowing the user to replace the default annoying message with a custom one.

4. Finally, modify your program again so that it uses SIGINT and the system calls mentioned above to ignore Cntl-C. Once you have figured out how to handle SIGALRM, this part should be relatively easy. (You should use the SIG_IGN argument to signal().) To kill the program at this point, you'll have to do something like this:

  1. use Cntl-Z to suspend the program;
  2. use ps to find its process id number; and
  3. use the kill command to terminate the program (Check the manual page for kill and you'll see that it sends a given process the SIGTERM signal.)
Feel free to discuss the project, the Unix manual pages, and the system calls with myself or your classmates. You are not to look at anyone else's source program.

Your program should be reasonably efficient in terms of its use of both time and space, should be well-structured (i.e., all functions should be short enough to be read without scrolling), and should be fully documented.

Your program must conform to the CS-232 Coding Standards to receive full credit.

Part Deux

The strace command on Linux can be very useful for watching what a process is doing when it is running. It displays the system calls being made, the arguments being passed in to them, and the return values from those calls.

In this part of the assignment, run your completed program "under" strace. I.e., if your program is called a.out, you would run it this way:

strace ./a.out

Output might look something like this:

execve("./a.out", ["./a.out", "--help"], [/* 35 vars */]) = 0
brk(0) = 0xa37000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f37351d5000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/tls/x86_64/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/tls/x86_64", 0x7fffb8b7f840) = -1 ENOENT (No such file or directory)


Create a file called analysis.txt in which you place *some* of the strace output -- don't put it all. Pick 5 different system calls you see and write a few sentences (in the file) that describe what each call does. To figure out what the system calls are doing, use man, or search online.

Turn in:

Copy your files to /home/cs/232/current/<yourid>/proj1/. Also submit a script file, in which you demonstrate:

  1. gcc or g++ successfully compiling your program ; and
  2. Execution of your program as necessary to show that the various combinations of command-line switches all work.

Then, submit your analysis.txt file.

Finally submit the grading.txt file found here, filled out with your name. You can look at that file also to see how you will be graded.

Due date: Friday, Feb. 17, 11:59 p.m.

Calvin > CS > 232 > Projects > 1

This page maintained by Victor Norman.