8 #ifndef INCL_evo_process_h 9 #define INCL_evo_process_h 16 #include <sys/types.h> 42 return ::GetCurrentProcessId();
69 #define EVO_TEMP_LOG_ERR(MSG, ...) { \ 71 fprintf(stderr, "daemonize: " MSG "\n", __VA_ARGS__); \ 73 syslog(LOG_ERR, "fork() failed: %s", strerror(errno)); \ 78 openlog(
"daemonize", LOG_PID, LOG_DAEMON);
105 if ((flags & DAEMONIZE_NO_CD) == 0 && chdir(
"/") != 0)
109 if (flags & DAEMONIZE_NO_REDIR) {
111 close(STDOUT_FILENO);
113 close(STDERR_FILENO);
114 if (open(
"/dev/null", O_RDWR) != 0) {
118 if (dup(STDIN_FILENO) == -1)
120 if (!use_stderr && dup(STDIN_FILENO) == -1)
131 if (!result && (flags & DAEMONIZE_NO_EXIT) == 0)
135 #undef EVO_TEMP_LOG_ERR 247 fprintf(stderr,
"Signal::set_on_shutdown() failed\n");
277 global_server() = &server;
282 global_server()->shutdown();
286 static T*& global_server() {
287 static T* server = NULL;
299 State& state = get_state();
302 if (on_shutdown != NULL && !state.registered) {
303 if (::SetConsoleCtrlHandler(main_handler, TRUE) != TRUE)
305 state.registered =
true;
311 state.on_shutdown = on_shutdown;
323 State& state = get_state();
325 state.shutdown_flag =
true;
326 state.condmutex.notify_all();
339 State& state = get_state();
341 state.handlers.remove(get_signum(type));
342 if (state.registered && state.on_shutdown == NULL && state.handlers.empty()) {
343 ::SetConsoleCtrlHandler(main_handler, FALSE);
344 state.registered =
false;
351 return (::SetConsoleCtrlHandler(NULL, TRUE) == TRUE);
354 const int signum = get_signum(type);
355 if (signum == INVALID_SIGNUM)
357 get_state().handlers.remove(signum);
359 struct sigaction action_data;
360 action_data.sa_handler = (action ==
aDEFAULT ? SIG_DFL : SIG_IGN);
361 action_data.sa_flags = 0;
362 sigemptyset(&action_data.sa_mask);
364 return (::sigaction(signum, &action_data, NULL) == 0);
374 State& state = get_state();
376 const DWORD signum = get_signum(type);
377 if (signum == INVALID_SIGNUM)
379 if (handler != NULL) {
381 state.handlers[signum] = handler;
382 if (state.registered)
385 if (::SetConsoleCtrlHandler(main_handler, TRUE) == TRUE) {
387 state.registered =
true;
391 const int signum = get_signum(type);
392 if (signum == INVALID_SIGNUM)
395 state.handlers[signum] = handler;
397 struct sigaction action_data;
398 action_data.sa_handler = main_handler;
399 action_data.sa_flags = 0;
400 sigfillset(&action_data.sa_mask);
402 return (::sigaction(signum, &action_data, NULL) == 0);
411 const SigNumType signum = get_signum(signal);
416 return (::GenerateConsoleCtrlEvent(signum, pid) == TRUE);
418 return (::kill(pid, signum) == 0);
438 shutdown_flag =
false;
443 static State& get_state() {
449 static const DWORD INVALID_SIGNUM = 0xFFFFFFFF;
451 static DWORD get_signum(
Type type) {
460 return INVALID_SIGNUM;
463 static Type get_sigtype(SigNumType value) {
475 static BOOL WINAPI main_handler(DWORD value) {
476 const Type type = get_sigtype(value);
478 State& state = get_state();
482 h = state.handlers.find(value);
488 if (state.registered && state.on_shutdown != NULL) {
490 (*state.on_shutdown)(value, type);
492 while (!state.shutdown_flag)
500 static const int INVALID_SIGNUM = -1;
502 static int get_signum(
Type type) {
506 case tPIPE:
return SIGPIPE;
507 case tCHILD:
return SIGCHLD;
508 case tHUP:
return SIGHUP;
509 case tUSER1:
return SIGUSR1;
510 case tUSER2:
return SIGUSR2;
513 return INVALID_SIGNUM;
516 static Type get_sigtype(
bool& shutdown, SigNumType value) {
519 case SIGINT: shutdown =
true;
return tINTERRUPT;
520 case SIGTERM: shutdown =
true;
return tTERMINATE;
521 case SIGPIPE:
return tPIPE;
522 case SIGCHLD:
return tCHILD;
523 case SIGHUP:
return tHUP;
524 case SIGUSR1:
return tUSER1;
525 case SIGUSR2:
return tUSER2;
531 static void main_handler(
int value) {
533 const Type type = get_sigtype(shutdown, value);
535 State& state = get_state();
536 const Handler* h = state.handlers.find(value);
540 if (shutdown && state.on_shutdown != NULL)
541 (*state.on_shutdown)(value, type);
#define EVO_TEMP_LOG_ERR(MSG,...)
static void shutdown_sync()
Sync shutdown with signal handler.
Definition: process.h:321
void(* OnShutdown)(SigNumType, Type)
General shutdown handler type.
Definition: process.h:223
User logging off, though which user is undefined (CTRL_LOGOFF_EVENT) [Windows, services only]...
Definition: process.h:218
Interrupted by Control-C (SIGINT) [Portable: Linux/Unix/Windows].
Definition: process.h:207
static bool set_handler(Type type, Handler handler)
Set signal handler.
Definition: process.h:373
bool error
Error flag, set to false on success.
Definition: process.h:230
Write on broken pipe (SIGPIPE) [Linux/Unix].
Definition: process.h:210
static bool set_on_shutdown(OnShutdown on_shutdown)
Set shutdown handler.
Definition: process.h:298
Evo implementation detail for system portability – this is included by most Evo headers, include this via: include <evo/type.h>.
Main(Signal::OnShutdown on_shutdown, bool except=1)
Constructor that sets up shutdown handler.
Definition: process.h:242
Action
Signal handling action.
Definition: process.h:198
Process signal handling.
Definition: process.h:189
Condition object for thread synchronization.
Definition: thread.h:243
User defined signal 2 (SIGUSR2) [Linux/Unix].
Definition: process.h:214
Terminal hangup, or daemon reload (SIGHUP) [Linux/Unix].
Definition: process.h:212
System shutting down (CTRL_SHUTDOWN_EVENT) [Windows, services only].
Definition: process.h:219
Evo threads implementation.
#define EVO_EXCEPTIONS
Whether to throw exceptions on error by default.
Definition: evo_config.h:35
Type
Signal type.
Definition: process.h:204
Child process terminated (SIGCHLD), ignored by default [Linux/Unix].
Definition: process.h:211
Unknown signal type (used internally)
Definition: process.h:205
Main()
Default constructor.
Definition: process.h:233
Smart locking for synchronization.
Definition: lock.h:28
void(* Handler)(SigNumType, Type)
Signal handler function type
Definition: process.h:222
static void on_shutdown(Signal::SigNumType, Signal::Type)
Default shutdown handler, called on shutdown signal.
Definition: process.h:281
Evo base exception class.
Definition: sys.h:1214
Ignore signal.
Definition: process.h:200
Evo C++ Library namespace.
Definition: alg.h:11
Use default handler, i.e. remove user handler.
Definition: process.h:199
Helper for common shutdown signal handling in program main().
Definition: process.h:229
static bool set_handler(Type type, Action action)
Set signal handling option.
Definition: process.h:335
General terminate (SIGTERM) [Portable: Linux/Unix/Windows].
Definition: process.h:208
static bool send_signal(ProcessId pid, Type signal)
Send signal to current process.
Definition: process.h:410
~Main()
Destructor.
Definition: process.h:255
MainServer(T &server, bool except=1)
Constructor that sets default shutdown handler for server.
Definition: process.h:276
Helper for common server shutdown signal handling in program main().
Definition: process.h:269
User defined signal 1 (SIGUSR1) [Linux/Unix].
Definition: process.h:213
Control-Break (CTRL_BREAK_EVENT) [Windows].
Definition: process.h:216
#define EVO_THROW(TYPE, MSG)
Throw an Evo exception.
Definition: sys.h:1446
static const ulong INF
Infinite wait timeout value.
Definition: thread.h:282
Process closed by user (CTRL_CLOSE_EVENT) [Windows].
Definition: process.h:217
int SigNumType
Signal number value type.
Definition: process.h:194