Lab Exercise 8: Signals

Create two C programs such that you can send signals from the keyboard using kill(1) to one program, which will repeat the signal via kill(2) to the other program.

For example, if the programs are named near and far, use kill(1) to send the SIGUSR1 (signal 10) or SIGUSR2 (signal 12) signal to a copy of near running in the background or in another window. Once near receives the signal, have it issue a kill(2) to pass on the signal to the program far, also in the background or in another window. Have each program issue progress messages (clearly labelled with its name) so you can see what each one is doing at each step.

Both programs must handle SIGUSR1 and SIGUSR2 appropriately, and both must terminate gracefully when SIGTERM (at least; you may also wish to support SIGINT or even more) is sent to near.

Here's an example of what you might see on the screen:

System Prompt$ far &
[1] 18986
System Prompt$ near 18986 &
[2] 18987
System Prompt$ kill -sigusr1 18987
System Prompt$
near: caught signal 10, sent to pid 18986
far: signal caught for 10
kill -sigusr2 18987
System Prompt$
near: caught signal 12, sent to pid 18986
far: signal caught for 12
kill 18987
System Prompt$
near: caught signal 15, sent to pid 18986
far: signal caught for 15
[Enter issued by user]
[1]-  Terminated    far
[2]+  Exit 1        near 18986

System Prompt$

The far program is started in the background with the ending &. The second program, near, is also started in the background and is given the pid (process id) for far as a command-line argument (use strtol() or strtoul() to convert it to an integer) to be used when it issues the kill(2). Both programs terminate when they receive SIGTERM (signal 15).

Signals from the keyboard are sent only to near (pid 18987 in the sample above). far only receives its signals from near (pid 18986).

In a never-ending (infinite!) loop, you can use pause(2) to wake a program only when a signal has been received, or you can use a brief sleep(3). Your infinite loop can be created using either for or while; they are the same.

Note that you will have to use global variables in order to share data between a main program and a signal-catcher function. You are to put each function in its own .c file, and use extern to tell the linker when not to instantiate a variable but to find it elsewhere (see Section 4.4 in K&R, page 80), and create a makefile using a default target line as the first line in the file to cause each of the two executables to be made at the same time, such as:

both:          near      far

See the lecture notes for examples of signal programs, the use of extern, and this style of makefile. The lecture programs are in ~allisor/Student/signals.

Keyboard


"near" process


"far" process

kill command is sent to near

=>

Process main() loop waits for signal from the keyboard and sends kill() to far

=>

Process main() loop waits for signal from near

 


Signal handler catches signal from keyboard and notifies the process.


Signal handler catches signal from near and notifies the process.

Demonstrate your two programs working together before the end of the lab period.