From: Christian P. <cp...@us...> - 2005-01-18 17:50:18
|
Update of /cvsroot/pclasses/pclasses2/src/App In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31280/src/App Added Files: BackgroundApp.cpp Log Message: Added BackgroundApp class. --- NEW FILE: BackgroundApp.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/App/BackgroundApp.h" #include <signal.h> #ifndef WIN32 # include <sys/types.h> # include <sys/stat.h> # include <fcntl.h> #endif namespace P { namespace App { BackgroundApp::BackgroundApp(const AppDetails& details) throw() : SimpleApp(details) { } BackgroundApp::~BackgroundApp() throw() { } #ifdef WIN32 bool startService() { HANDLE SC_HANDLE svcmgr = OpenSCManager(0,0,GENERIC_READ); if(svcmgr == NULL) { std::cerr << "ERROR: Could not open the service manager." << std::endl; return false; } SC_HANDLE svc = OpenService(svcmgr, "", SERVICE_ALL_ACCESS); if(svc == NULL) { CloseServiceHandle(svcmgr); std::cerr << "ERROR: Could not open service." << std::endl; return false; } if(!StartService(svc, 0, NULL)) { CloseServiceHandle(svcmgr); CloseServiceHandle(svc); std::cerr << "ERROR: Could not start service." << std::endl; return false; } std::cout << "Service starting ... " << std::flush(); DWORD startTickCount = 0, lastCheckPoint = 0; while(1) { if(!QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, &svcStatus, sizeof(SERVICE_STATUS_PROCESS), 0)) { CloseServiceHandle(svcmgr); CloseServiceHandle(svc); std::cerr << "ERROR: Could not query service state." << std::endl; return false; } if(svcStatus.dwCurrentState != SERVICE_START_PENDING) break; bool serviceOk = false; // update checkpoint values ... if(svcStatus.dwCheckPoint > lastCheckPoint) { startTickCount = GetTickCount(); lastCheckPoint = svcStatus.dwCheckPoint; std::cout << "." << std::flush(); ok = true; } // if checkpoint value did not change, // check if the service has timed out. if(!serviceOk) { // the service seems to hang ... if(GetTickCount() - startTickCount > svcStatus.dwWaitHint) break; } // wait some time ... Thread::sleep(1000); } std::cout << std::endl; switch(svcStatus.dwCurrentState) { case SERVICE_START_PENDING: std::cerr << "ERROR: Service takes longer to start than expected." << std::endl; break; case SERVICE_PAUSED: case SERVICE_PAUSE_PENDING: case SERVICE_CONTINUE_PENDING: case SERVICE_RUNNING: std::cout << "Service successfully started." << std::endl; break; case SERVICE_STOPPED: case SERVICE_STOP_PENDING: std::cerr << "Service is stopped." << std::endl; break; } CloseServiceHandle(svcmgr); CloseServiceHandle(svc); return true; } bool installService() { } DWORD WINAPI serviceCtrlHandler(DWORD control, DWORD eventType, LPVOID eventData, LPVOID context) { } void WINAPI serviceMain(DWORD argc, LPTSTR* argv) { SERVICE_STATUS_HANDLE statusHandle = RegisterServiceCtrlHandlerEx(serviceName, serviceCtrlHandler, 0); } #endif int BackgroundApp::init(int argc, char* argv[]) { int ret = SimpleApp::init(argc, argv); if(ret) return ret; #ifdef SIGHUP ::signal(SIGHUP, SimpleApp::signalHandler); #endif #ifdef WIN32 { // connect to the service controller ... // StartServiceCtrlDispatcher() // otherwise try to start the service ... if(!startService()) { std::cerr << "There was an error starting the service. Is the Service already installed?" << std::endl; std::cerr << "Try executing \"" << argv[0] << " --install-service\" on the command line." << std::endl; return 1; } } #else { // send the process to the background ... pid_t pid; if((pid = fork()) != 0) exit(0); setsid(); // redirect input and output to nirvana ... int nullfd = open("/dev/null", O_RDWR); dup2(nullfd, 0); dup2(nullfd, 1); dup2(nullfd, 2); } #endif return 0; } void BackgroundApp::cleanup() { } void BackgroundApp::finish() { } void BackgroundApp::signal(int sig) { SimpleApp::signal(sig); #ifdef SIGHUP if(sig == SIGHUP) reload(); #endif } void BackgroundApp::reload() { } } // !namespace App } // !namespace P |