summaryrefslogtreecommitdiff
path: root/src/common/core.cpp
blob: a6a170ba605cd141d3c6117e7e29b00c5aa651f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "core.hpp"

#include <sys/wait.h>

#include <unistd.h>

#include <csignal>
#include <cstdio>
#include <cstdlib>

#include "mt_rand.hpp"
#include "nullpo.hpp"
#include "socket.hpp"
#include "timer.hpp"
#include "version.hpp"

// Added by Gabuzomeu
//
// This is an implementation of signal() using sigaction() for portability.
// (sigaction() is POSIX; signal() is not.)  Taken from Stevens' _Advanced
// Programming in the UNIX Environment_.
//
typedef void(*sigfunc)(int);
static
sigfunc compat_signal(int signo, sigfunc func)
{
    struct sigaction sact, oact;

    sact.sa_handler = func;
    sigfillset(&sact.sa_mask);
    sigdelset(&sact.sa_mask, SIGSEGV);
    sigdelset(&sact.sa_mask, SIGBUS);
    sigdelset(&sact.sa_mask, SIGTRAP);
    sigdelset(&sact.sa_mask, SIGILL);
    sigdelset(&sact.sa_mask, SIGFPE);
    sact.sa_flags = 0;

    if (sigaction(signo, &sact, &oact) < 0)
        return SIG_ERR;

    return oact.sa_handler;
}

static
void chld_proc(int)
{
    wait(NULL);
}
static
void sig_proc(int)
{
    for (int i = 1; i < 31; ++i)
        compat_signal(i, SIG_IGN);
    term_func();
    _exit(0);
}

bool runflag = true;

/*
    Note about fatal signals:

    Under certain circumstances,
    the following signals MUST not be ignored:
    SIGFPE, SIGSEGV, SIGILL
    Unless you use SA_SIGINFO and *carefully* check the origin,
    that means they must be SIG_DFL.
 */
int main(int argc, char **argv)
{
    /// Note that getpid() and getppid() may be very close
    mt_seed(time(NULL) ^ (getpid() << 16) ^ (getppid() << 8));

    do_socket();

    do_init(argc, argv);
    // set up exit handlers *after* the initialization has happened.
    // This is because term_func is likely to depend on successful init.

    compat_signal(SIGPIPE, SIG_IGN);
    compat_signal(SIGTERM, sig_proc);
    compat_signal(SIGINT, sig_proc);
    compat_signal(SIGCHLD, chld_proc);

    // Signal to create coredumps by system when necessary (crash)
    compat_signal(SIGSEGV, SIG_DFL);
    compat_signal(SIGBUS, SIG_DFL);
    compat_signal(SIGTRAP, SIG_DFL);
    compat_signal(SIGILL, SIG_DFL);
    compat_signal(SIGFPE, SIG_DFL);

    atexit(term_func);

    while (runflag)
    {
        do_sendrecv(do_timer(gettick_nocache()));
        do_parsepacket();
    }
}