X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/90e389f6ec12e60a62c362296ffcf314feb5b03d..0907aa4037b12b6b88ee24495d4577a064d4f8db:/projects/rscriptd/main.cpp diff --git a/projects/rscriptd/main.cpp b/projects/rscriptd/main.cpp index 714da320..e7c54eec 100644 --- a/projects/rscriptd/main.cpp +++ b/projects/rscriptd/main.cpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include // strerror #include #include "stg/common.h" @@ -46,8 +48,6 @@ #include "listener.h" #include "pidfile.h" -using namespace std; - #ifdef DEBUG # define MAIN_DEBUG 1 # define NO_DAEMON 1 @@ -55,147 +55,29 @@ using namespace std; #define START_FILE "/._ST_ART_ED_" -static bool childExited = false; -set executersPid; -static pid_t stgChildPid; +std::set executersPid; volatile time_t stgTime = time(NULL); -class STG_STOPPER -{ -public: - STG_STOPPER() { nonstop = true; } - bool GetStatus() const { return nonstop; }; - void Stop(const char * __file__, int __line__) - { - #ifdef NO_DAEMON - printfd(__FILE__, "rscriptd stopped at %s:%d\n", __file__, __line__); - #endif - nonstop = false; - } -private: - bool nonstop; -}; -//----------------------------------------------------------------------------- -STG_STOPPER nonstop; -//----------------------------------------------------------------------------- -void CatchPROF(int) -{ -} -//----------------------------------------------------------------------------- -void CatchUSR1(int) -{ -} -//----------------------------------------------------------------------------- -void CatchTERM(int sig) -{ -/* - *Function Name:CatchINT - *Parameters: sig_num - signal number - *Description: INT signal handler - *Returns: Nothing - */ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Shutting down... %d", sig); - -nonstop.Stop(__FILE__, __LINE__); - -struct sigaction newsa, oldsa; -sigset_t sigmask; - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); -} -//----------------------------------------------------------------------------- -void CatchPIPE(int) -{ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Broken pipe!"); -} -//----------------------------------------------------------------------------- -void CatchHUP(int) -{ -} //----------------------------------------------------------------------------- -void CatchCHLD(int) +void KillExecuters() { -int status; -pid_t childPid; -childPid = waitpid(-1, &status, WNOHANG); - -set::iterator pid; -pid = executersPid.find(childPid); -if (pid != executersPid.end()) - { - executersPid.erase(pid); - } -if (childPid == stgChildPid) +std::set::iterator pid; +pid = executersPid.begin(); +while (pid != executersPid.end()) { - childExited = true; + printfd(__FILE__, "KillExecuters pid=%d\n", *pid); + kill(*pid, SIGUSR1); + ++pid; } } //----------------------------------------------------------------------------- -void SetSignalHandlers() -{ -struct sigaction newsa, oldsa; -sigset_t sigmask; - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGUSR1); -newsa.sa_handler = CatchUSR1; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGUSR1, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGPIPE); -newsa.sa_handler = CatchPIPE; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGPIPE, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGHUP); -newsa.sa_handler = CatchHUP; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGHUP, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGCHLD); -newsa.sa_handler = CatchCHLD; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGCHLD, &newsa, &oldsa); -} -//----------------------------------------------------------------------------- +#if defined(LINUX) || defined(DARWIN) int StartScriptExecuter(char * procName, int msgKey, int * msgID) +#else +int StartScriptExecuter(char *, int msgKey, int * msgID) +#endif { -STG_LOGGER & WriteServLog = GetStgLogger(); +auto & WriteServLog = STG::Logger::get(); if (*msgID == -11) // If msgID == -11 - first call. Create queue { @@ -237,29 +119,73 @@ switch (executerPid) //close(1); //close(2); //setsid(); - Executer(msgKey, *msgID, executerPid, procName); +#if defined(LINUX) || defined(DARWIN) + Executer(*msgID, executerPid, procName); +#else + Executer(*msgID, executerPid); +#endif return 1; default: // Parent if (executersPid.empty()) - Executer(msgKey, *msgID, executerPid, NULL); +#if defined(LINUX) || defined(DARWIN) + Executer(*msgID, executerPid, NULL); +#else + Executer(*msgID, executerPid); +#endif executersPid.insert(executerPid); } return 0; } //----------------------------------------------------------------------------- +void StopScriptExecuter(int msgID) +{ +auto & WriteServLog = STG::Logger::get(); + +for (int i = 0; i < 5; ++i) + { + struct msqid_ds data; + if (msgctl(msgID, IPC_STAT, &data)) + { + int e = errno; + printfd(__FILE__, "StopScriptExecuter() - msgctl for IPC_STAT failed: '%s'\n", strerror(e)); + WriteServLog( "Failed to check queue emptiness: '%s'", strerror(e)); + break; + } + + WriteServLog("Messages in queue: %d", data.msg_qnum); + + if (data.msg_qnum == 0) + break; + + struct timespec ts = {1, 0}; + nanosleep(&ts, NULL); + } + +if (msgctl(msgID, IPC_RMID, NULL)) + { + int e = errno; + printfd(__FILE__, "StopScriptExecuter() - msgctl for IPC_STAT failed: '%s'\n", strerror(e)); + WriteServLog("Failed to remove queue: '%s'", strerror(e)); + } +else + { + WriteServLog("Queue removed successfully."); + } + +KillExecuters(); +} +//----------------------------------------------------------------------------- #ifdef NO_DAEMON -int ForkAndWait(const string &) +int ForkAndWait(const std::string &) #else -int ForkAndWait(const string & confDir) +int ForkAndWait(const std::string & confDir) #endif { #ifndef NO_DAEMON -stgChildPid = fork(); -string startFile = confDir + START_FILE; -unlink(startFile.c_str()); +pid_t childPid = fork(); -switch (stgChildPid) +switch (childPid) { case -1: // Failure return -1; @@ -273,23 +199,6 @@ switch (stgChildPid) break; default: // Parent - for (int i = 0; i < 120 * 5; i++) - { - if (access(startFile.c_str(), F_OK) == 0) - { - //printf("Fork successfull. Exit.\n"); - unlink(startFile.c_str()); - exit(0); - } - - if (childExited) - { - unlink(startFile.c_str()); - exit(1); - } - usleep(200000); - } - unlink(startFile.c_str()); exit(1); break; } @@ -297,40 +206,19 @@ switch (stgChildPid) return 0; } //----------------------------------------------------------------------------- -void KillExecuters() -{ -set::iterator pid; -pid = executersPid.begin(); -while (pid != executersPid.end()) - { - printfd(__FILE__, "KillExecuters pid=%d\n", *pid); - kill(*pid, SIGUSR1); - ++pid; - } -} -//----------------------------------------------------------------------------- int main(int argc, char * argv[]) { - -/* - Initialization order: - - Logger - - Config - - Set signal nandlers - - Fork and exit - */ - CONFIGFILE * cfg = NULL; LISTENER * listener = NULL; int msgID = -11; int execNum = 0; int execMsgKey = 0; -string logFileName; -string confDir; -string password; -string onConnect; -string onDisconnect; +std::string logFileName; +std::string confDir; +std::string password; +std::string onConnect; +std::string onDisconnect; int port; int userTimeout; @@ -347,8 +235,8 @@ else if (cfg->Error()) { - STG_LOGGER & WriteServLog = GetStgLogger(); - WriteServLog.SetLogFileName("/var/log/rscriptd.log"); + auto & WriteServLog = STG::Logger::get(); + WriteServLog.setFileName("/var/log/rscriptd.log"); WriteServLog("Error reading config file!"); delete cfg; return EXIT_FAILURE; @@ -364,18 +252,17 @@ cfg->ReadInt("UserTimeout", &userTimeout, 60); cfg->ReadString("ScriptOnConnect", &onConnect, "/etc/rscriptd/OnConnect"); cfg->ReadString("ScriptOnDisconnect", &onDisconnect, "/etc/rscriptd/OnDisconnect"); -SetSignalHandlers(); if (ForkAndWait(confDir) < 0) { - STG_LOGGER & WriteServLog = GetStgLogger(); + auto & WriteServLog = STG::Logger::get(); WriteServLog("Fork error!"); delete cfg; return EXIT_FAILURE; } -STG_LOGGER & WriteServLog = GetStgLogger(); +auto & WriteServLog = STG::Logger::get(); PIDFile pidFile("/var/run/rscriptd.pid"); -WriteServLog.SetLogFileName(logFileName); +WriteServLog.setFileName(logFileName); WriteServLog("rscriptd v. %s", SERVER_VERSION); for (int i = 0; i < execNum; i++) @@ -383,8 +270,7 @@ for (int i = 0; i < execNum; i++) int ret = StartScriptExecuter(argv[0], execMsgKey, &msgID); if (ret < 0) { - STG_LOGGER & WriteServLog = GetStgLogger(); - WriteServLog("Start Script Executer error!"); + STG::Logger::get()("Start Script Executer error!"); delete cfg; return EXIT_FAILURE; } @@ -407,27 +293,39 @@ listener->Start(); WriteServLog("rscriptd started successfully."); WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); -#ifndef NO_DAEMON -string startFile(confDir + START_FILE); -creat(startFile.c_str(), S_IRUSR); -#endif +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); -while (nonstop.GetStatus()) +while (true) { - usleep(100000); + sigfillset(&signalSet); + int sig = 0; + printfd(__FILE__, "Before sigwait\n"); + sigwait(&signalSet, &sig); + printfd(__FILE__, "After sigwait. Signal: %d\n", sig); + bool stop = false; + switch (sig) + { + case SIGTERM: + stop = true; + break; + case SIGINT: + stop = true; + break; + default: + WriteServLog("Ignore signel %d", sig); + break; + } + if (stop) + break; } listener->Stop(); WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); -int res = msgctl(msgID, IPC_RMID, NULL); -if (res) - WriteServLog("Queue was not removed. id=%d", msgID); -else - WriteServLog("Queue removed successfully."); - -KillExecuters(); +StopScriptExecuter(msgID); WriteServLog("rscriptd stopped successfully."); WriteServLog("---------------------------------------------");