HPlogo Berkeley Sockets/iX Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 2 Socket System Calls

Signals and Sockets

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

What is a Signal?

A signal is the notification to a process of an event. This event can be either external or internal. A signal can be generated by either the operating system or a process (even the same process that is receiving it). Other than which signal is delivered, no information is delivered with the signal. A process cannot determine what process generated the signal, how it was generated or which file descriptor, if any, for the process the signal is related to. When a signal is sent to a process and the process is made aware of that signal, it is said that that signal has been raised.

There are several methods for generating a signal. However, for the purposes of this discussion, how signals are generated is largely immaterial. Suffice it to say that most signals related to sockets are generated by software conditions.

There are many system calls relating to the handling of signals. Please refer to the POSIX manuals for a more complete description. For the purposes of illustration, we will use the signal() system call, which is the simplest of the system calls dealing with sockets, to describe signal handling.

There are several default actions possible that may be performed upon receipt of a signal. Some of them are: ignore the signal, terminate the process, suspend (stop) the process, and resume (continue) the process. Of the signals generated by sockets, only the ignore and terminate defaults are available. Which of these actions is the default for signal reception depends on the signal.

When signal() is called, there are three methods for handling the signal. They are SIG_DFL, SIG_IGN or a user specified signal handler. SIG_DFL sets the signal handler to the default signal handler. This is useful if the signal handler was changed and the process should be returned to an initial state. SIG_IGN sets the signal handler to ignore this signal.

The third choice can be the most useful. It is used to set up a user specifiable function to be the signal handler. Whenever that signal is raised, the user specified function is invoked. This is generally referred to as catching a signal. A typical example of this type of handler (for a signal that is not indicative of an error state) is to either set or increment a flag indicating that a signal was received.

Sockets and Incoming Signals

When a signal is sent to a process while performing a sockets function, several things may occur. This depends on whether the socket function is defined as a slow function. A slow function is a function that can block indefinitely. For sockets, these functions are read, write, recv, send, recvfrom, recvmsg, sendmsg, and accept. All other sockets functions are fast.

Fast functions are not interrupted by a signal. Instead, the signal is raised when these socket functions exit.

Slow functions are interrupted by a signal if they are blocked waiting for IO (if they are processing IO, they are not interrupted). They are interrupted in the middle of processing by the raising of a signal. They stop what processing they are doing and return the error EINTR. They do not complete the IO that was initiated. The user program must re-initiate any desired IO explicitly.

Signals Generated By Sockets

There are two signals that can be generated by actions on a socket. They are SIGPIPE and SIGIO. A SIGPIPE is generated when a send operation is attempted on a broken socket. One way of breaking a socket is to do a shutdown(,2) on a socket. The default action is to terminate the process. The target of the signal is the process attempting the send.

The other signal is SIGIO. SIGIO is somewhat more complex than SIGPIPE. First, a call to ioctl() to request the enabling FIOASYNC is required to enable generation of this signal. Second, another call to ioctl() is required to request SIOCSPGRP, which sets the target process group. A target process group is either a process (specified by a positive process id) or a process group (specified by a negative process id). A SIGIO signal is generated whenever new IO can complete on a socket. Examples of when a SIGIO signal is generated are when new data arrives at the socket, when data can again be sent on the socket, when the socket is either partially or completely shutdown or when a listen socket has a connection request posted on it.

Using Signals With Sockets

There are several issues to using sockets that can be resolved through the use of signals. One is the fact that there are no timeouts on sockets. A similar functionality can be accomplished with the use of the SIGALRM signal and the alarm() system call. Alarm() sets up a SIGALRM signal to be received a certain specified number of seconds in the future. If the socket call is not completed by the time the alarm goes off, it is interrupted. The alarm is reset by another call to alarm() with a time of 0 seconds.

Another issue that may arise if the use of signals to indicate when IO can complete. Use of the SIGIO signal can be used to indicate when IO can complete. After enabling the SIGIO signal on all of the desired descriptors, pause() is called to wait for a signal to arrive. Then, either using a polling method or select(), it can be determined which socket has IO ready to complete. This avoids repeated calls to no-blocking IO when there is no IO present.

MPE/iX Specific

Due to POSIX/iX design considerations, the read() and write() system calls may not be interrupted by a signal while they are running system code (see the POSIX.1/iX Reference Manual).

Select() does not support signals in this release. Its non-support takes the following form: when blocked in select(), any signal that arrives, even those we are set to ignore, interrupts select() and causes it to return EINTR. Even ordinary signals that default to ignore, such as SIGCHLD (the signal generated when a child process terminates), cause select() to be interrupted. Care must be taken to account for this non-support.

The SIGURG signal is not supported in this release. This is the signal that is sent when urgent data is received on a socket.

None of the socket functions should be called from within a signal handler.

Feedback to webmaster