Al compilar el codigo de aquí abajo con 'g++ senyaloriginal.cpp' me da error al linkar. Alguien me puede decir porque? Es un codigo copiado que a priori tendría que fucionar. Lo que pasa es que he cojido los trozitos de un documento y quizas el orden de las clases no este bien. Todo este codigo lo tengo metido en un único fichero.
#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
class Event_Handler
{
public:
// Hook method for the signal hook method.
virtual int handle_signal (int signum) = 0;
// ... other hook methods for other types of
// events such as timers, I/O, and
// synchronization objects.
};
class Signal_Handler
{
public:
// Entry point.
static Signal_Handler *instance (void);
// Register an event handler <eh> for <signum>
// and return a pointer to any existing <Event_Handler>
// that was previously registered to handle <signum>.
Event_Handler *register_handler (int signum,Event_Handler *eh);
// Remove the <Event_Handler> for <signum>
// by setting the slot in the <signal_handlers_>
// table to NULL.
int remove_handler (int signum);
private:
// Ensure we're a Singleton.
Signal_Handler (void);
// Singleton pointer.
static Signal_Handler *instance_;
// Entry point adapter installed into <sigaction>
// (must be a static method or a stand-alone
// extern "C" function).
static void dispatcher (int signum);
// Table of pointers to concrete <Event_Handler>s
// registered by applications. NSIG is the number of
// signals defined in </usr/include/sys/signal.h>.
static Event_Handler *signal_handlers_[NSIG];
};
Event_Handler * Signal_Handler::register_handler (int signum, Event_Handler *eh){
// Copy the <old_eh> from the <signum> slot in
// the <signal_handlers_> table.
Event_Handler *old_eh = Signal_Handler::signal_handlers_[signum];
// Store <eh> into the <signum> slot in the
// <signal_handlers_> table.
Signal_Handler::signal_handlers_[signum] = eh;
// Register the <dispatcher> to handle this
// <signum>.
struct sigaction sa;
sa.sa_handler = Signal_Handler::dispatcher;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
sigaction (signum, &sa, 0);
return old_eh;
}
void Signal_Handler::dispatcher (int signum){
// Perform a sanity check...
if (Signal_Handler::signal_handlers_[signum] != 0)
// Dispatch the handler's hook method.
Signal_Handler::signal_handlers_
[signum]->handle_signal (signum);
}
class SIGINT_Handler : public Event_Handler{
public:
SIGINT_Handler (void)
: graceful_quit_ (0) {}
// Hook method.
virtual int handle_signal (int signum){
assert (signum == SIGINT);
this->graceful_quit_ = 1;
}
// Accessor.
sig_atomic_t graceful_quit (void)
{ return this->graceful_quit_; }
private:
sig_atomic_t graceful_quit_;
};
class SIGQUIT_Handler : public Event_Handler{
public:
SIGQUIT_Handler (void)
: abortive_quit_ (0) {}
// Hook method.
virtual int handle_signal (int signum){
assert (signum == SIGQUIT);
this->abortive_quit_ = 1;
}
// Accessor.
sig_atomic_t abortive_quit (void)
{ return this->abortive_quit_; }
private:
sig_atomic_t abortive_quit_;
};
int main (void){
SIGINT_Handler sigint_handler;
SIGQUIT_Handler sigquit_handler;
// Register the handler for SIGINT.
Signal_Handler::instance ()->register_handler (SIGINT, &sigint_handler);
// Register the handler for SIGQUIT.
Signal_Handler::instance ()->register_handler (SIGQUIT, &sigquit_handler);
// Run the main event loop.
while (sigint_handler.graceful_quit () == 0 && sigquit_handler.abortive_quit () == 0)
printf("treballa");
if (sigquit_handler.abortive_quit () == 1)
_exit (1);
else /* if sigint_handler.graceful_quit () */ {
printf("neteja");
return 1;
}
}