fixed game_uno +2/+4 timeout handling
[NeonServV5.git] / src / signal.c
1 /* signal.c - NeonServ v5.6
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17 #include "signal.h"
18 #include "bots.h"
19 #include "ChanNode.h"
20 #include "ClientSocket.h"
21 #include "IOHandler.h"
22 #include "ConfigParser.h"
23 #include "log.h"
24
25 static void sigcrash();
26 static void sigexit();
27
28 void sighandler(int signum) {
29     printf_log("main", LOG_INFO, "Received Signal %d\n", signum);
30     signal(signum, SIG_DFL);
31     switch(signum) {
32         case SIGABRT:
33         case SIGTERM:
34         case SIGINT:
35             //normal shutdown
36             sigexit(signum);
37             break;
38         case SIGSEGV:
39         case SIGFPE:
40         case SIGILL:
41             //crash
42             sigcrash(signum);
43             break;
44     }
45     #ifdef WIN32
46     exit(signum);
47     #else
48     kill(getpid(), signum);
49     #endif
50 }
51
52 static void sigcrash(int signum) {
53     char coregen[MAXLEN];
54         coregen[0] = 0;
55     char *signame;
56     switch(signum) {
57         case SIGSEGV:
58             signame = "SIGSEGV";
59             break;
60         case SIGFPE:
61             signame = "SIGFPE";
62             break;
63         case SIGILL:
64             signame = "SIGILL";
65             break;
66         default:
67             signame = "SIGUNKNOWN";
68             break;
69     }
70     printf_log("main", LOG_ERROR, "NeonServ process crashed (%s)\n", signame);
71     #ifndef WIN32
72     char gcore[50];
73     sprintf(gcore, "gcore %u", getpid());
74     int sysretn = system(gcore); //generate core file
75     sprintf(coregen, "core file generated. (%d)", sysretn);
76     printf_log("main", LOG_ERROR | LOG_INFO, "generated core file.\n");
77     #endif
78     //close all bots
79     struct ClientSocket *bot;
80     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
81         if((bot->flags & SOCKET_FLAG_CONNECTED)) {
82             iohandler_close(bot->iofd);
83             bot->flags &= ~(SOCKET_FLAG_CONNECTED | SOCKET_FLAG_READY);
84             bot->iofd = NULL;
85         }
86     }
87     printf_log("main", LOG_INFO, "hard shutdown...\n");
88     usleep(2000000);
89     //hard restart
90     restart_bot(1);
91     exit(0);
92 }
93
94 static void sigexit(int signum) {
95     stop_bot();
96 }