Programming with sockets

Signals and process groups

Because of the existence of the SIGURG and SIGIO signals, each socket has an associated process number, just as is done for terminals. This value is initialized to zero, but may be redefined at a later time with the F_SETOWN fcntl such as was done in the code above for SIGIO.

To set the socket's process id for signals, positive arguments should be given to the fcntl call. To set the socket's process group for signals, negative arguments should be passed to fcntl.

The only acceptable arguments to these system calls are the caller's process id or a negative process group having the same absolute value as the caller's process id (the process must be the process group leader of its own process group). Therefore, the only allowed recipient of SIGURG and SIGIO signals is the calling process.

Note that the process number shows either the associated process id or the associated process group; it is impossible to specify both at the same time. A similar fcntl command, F_GETOWN, is available for determining the current process number of a socket.

Note that the receipt of SIGURG and SIGIO can also be enabled by using the ioctl(S) call to assign the socket to the user's process group:

   /* oobdata is the out-of-band data handling routine */
   signal(SIGURG, oobdata);
   . . .
   int pid = -getpid();

if (ioctl(client, SIOCSPGRP, (char *)&pid) < 0) { perror("ioctl: SIOCSPGRP"); } ...

Another signal that is useful when building server processes is SIGCHLD. This signal is delivered to a process when any child processes have changed state. Normally servers use the signal to ``reap'' child processes that have exited without explicitly awaiting their termination or periodically polling for exit status. For example, the remote login server loop shown in ``Servers'' may be augmented as follows:

   int reaper();
   signal(SIGCHLD, reaper);
   listen(f, 5);
   for (;;) {
   	int g, len = sizeof(from);

g = accept(f, (struct sockaddr *)&from, &len,); if (g < 0) { if (errno != EINTR) syslog(LOG_ERR, "rlogind: accept: %m"); continue; } ... } ... #include <wait.h> reaper() { int status;

while (wait(&status) > 0) continue; }

If the parent server process fails to reap its children, several zombie processes may be created.
© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005