signal


A s ignal is a software interrupt. UNIX supports about 30 signals, each with a unique integer code. The signals are numbered sequentially, starting with the number one. You can program the current process to react to a particular signal in one of these ways.

In addition, you can program the current process to block certain signals. Blocked signals are queued and only delivered if they are unblocked. Some signals are so common they have a function named after them. These function names are listed in the following table.
 
Signal Function

SIGINT

interrupt()

SIGKILL

kill()

SIGHUP

hangup()

SIGQUIT

quit()

SIGSTOP

suspend()

SIGTSTP

keyboard_suspend()

SIGTERM

terminate()

SIGCONT

resume()

The examples in this section illustrate the various uses of signals.

Terminating a Process

The following example shows the result of a current process receiving a SIGTERM signal. The current process reacts in the default manner by displaying the message "Terminated" and terminating without dumping core.

Example <ospace/unix/examples/signal1.cpp>
#include <iostream>
#include <ospace/unix.h>

int
main()
  {
  os_unix_toolkit initialize;

  os_this_process::terminate(); // Commit suicide.
  return 0;
  }

Terminated

Suspending, Resuming, and Terminating a Process

Once a process object is associated with a running process, you can suspend, resume, or terminate it using suspend() , resume() , or terminate() . These functions operate by sending the process a signal. The following example demonstrates all of these functions.

Example <ospace/unix/examples/signal2.cpp>
#include <iostream>
#include <ospace/unix.h>

int
child_function()
  {
  while ( true ) // Loop forever.
    {
    cout << "Child loop" << endl;
    os_this_process::sleep( 1 );
    }
  return 0; // Will never execute.
  }

int
main()
  {
  os_unix_toolkit initialize;

  os_process child( child_function ); // Spawn child.
  os_this_process::sleep( 4 );
  cout << "child.suspend()" << endl;
  child.suspend();
  cout << "Parent sleeps for 4 seconds" << endl;
  os_this_process::sleep (4);
  cout << "child.resume()" << endl;
  child.resume ();
  os_this_process::sleep (4);
  cout << "child.terminate()" << endl;
  child.terminate ();
  cout << "Parent finished" << endl;
  return 0;
  }

Child loop
Child loop
Child loop
Child loop
Child loop
child.suspend()
Parent sleeps for 4 seconds
child.resume()
Child loop
Child loop
Child loop
Child loop
child.terminate()
Child loop
Parent finished

Setting an Alarm Signal

The following example uses set_alarm() to send a SIGALRM signal to the current process after four seconds. The process reacts in the default manner by displaying the message " Alarm Clock" and terminating.

Example <ospace/unix/examples/signal3.cpp>
#include <iostream>
#include <ospace/unix.h>

int
main()
  {
  os_unix_toolkit initialize;

  cout << "Set the alarm for 4 seconds." << endl;
  os_this_process::set_alarm( 4 );
  cout << "Pause for a signal..." << endl;
  os_this_process::pause(); // Wait for a signal.
  cout << "Program terminated OK" << endl; // Never executed.
  return 0;
  }

Set the alarm for 4 seconds.
Pause for a signal...
Alarm Clock

Blocking Signals

In the next example, the current process is set to block SIGUSR1 signals and send a SIGUSR1 to itself. The pending_signals() function shows that SIGUSR1 is queued. When SIGUSR1 is unblocked, it is delivered to the current process, which terminates and displays "User Signal 1."

Example <ospace/unix/examples/signal4.cpp>
#include <iostream>
#include <ospace/unix.h>

int
main()
  {
  os_unix_toolkit initialize;

  os_this_process::block( SIGUSR1 );
  vector< ossig_t > blocked = os_this_process::blocked_signals();

  cout << "Blocked signals = ";
  for ( int i = 0; i < blocked.size(); i++ )
    cout << os_signal( blocked[ i ] ) << " ";
  cout << endl;
  os_this_process::signal( SIGUSR1 );
  vector< ossig_t > pending = os_this_process::pending_signals();

  cout << "Pending signals = ";
  for ( i = 0; i < pending.size(); i++ )
    cout << os_signal( pending[ i ] ) << " ";
  cout << endl;
  os_this_process::unblock( SIGUSR1 );

  cout << "Terminating OK" << endl; // Never executed.
  return 0;
  }

Blocked signals = os_signal( 16, User Signal 1 )
Pending signals = os_signal( 16, User Signal 1 )
User Signal 1

Ignoring Signals and Restoring Defaults

To ignore and discard a signal, use ignore() . To restore the default action, use restore_default() . The following example shows how programs can use these functions to protect their critical regions from the interrupt signal, SIGINT (Control-C).

T he SIGKILL and SIGSTOP signals can never be ignored or discarded.

Example <ospace/unix/examples/signal5.cpp>
#include <iostream>
#include <ospace/unix.h>

int
main()
  {
  os_unix_toolkit initialize;

  os_this_process::ignore( SIGINT );

  cout << "Try and kill me with a Control-C (SIGINT)" << endl;
  os_this_process::sleep( 5 );
  os_this_process::restore_default( SIGINT );

  cout << "Try again" << endl;
  os_this_process::sleep( 5 );

  cout << "Terminating OK" << endl; // Never executed.
  return 0;
  }

Try and kill me with a Control-C (SIGINT)
^C^C^C (Doesn't work)
Try again
^C (Terminates the program)

Using Signal Sets

Many of the signal-related functions can take either a single signal or a vector of signal codes as a parameter. In the following example, a set of signals is blocked, sent, and unblocked. When the first blocked signal, SIGALRM , is delivered, the current process terminates with the message "Alarm Clock."

To denote an empty set of signals, use the predefined object os_signal::empty_set .

Example <ospace/unix/examples/signal6.cpp>
#include <iostream>
#include <ospace/unix.h>

int
main()
  {
  os_unix_toolkit initialize;

  vector< os_sig_t > signals;
  signals.push_back( SIGALRM );
  signals.push_back( SIGTERM );

  cout << "Blocking ";
  os_this_process::block( signals );
  os_this_process::signal( SIGALRM );
  os_this_process::signal( SIGTERM );

  cout << "OK so far" << endl;
  os_this_process::unblock( signals );
  cout << "Terminating OK" << endl; // Never executed.
  return 0;
  }

Blocking OK so far
Alarm Clock

Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.