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
|
#include "chatServer.hpp"
#include "log.hpp"
#include <algorithm>
#include <csignal>
#include <unistd.h>
#include <vector>
static void handleSignal(int sig) {
signal(sig, SIG_DFL);
log(SYS, "Caught signal: {}", sig);
switch (sig) {
default:
// quick_exit(less cleanup) if the cleanup took too long
signal(SIGALRM, [](int) { std::_Exit(1); });
alarm(5);
std::exit(0);
break;
}
}
static void registerSignals() {
signal(SIGINT, handleSignal);
signal(SIGTERM, handleSignal);
// client may not finish reading hence the server will receive SIGPIPE, we don't want that to just crash the server
signal(SIGPIPE, SIG_IGN);
}
static void help() {
log(ERR, "usage: chat-server <port>");
}
int main(int argc, char *argv[]) try {
std::vector<std::string> args{argv + 1, argv + argc};
if (args.empty()) {
help();
return EXIT_FAILURE;
}
uint16_t port = 0;
for (const auto &arg : args) {
if (arg == "-h" || arg == "--help") {
help();
return EXIT_SUCCESS;
} else if (std::ranges::all_of(arg, ::isdigit)) {
port = std::stoi(arg);
if (port < 0) {
log(ERR, "Port number must be greater than 0");
return EXIT_FAILURE;
} else if (port > 65535) {
log(ERR, "Port number must be less than 65536");
return EXIT_FAILURE;
}
log(LOG, "Port number: {}", port);
}
}
if (port == 0) {
log(ERR, "Port number is required");
help();
return EXIT_FAILURE;
}
registerSignals();
g_pChatServer = std::make_unique<CChatServer>(port);
g_pChatServer->start();
// died
g_pChatServer->cleanup();
g_pChatServer.reset();
return EXIT_SUCCESS;
} catch (const std::exception &e) {
log(ERR, "Fatal error: {}", e.what());
return EXIT_FAILURE;
} catch (...) {
log(ERR, "Unknown fatal error occurred");
return EXIT_FAILURE;
}
|