|
|
|
/*
|
|
|
|
* async.c - functions to be called asynchronously (in signal handlers)
|
|
|
|
* also functions for non-standard operations over whole daemon
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <syslog.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "async.h"
|
|
|
|
#include "task.h"
|
|
|
|
#include "trie.h"
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
extern int sockfd; //in daemon.c
|
|
|
|
|
|
|
|
void async_kill(int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Stopping");
|
|
|
|
exit(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_shutdown (int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Shutting down");
|
|
|
|
if(close(sockfd) == -1) {
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: close failed: %m");
|
|
|
|
}
|
|
|
|
if(unlink(cfg_socket) == -1) {
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: unlink failed: %m");
|
|
|
|
}
|
|
|
|
async_save(sig);
|
|
|
|
async_kill(sig);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_save(int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Saving everything");
|
|
|
|
task_save(cfg_task_file);
|
|
|
|
trie_save(cfg_trie_file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_flush(int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Flushing everything");
|
|
|
|
task_flush();
|
|
|
|
trie_flush();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_load (int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Loading everything");
|
|
|
|
task_load(cfg_task_file);
|
|
|
|
trie_load(cfg_trie_file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_restart (int sig) {
|
|
|
|
syslog(cfg_log_facility | LOG_INFO, "Restarting");
|
|
|
|
async_save(sig);
|
|
|
|
async_flush(sig);
|
|
|
|
async_load(sig);
|
|
|
|
}
|
|
|
|
|
|
|
|
void async_run (int sig, siginfo_t *info, void *unused) {
|
|
|
|
if (info == NULL) {
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: someone is kidding us, we will kid them back and do nothing");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint64_t *p_id = (info -> si_value).sival_ptr;
|
|
|
|
if (p_id == NULL) {
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: someone is kidding us again, we will kid them back and do nothing");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
struct task t = task_details(*p_id);
|
|
|
|
// And now run it
|
|
|
|
// First, fork
|
|
|
|
pid_t pid = fork();
|
|
|
|
if (pid == -1) {
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: cannot fork: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (pid > 0) {
|
|
|
|
//We said in daemon.h that we don't care for children
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (pid == 0) {
|
|
|
|
// Reset signal handler for SIGCHLD (other signals are defined by us and will be reset during exec()
|
|
|
|
struct sigaction siga;
|
|
|
|
siga.sa_handler = SIG_DFL;
|
|
|
|
sigaction(SIGCHLD, &siga, NULL);
|
|
|
|
|
|
|
|
// Exec
|
|
|
|
execvp(t.argv[0], t.argv);
|
|
|
|
syslog(cfg_log_facility | LOG_ERR, "async: cannot exec: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|