diff --git a/Main/gserver.cpp b/Main/gserver.cpp index f8f6248..b7e7532 100644 --- a/Main/gserver.cpp +++ b/Main/gserver.cpp @@ -11,13 +11,13 @@ using namespace std; -#define GSERVER_PORT_FILE "bin/.gserver_port" -#define GSERVER_PORT_SWAP "bin/.gserver_port.swap" -#define GSERVER_LOG "logs/gserver.log" +//#define GSERVER_PORT_FILE "bin/.gserver_port" +//#define GSERVER_PORT_SWAP "bin/.gserver_port.swap" +//#define GSERVER_LOG "logs/gserver.log" bool isOnlyProcess(const char* argv0); void checkSwap(); -bool startServer(); +bool startServer(bool _debug); bool stopServer(); int main(int argc, char* argv[]) @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) return -1; } - if (mode == "-h" || mode == "--help") { + else if (mode == "-h" || mode == "--help") { cout << endl; cout << "gStore Server (gServer)" << endl; cout << endl; @@ -52,6 +52,7 @@ int main(int argc, char* argv[]) cout << "\t-r,--restart\t\tRestart gServer." << endl; cout << "\t-p,--port [PORT=" << Socket::DEFAULT_CONNECT_PORT << "]\tChange connection port configuration, takes effect after restart if gServer running." << endl; cout << "\t-P,--printport\t\tDisplay current connection port configuration." << endl; + cout << "\t-d,--debug\t\tStart gServer in debug mode (keep gServer in the foreground)." << endl; cout << "\t-k,--kill\t\tKill existing gServer process(es), ONLY use when out of normal procedures." << endl; cout << endl; return 0; @@ -70,7 +71,8 @@ int main(int argc, char* argv[]) } } if (!isOnlyProcess(argv[0])) { - ofstream out(GSERVER_PORT_SWAP, ios::out); + //ofstream out(GSERVER_PORT_SWAP, ios::out); + ofstream out(Util::gserver_port_swap.c_str()); if (!out) { cout << "Failed to change port!" << endl; return -1; @@ -80,7 +82,8 @@ int main(int argc, char* argv[]) cout << "Port will be changed to " << port << " after the current server stops or restarts." << endl; return 0; } - ofstream out(GSERVER_PORT_FILE, ios::out); + //ofstream out(GSERVER_PORT_FILE, ios::out); + ofstream out(Util::gserver_port_file.c_str()); if (!out) { cout << "Failed to change port!" << endl; return -1; @@ -91,12 +94,17 @@ int main(int argc, char* argv[]) return 0; } - if (mode == "-s" || mode == "--start") { + else if (mode == "-s" || mode == "--start") { if (!isOnlyProcess(argv[0])) { cout << "gServer already running!" << endl; return -1; } - if (startServer()) { + if (startServer(false)) { + sleep(1); + if (isOnlyProcess(argv[0])) { + cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl; + return -1; + } return 0; } else { @@ -104,7 +112,7 @@ int main(int argc, char* argv[]) } } - if (mode == "-t" || mode == "--stop") { + else if (mode == "-t" || mode == "--stop") { if (isOnlyProcess(argv[0])) { cout << "gServer not running!" << endl; return -1; @@ -117,7 +125,7 @@ int main(int argc, char* argv[]) } } - if (mode == "-r" || mode == "--restart") { + else if (mode == "-r" || mode == "--restart") { if (isOnlyProcess(argv[0])) { cout << "gServer not running!" << endl; return -1; @@ -125,22 +133,32 @@ int main(int argc, char* argv[]) if (!stopServer()) { return -1; } - if (!startServer()) { + if (startServer(false)) { + sleep(1); + if (isOnlyProcess(argv[0])) { + cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl; + return -1; + } + return 0; + } + else { return -1; } return 0; } - if (mode == "-P" || mode == "--printport") { + else if (mode == "-P" || mode == "--printport") { unsigned short port = Socket::DEFAULT_CONNECT_PORT; - ifstream in(GSERVER_PORT_FILE); + //ifstream in(GSERVER_PORT_FILE); + ifstream in(Util::gserver_port_file.c_str()); if (in) { in >> port; in.close(); } cout << "Current connection port is " << port << '.' << endl; unsigned short portSwap = 0; - ifstream inSwap(GSERVER_PORT_SWAP); + //ifstream inSwap(GSERVER_PORT_SWAP); + ifstream inSwap(Util::gserver_port_swap.c_str()); if (inSwap) { inSwap >> portSwap; inSwap.close(); @@ -151,7 +169,7 @@ int main(int argc, char* argv[]) return 0; } - if (mode == "-k" || mode == "--kill") { + else if (mode == "-k" || mode == "--kill") { if (isOnlyProcess(argv[0])) { cout << "No process to kill!" << endl; return -1; @@ -160,8 +178,10 @@ int main(int argc, char* argv[]) return 0; } - cout << "Invalid arguments! Input \"bin/gserver -h\" for help." << endl; - return -1; + else { + cerr << "Invalid arguments! Type \"bin/gserver -h\" for help." << endl; + return -1; + } } bool isOnlyProcess(const char* argv0) { @@ -169,10 +189,12 @@ bool isOnlyProcess(const char* argv0) { } void checkSwap() { - if (access(GSERVER_PORT_SWAP, 00) != 0) { + //if (access(GSERVER_PORT_SWAP, 00) != 0) { + if (access(Util::gserver_port_swap.c_str(), 00) != 0) { return; } - ifstream in(GSERVER_PORT_SWAP, ios::in); + //ifstream in(GSERVER_PORT_SWAP, ios::in); + ifstream in(Util::gserver_port_swap.c_str()); if (!in) { cout << "Failed in checkSwap(), port may not be changed." << endl; return; @@ -180,27 +202,33 @@ void checkSwap() { unsigned short port; in >> port; in.close(); - ofstream out(GSERVER_PORT_FILE, ios::out); + //ofstream out(GSERVER_PORT_FILE, ios::out); + ofstream out(Util::gserver_port_file.c_str()); if (!out) { cout << "Failed in checkSwap(), port may not be changed." << endl; return; } out << port; out.close(); - chmod(GSERVER_PORT_FILE, 0644); - string cmd = string("rm ") + GSERVER_PORT_SWAP; + //chmod(GSERVER_PORT_FILE, 0644); + chmod(Util::gserver_port_file.c_str(), 0644); + //string cmd = string("rm ") + GSERVER_PORT_SWAP; + string cmd = string("rm ") + Util::gserver_port_swap; system(cmd.c_str()); } -bool startServer() { +bool startServer(bool _debug) { unsigned short port = Socket::DEFAULT_CONNECT_PORT; - ifstream in(GSERVER_PORT_FILE, ios::in); + //ifstream in(GSERVER_PORT_FILE, ios::in); + ifstream in(Util::gserver_port_file.c_str()); if (!in) { - ofstream out(GSERVER_PORT_FILE, ios::out); + //ofstream out(GSERVER_PORT_FILE, ios::out); + ofstream out(Util::gserver_port_file.c_str()); if (out) { out << port; out.close(); - chmod(GSERVER_PORT_FILE, 0644); + //chmod(GSERVER_PORT_FILE, 0644); + chmod(Util::gserver_port_file.c_str(), 0644); } } else { @@ -208,6 +236,17 @@ bool startServer() { in.close(); } + if (_debug) { + Server server(port); + if (!server.createConnection()) { + cerr << Util::getTimeString() << "Failed to create connection at port " << port << '.' << endl; + return false; + } + cout << Util::getTimeString() << "Server started at port " << port << '.' << endl; + server.listen(); + return true; + } + pid_t fpid = fork(); // child @@ -215,23 +254,51 @@ bool startServer() { if (!Util::dir_exist("logs")) { Util::create_dir("logs"); } - freopen(GSERVER_LOG, "a", stdout); - freopen(GSERVER_LOG, "a", stderr); - Server server(port); - if (!server.createConnection()) { - cout << Util::getTimeString() << "Failed to create connection at port " << port << '.' << endl; - return false; + freopen(Util::gserver_log.c_str(), "a", stdout); + freopen(Util::gserver_log.c_str(), "a", stderr); + + int status; + + while (true) { + fpid = fork(); + + // child, main process + if (fpid == 0) { + Server server(port); + if (!server.createConnection()) { + cerr << Util::getTimeString() << "Failed to create connection at port " << port << '.' << endl; + return false; + } + cout << Util::getTimeString() << "Server started at port " << port << '.' << endl; + server.listen(); + exit(0); + return true; + } + + // parent, deamon process + else if (fpid > 0) { + waitpid(fpid, &status, 0); + if (WIFEXITED(status)) { + exit(0); + return true; + } + cerr << Util::getTimeString() << "Server stopped abnormally, restarting server..." << endl; + } + + // fork failure + else { + cerr << Util::getTimeString() << "Failed to start server: deamon fork failure." << endl; + return false; + } } - cout << Util::getTimeString() << "Server started at port " << port << '.' << endl; - server.listen(); - exit(0); - return true; } + // parent else if (fpid > 0) { cout << "Server started at port " << port << '.' << endl; return true; } + // fork failure else { cout << "Failed to start server at port " << port << '.' << endl; @@ -241,7 +308,8 @@ bool startServer() { bool stopServer() { unsigned short port = Socket::DEFAULT_CONNECT_PORT; - ifstream in(GSERVER_PORT_FILE, ios::in); + //ifstream in(GSERVER_PORT_FILE, ios::in); + ifstream in(Util::gserver_port_file.c_str()); if (in) { in >> port; in.close(); @@ -262,3 +330,4 @@ bool stopServer() { checkSwap(); return true; } +