---
name: "signal"
section: "3bobcat"
platform: "linux"
package: "libbobcat-dev"
version: "6.07.01-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/signal/3bobcat"
---

# signal(3bobcat)

Signal Handler

## NAME

FBB::Signal - Signal Handler

## SYNOPSIS

**#include \<bobcat/signal\>**\
 Linking option: *-lbobcat*

## DESCRIPTION

Signals have the well known drawback that signals arrive free of context. E.g., assume a program runs a flow control loop like this:

```
void Class::run()
{
    while (d_continue)
        handleTasks();
    cleanup();
}
```

then if the program needs to recognize  a termination signal then the typical signal handler looks like this:

```
void signalHandler(int signal)
{
    // perform required actions
}
```

Since the *signalHandler* is called asynchronically, there is no context available, and the usual way of communicating between objects and signal handlers is via static variables, like this:

```
// declared as static bool s_continue;
bool Class::s_continue = true;
void Class::run()
{
    while (s_continue)
        handleTasks();
    cleanup();
}
// declared as static void signalHander(int signal);
void Class::signalHandler(int signal)
{
    s_continue = false;
}
```

The class *Signal* allows the signal handler to operate in the context of a class. The advantage of this is that static data members are no longer required and that the signal may be used to control data members of individual objects.

The signal is now handled by an object, whose class must define a member

```
    void signalHandler(size_t signum) override;
```

and this function is responsible for handling the received signal. Since it is a member function it may affect its object’s local variables and it may call its object’s member functions. Static data members are not required anymore (see below for an example).

Note that, as the signal may arrive at unpredicable times data members that can be modified by *signalHandler* should be declared using the *volatile* modifier. Moreover, data that can be modified by the *signalHandler* member and by other class members should be protected by *mutexes* (cf. the **C++-11** class *std::mutex* or **pthread\_mutex\_lock**(3posix)).

## NAMESPACE

**FBB**\
 All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace **FBB**.

## INHERITS FROM

*Signal* is not derived from other classes, but the classes for which signals must be handled by *Signal* must themselves publicly be derived from the class *FBB::SignalHandler* and must implement a member

```
    void signalHandler(size_t signum) override;
```

handling the received signal.

## CONSTRUCTORS AND OVERLOADED OPERATORS

*Signal* is defined as a *singleton*, and does not offer public or protected constructors, nor does it offer overloaded operators.

## STATIC MEMBER FUNCTION

- o

  **static Signal &instance()**:\
  \
   This static member can be used to access a reference to the program’s single *Signal* object.

## MEMBER FUNCTIONS

All of *Signal*’s member functions can only be called through a reference to the program’s *Signal* object, returning a reference to the program’s single *Signal* object:

- o

  **void add(size\_t signum, SignalHandler &object)**:\
  \
   *SignalHandler object* is activated on arrival of signal *signum*. If multiple *SignalHandler* objects must be called then multiple *Signal::add* calls can be provided, and the various *SignalHandler::signalHandler* members are called in the same sequence as their respective *Signal::add* calls. If one of the earlier *signalHandler* members terminates the program then later *signalHandler* members are not activated anymore. If *Signal::add* is called by, e.g., an object’s constructor, then its destructor should call *Signal::remove* to prevent the object’s signal handler from being called after its destruction.

- o

  **void remove(size\_t signum, SignalHandler &object)**:\
  \
   *SignalHandler object* for signal *signum* is removed from the *Signal* object. It is the responsibility of *object* to deregister itself from *Signal* just before *object* goes out of scope. Objects can only deregister themselves if they’ve previously registered themselves using *add*.

- o

  **void ignore(size\_t signum)**:\
  \
   Any previously installed *SignalHandler* object is no longer activated on arrival of signal *signum*. In addition, if possible, signal *signum* is completely ignored (some signals cannot be caught, blocked, of ignored, like *SIGKILL* and *SIGSTOP* (cf. [**signal**(7)](/signal/7.md))).

- o

  **void reset(size\_t signum)**:\
  \
   Any previously installed *SignalHandler* object is no longer activated on arrival of signal *signum*. In addition, the default action the program takes on arrival of signal *signum* is reinstalled (cf. [**signal**(7)](/signal/7.md)).

If the *signum* value that is passed to *Signal*’s members is not a defined signal value, then an **FBB::Exception** exception is thrown.

## EXAMPLE

```
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <bobcat/signal>
class SignalDemo: public FBB::SignalHandler
{
    volatile size_t d_signal;
    volatile bool d_continue;
    pid_t d_pid;
    public:
        SignalDemo();
        void run();
    private:
        void signalHandler(size_t signum) override;
};
using namespace std;
using namespace FBB;
SignalDemo::SignalDemo()
:
    d_signal(0),
    d_continue(true),
    d_pid(getpid())
{}
void SignalDemo::run()
{
    while (d_continue)
    {
        cout << "Send a SIGINT (2) or SIGTERM (15) ... to process " <<
                    d_pid << endl;
        sleep(1);
    }
    cout << "Ending `run’ after receiving signal " << d_signal << endl;
}
void SignalDemo::signalHandler(size_t signal)
{
    if (signal == SIGINT)
        cout << "Process " << d_pid << " received SIGINT" << endl;
    else if (signal == SIGTERM)
    {
        cout << "Process " << d_pid << " received SIGTERM" << endl;
        d_signal = SIGTERM;
        d_continue = false;
    }
}
int main()
{
    SignalDemo signalDemo;
    Signal::instance().add(SIGINT, signalDemo);
    Signal::instance().add(SIGTERM, signalDemo);
    signalDemo.run();
}
```

## FILES

*bobcat/signal* - defines the class interface

## SEE ALSO

[**bobcat**(7)](/bobcat/7.md), **pthread\_mutex\_lock**(3posix), [**signal**(7)](/signal/7.md),\
 and the **C++-11** class *std::mutex*.

## BUGS

None Reported.

## BOBCAT PROJECT FILES

- o

  *https://fbb-git.gitlab.io/bobcat/*: gitlab project page;

Debian Bobcat project files:

- o

  *libbobcat6*: debian package containing the shared library, changelog and copyright note;

- o

  *libbobcat-dev*: debian package containing the static library, headers, manual pages, and developer info;

## BOBCAT

Bobcat is an acronym of \`Brokken’s Own Base Classes And Templates’.

## COPYRIGHT

This is free software, distributed under the terms of the GNU General Public License (GPL).

## AUTHOR

Frank B. Brokken (**f.b.brokken@rug.nl**).
