Lab 3 - Signals and select()

This lab is worth 10 points.
Due: Friday January 25, 2008 at 5pm

In this lab, we will explore two concepts central to many network programs: signal masks and select(). These concepts form the basis of allowing a program to use full-duplex communication.

Part 1: Signals

Signals are notifications sent by the operating system or the user to processes. The signals can affect the behavior of the program. For example, if you are running a program in the foreground of your shell and you type CTRL-C, this sends the SIGINT signal to the process. By default, the process will terminate when it receives this signal. The coder can also set up signal handlers to change the default behavior of the process when it receives certain specific signals.

To investigate how this is done, download the file process.c from http://www.cs.csub.edu/~marc/code/cs376.html or copy it from the directory /usr/users/marc/public_html/code/cs376/ while on Helios. Also download or copy all of the supporting files (makefile.unx, header.h, startup.h, startup.c, cleanup.c, diagnost.c and diagnost.h) if you do not have a copy of them in your directory. These are the same supporting files from last week. Copy makefile.unx to Makefile as done with last week's lab. Then type:

make process
to compile the code. To run the program, use the command:
process 01000
Answer the following questions as part of your write-up:
  1. What is the output of process?
  2. What is the purpose of the signals listed on the line "Current Signal Mask" in the output? (look up the listed signals in the man pages or online)
  3. Look at the source of process.c and answer the following questions.
    1. What is the full list of signals marked in the source code as important signals?
    2. Pick three important signals that you did not describe in Question 2 and describe their purpose.
    3. Look at the man page for sigemptyset and describe its purpose in process.c
    4. Look at the man page for sigprocmask and describe how it is used in process.c

Part 2: select()

The purpose of select() is to give the program a way of waiting for I/O events or errors from specified file descriptors or sockets. For example, if the user types something on the keyboard, this will be an event for the stdin file descriptor. If data is waiting on the network socket, i.e. something can be read with recv(), then this would also be an I/O event.

To see how select() can be used in a network program, download or copy the files terminal.c and specio.h from Dr. Marc Thomas' website/directory to your lab directory. If you have made a new directory for part 2 of the lab, you will also need all of the supporting files. Compile the code with:

make terminal
This program steps through three basic terminal modes: raw, cbreak and cooked. Raw mode inputs data character by character with no interpretation (e.g. no signal handling). Cbreak mode responds to SIGINT (CTRL-C) and also uses character by character mode. Cooked mode, also called line mode, gets a full line of input from the user and does interpretation. Run terminal giving it a variety of input such as printable characters, tabs, control sequences (CTRL-G for bell, CTRL-C for SIGINT, CTRL-Z for SIGSTOP, etc) and escape.

Answer the following questions for your write-up:

  1. Describe what happened when you ran terminal with a variety of input.
  2. Look at the source code for terminal.c
    1. How is the SIGINT (CTRL-C) signal handler set up? (hint: man signal)
    2. Look at the section labeled "selectloop". How is select() being used in this loop?
  3. Return to the question from the previous lab about modifying vcrec.c and vcsend.c to support full duplex communication. How would you use concepts explored in this lab to allow full duplex communication between the two processes?