FBB::Signal(3bobcat)
π FBB::Signal π β the signal handler page from bobcat(3bobcat), bestie edition
okay so. you're reading a manual page. yes a manual page, we're doing this. this one's FBB::Signal(3bobcat) and it lives in the signal handler corner of the bobcat docs. grab a snack. π
πΈ NAME πΈ
FBB::Signal β Signal Handler. that's it. that's the whole name section. short and iconic. π
β¨ SYNOPSIS β¨
#include <bobcat/signal>
Linking option: -lbobcat
yes the -lbobcat is required, do not fight it, just link the library. π«Ά
π¦ DESCRIPTION π¦
okay so here's the tea. signals have a very well known drawback: they arrive free of context. like a text from a number you don't have saved. π
say your program runs a flow control loop like this:
void Class::run()
{
while (d_continue)
handleTasks();
cleanup();
}
and now the program needs to recognize a termination signal. the typical signal handler looks like this:
void signalHandler(int signal)
{
// perform required actions
}
the problem? since the signalHandler is called asynchronically, there is no context available. so 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;
}
(and yes, that typo signalHander is in the original and i am preserving it. archival queen behavior. π)
so the class Signal exists to let the signal handler 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. that's the glow-up. β¨
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's 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 (scroll down for an example). π
β οΈ important, bestie, do NOT skip this: as the signal may arrive at unpredicable times, data members that can be modified bysignalHandlershould be declared using thevolatilemodifier. moreover, data that can be modified by thesignalHandlermember and by other class members should be protected by mutexes (cf. the C++-11 classstd::mutexorpthread_mutex_lock(3posix)). this is not a vibe suggestion, this is a "your program will be haunted" situation. π
π 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. so like. it's not the one inheriting. it's the one being inherited from. the main character energy is honestly reversed here and that's fine. π
π CONSTRUCTORS AND OVERLOADED OPERATORS π
Signal is defined as a singleton, and it does not offer public or protected constructors, nor does it offer overloaded operators. there's exactly one. no clones. no sequels. no overloads. periodt. π
β STATIC MEMBER FUNCTION β
static Signal &instance()β this static member can be used to access a reference to the program's singleSignalobject. the one. the only. π«Ά
π 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. yeah we said it twice. it matters.
void add(size_t signum, SignalHandler &object)β theSignalHandlerobjectis activated on arrival of signalsignum. if multipleSignalHandlerobjects must be called, then multipleSignal::addcalls can be provided, and the variousSignalHandler::signalHandlermembers are called in the same sequence as their respectiveSignal::addcalls. if one of the earliersignalHandlermembers terminates the program, then latersignalHandlermembers are not activated anymore. also: ifSignal::addis called by, e.g., an object's constructor, then its destructor should callSignal::removeto prevent the object's signal handler from being called after its destruction. (that last one is the classic oopsie. don't be that girl. π)void remove(size_t signum, SignalHandler &object)β theSignalHandlerobjectfor signalsignumis removed from theSignalobject. it is the responsibility ofobjectto deregister itself fromSignaljust beforeobjectgoes out of scope. objects can only deregister themselves if they've previously registered themselves usingadd. no take-backs for things you never did. πvoid ignore(size_t signum)β any previously installedSignalHandlerobject is no longer activated on arrival of signalsignum. in addition, if possible, signalsignumis completely ignored (some signals cannot be caught, blocked, of ignored, likeSIGKILLandSIGSTOP(cf.signal(7))). yes that "of ignored" is in the original, we love her, she stays. πvoid reset(size_t signum)β any previously installedSignalHandlerobject is no longer activated on arrival of signalsignum. in addition, the default action the program takes on arrival of signalsignumis reinstalled (cf.signal(7)). back to factory settings. πΈ
heads up: if thesignumvalue that is passed toSignal's members is not a defined signal value, then anFBB::Exceptionexception is thrown. so like, validate your inputs. π
π₯ EXAMPLE π₯
this is the full demo. every line. no skipping. (it slays, honestly.)
#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();
}
notice the volatile on d_signal and d_continue? that's the description section paying rent. π
πΈ FILES πΈ
bobcat/signalβ defines the class interface
π¦ SEE ALSO π¦
bobcat(7)pthread_mutex_lock(3posix)signal(7)- and the C++-11 class
std::mutex.
π BUGS π
None Reported. (not me being suspiciously calm about that. π)
π BOBCAT PROJECT FILES π
- https://fbb-git.gitlab.io/bobcat/: gitlab project page;
Debian Bobcat project files:
libbobcat6: debian package containing the shared library, changelog and copyright note;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β. yes it's an acronym and it's a cat. we stan a double threat. π±
π 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).
okay that's the whole page bestie, you're officially Signal-literate, go forth and handle signals in context, protect your shared data with mutexes, and never call a signal handler after destruction. π«Ά
signing off from FBB::Signal(3bobcat) β this lovely thing ships as libbobcat-dev_6.15.01, dated 2005-2026, and you read every word, which is honestly iconic of you. β¨πΊπ
π¦ where this page comes from
- ubuntu stonking: libbobcat-dev 6.15.01-1 Β· GPL-3.0-or-later WITH OpenSSL exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms