CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON)
CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
+CHECK_SYMBOL_EXISTS(SA_SIGINFO signal.h HAVE_SA_SIGINFO)
CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL)
CHECK_C_SOURCE_COMPILES ("#include <sys/types.h>
#cmakedefine HAVE_FLOCK 1
+#cmakedefine HAVE_SA_SIGINFO 1
+
#cmakedefine DEBUG_MODE 1
#cmakedefine GMIME24 1
static gboolean controller_write_socket (void *arg);
-static
- void
+#ifndef HAVE_SA_SIGINFO
+static void
sig_handler (int signo)
+#else
+static void
+sig_handler (int signo, siginfo_t *info, void *unused)
+#endif
{
switch (signo) {
case SIGINT:
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-
+#include "config.h"
#include "mem_pool.h"
#include "filter.h"
#include "main.h"
uint64_t time;
};
+#ifndef HAVE_SA_SIGINFO
static void
sig_handler (int signo)
+#else
+static void
+sig_handler (int signo, siginfo_t *info, void *unused)
+#endif
{
switch (signo) {
case SIGINT:
static gboolean lmtp_write_socket (void *arg);
-static
- void
+#ifndef HAVE_SA_SIGINFO
+static void
sig_handler (int signo)
+#else
+static void
+sig_handler (int signo, siginfo_t *info, void *unused)
+#endif
{
switch (signo) {
case SIGINT:
rspamd_hash_t *counters;
-static void sig_handler (int);
static struct rspamd_worker *fork_worker (struct rspamd_main *, struct worker_conf *);
sig_atomic_t do_restart;
sig_atomic_t child_dead;
sig_atomic_t got_alarm;
+#ifdef HAVE_SA_SIGINFO
+GQueue *signals_info;
+#endif
+
extern int yynerrs;
extern FILE *yyin;
/* List of workers that are pending to start */
static GList *workers_pending = NULL;
-static
- void
+#ifndef HAVE_SA_SIGINFO
+static void
sig_handler (int signo)
+#else
+static void
+sig_handler (int signo, siginfo_t *info, void *unused)
+#endif
{
+#ifdef HAVE_SA_SIGINFO
+ siginfo_t *new_info;
+ new_info = g_malloc (sizeof (siginfo_t));
+ memcpy (new_info, info, sizeof (siginfo_t));
+ g_queue_push_head (signals_info, new_info);
+#endif
+
switch (signo) {
case SIGHUP:
do_restart = 1;
}
}
+#ifdef HAVE_SA_SIGINFO
+
+static const char *
+strsigcode (int code)
+{
+ switch (code) {
+ case SI_USER:
+ return "kill(2) or raise(3)";
+ break;
+ case SI_KERNEL:
+ return "sent by the kernel";
+ break;
+ case SI_TIMER:
+ return "POSIX timer expired";
+ break;
+ case SI_SIGIO:
+ return "queued SIGIO";
+ break;
+ default:
+ return "unknown reason";
+ }
+}
+
+static const char *
+chldsigcode (int code) {
+ switch (code) {
+ case CLD_EXITED:
+ return "Child exited normally";
+ case CLD_KILLED:
+ return "Child has terminated abnormally but did not create a core file";
+ case CLD_DUMPED:
+ return "Child has terminated abnormally and created a core file";
+ case CLD_TRAPPED:
+ return "Traced child has trapped";
+ default:
+ return "Unknown reason";
+ }
+}
+
+/* Prints info about incoming signals by parsing siginfo structures */
+static void
+print_signals_info ()
+{
+ siginfo_t *inf;
+
+ while ((inf = g_queue_pop_head (signals_info))) {
+ if (inf->si_signo == SIGCHLD) {
+ msg_info ("main: got SIGCHLD from child: %ld; reason: '%s'",
+ (long int)inf->si_pid, chldsigcode (inf->si_code));
+ }
+ else {
+ msg_info ("main: got signal: '%s'; received from pid: %ld; uid: %ld; reason: '%s'",
+ g_strsignal (inf->si_signo), (long int)inf->si_pid, (long int)inf->si_uid,
+ strsigcode (inf->si_code));
+ }
+ g_free (inf);
+ }
+}
+#endif
+
+
static void
read_cmd_line (int argc, char **argv, struct config_file *cfg)
{
char *args[] = { "", "-e", "0", NULL };
#endif
+#ifdef HAVE_SA_SIGINFO
+ signals_info = g_queue_new ();
+#endif
rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main));
bzero (rspamd, sizeof (struct rspamd_main));
rspamd->server_pool = memory_pool_new (memory_pool_get_size ());
msg_debug ("main: calling sigsuspend");
sigemptyset (&signals.sa_mask);
sigsuspend (&signals.sa_mask);
+#ifdef HAVE_SA_SIGINFO
+ print_signals_info ();
+#endif
if (do_terminate) {
msg_debug ("main: catch termination signal, waiting for childs");
pass_signal_worker (rspamd->workers, SIGTERM);
return 0;
}
+#ifdef HAVE_SA_SIGINFO
void
-init_signals (struct sigaction *signals, sig_t sig_handler)
+init_signals (struct sigaction *signals, void (*sig_handler)(int, siginfo_t *, void *))
+#else
+void
+init_signals (struct sigaction *signals, sighandler_t sig_handler)
+#endif
{
struct sigaction sigpipe_act;
/* Setting up signal handlers */
sigaddset (&signals->sa_mask, SIGALRM);
+#ifdef HAVE_SA_SIGINFO
+ signals->sa_flags = SA_SIGINFO;
+ signals->sa_handler = NULL;
+ signals->sa_sigaction = sig_handler;
+#else
signals->sa_handler = sig_handler;
signals->sa_flags = 0;
+#endif
sigaction (SIGTERM, signals, NULL);
sigaction (SIGINT, signals, NULL);
sigaction (SIGHUP, signals, NULL);
/* Poll sync socket for specified events */
int poll_sync_socket (int fd, int timeout, short events);
/* Init signals */
-void init_signals (struct sigaction *, sig_t);
+#ifdef HAVE_SA_SIGINFO
+void init_signals (struct sigaction *sa, void (*sig_handler)(int, siginfo_t *, void *));
+#else
+void init_signals (struct sigaction *sa, sighandler_t);
+#endif
/* Send specified signal to each worker */
void pass_signal_worker (GHashTable *, int );
/* Convert string to lowercase */
static gboolean write_socket (void *arg);
-static
- void
+#ifndef HAVE_SA_SIGINFO
+static void
sig_handler (int signo)
+#else
+static void
+sig_handler (int signo, siginfo_t *info, void *unused)
+#endif
{
switch (signo) {
case SIGINT: