/* * async.c - functions to be called asynchronously (in signal handlers) * also functions for non-standard operations over whole daemon */ #include #include #include #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; } }