30 void gcleanup_unix_handler_(
int signum ) ;
31 typedef void (*Handler)( int ) ;
45 static void add(
void (*fn)(
SignalSafe,
const char*) ,
const char * ) ;
48 static void installDefault(
const SignalSafe & ,
int ) ;
51 static void installDefault(
int ) ;
54 static void installIgnore(
int ) ;
60 static void atexit(
bool active ) ;
78 static void install(
int , Handler ,
bool ) ;
79 static void installHandler(
int ) ;
80 static bool ignored(
int ) ;
81 static void atexitHandler() ;
82 static Link * new_link_ignore_leak() ;
85 static Link * m_head ;
86 static Link * m_tail ;
87 static bool m_atexit_active ;
88 static bool m_atexit_installed ;
91 G::CleanupImp::Link * G::CleanupImp::m_head = nullptr ;
92 G::CleanupImp::Link * G::CleanupImp::m_tail = nullptr ;
93 bool G::CleanupImp::m_atexit_installed = false ;
94 bool G::CleanupImp::m_atexit_active = false ;
100 CleanupImp::installIgnore( SIGPIPE ) ;
105 CleanupImp::add( fn , arg ) ;
110 CleanupImp::atexit( active ) ;
115 void G::CleanupImp::init()
120 installIgnore( SIGPIPE ) ;
121 installHandler( SIGTERM ) ;
122 installHandler( SIGINT ) ;
123 installHandler( SIGHUP ) ;
124 installHandler( SIGQUIT ) ;
129 void G::CleanupImp::add(
void (*fn)(SignalSafe,
const char*) ,
const char * arg )
131 Link * p = new_link_ignore_leak() ;
139 if( m_head ==
nullptr ) init() ;
140 if( m_tail !=
nullptr ) m_tail->next = p ;
142 if( m_head ==
nullptr ) m_head = p ;
145 G::CleanupImp::Link * G::CleanupImp::new_link_ignore_leak()
150 void G::CleanupImp::installHandler(
int signum )
152 if( ignored(signum) )
153 G_DEBUG(
"G::CleanupImp::installHandler: signal " << signum <<
" is ignored" ) ;
155 install( signum , gcleanup_unix_handler_ ,
true ) ;
158 bool G::CleanupImp::ignored(
int signum )
160 static struct sigaction zero_action ;
161 struct sigaction action( zero_action ) ;
162 if( ::sigaction( signum ,
nullptr , &action ) )
163 throw Cleanup::Error(
"sigaction" ) ;
164 return action.sa_handler == SIG_IGN ;
167 void G::CleanupImp::installDefault(
int signum )
169 install( signum , SIG_DFL ,
true ) ;
172 void G::CleanupImp::installDefault(
const G::SignalSafe & ,
int signum )
174 install( signum , SIG_DFL ,
false ) ;
177 void G::CleanupImp::installIgnore(
int signum )
179 install( signum , SIG_IGN ,
true ) ;
182 void G::CleanupImp::install(
int signum , Handler fn ,
bool do_throw )
185 static struct sigaction zero_action ;
186 struct sigaction action( zero_action ) ;
187 action.sa_handler = fn ;
188 if( ::sigaction( signum , &action ,
nullptr ) && do_throw )
189 throw Cleanup::Error(
"sigaction" ) ;
192 void G::CleanupImp::atexit(
bool active )
194 if( active && !m_atexit_installed )
196 m_atexit_installed = true ;
197 ::atexit( atexitHandler ) ;
199 m_atexit_active = active ;
202 void G::CleanupImp::atexitHandler()
204 if( m_atexit_active )
205 callHandlers( SignalSafe() ) ;
208 void G::CleanupImp::callHandlers( SignalSafe )
211 for(
const Link * p = m_head ; p != nullptr ; p = p->next )
215 (*(p->fn))(SignalSafe(),p->arg) ;
225 void gcleanup_unix_handler_(
int signum )
static void atexit(bool active=true)
Ensures that the cleanup functions are also called via atexit(), in addition to abnormal-termination ...
An empty structure that is used to indicate a signal-safe, reentrant implementation.
static Identity start(SignalSafe)
A signal-safe alternative to construction.
static void stop(SignalSafe, Identity)
A signal-safe alternative to destruction.
static void init()
An optional early-initialisation function. May be called more than once.
A pimple-pattern implementation class used by G::Cleanup.
static void add(void(*fn)(SignalSafe, const char *), const char *arg)
Adds the given handler to the list of handlers that are to be called when the process terminates abno...