📄 svcproc.cxx
字号:
/*
* svcproc.cxx
*
* Service process (daemon) implementation.
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Log: svcproc.cxx,v $
* Revision 1.6 2007/05/01 04:26:43 rcolobong
* 1. Add new command line parameter for adding extension on Product Name
*
* Revision 1.5 2007/03/11 03:58:47 joegenbaclor
* Disabled PMEMORY_CHECK for release builds
*
* Revision 1.4 2006/12/22 07:39:06 joegenbaclor
* More on command line argument parsing.
*
* Revision 1.3 2006/12/21 18:10:20 joegenbaclor
* Allowed setting of HTTP service port via command line. More changes to follow ...
*
* Revision 1.2 2006/12/21 13:50:16 joegenbaclor
* Added misc console params for unix daemons
*
* Revision 1.1 2006/06/29 04:18:41 joegenbaclor
* *** empty log message ***
*
* Revision 1.89 2005/12/15 21:14:34 dsandras
* Fixed from Alexander Larsson <alexl _AT__ redhat.com> for gcc 4.1 compilation. Thanks!
*
* Revision 1.88 2005/11/30 12:47:42 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.87 2005/11/25 00:22:02 csoutheren
* Applied patch #1266244 from Nick Shmyrev
* Cleanup PSystemLog from PTrace in PService exit
*
* Revision 1.86 2004/06/01 07:42:19 csoutheren
* Restored memory allocation checking
* Added configure flag to enable, thanks to Derek Smithies
*
* Revision 1.85 2004/04/03 08:57:41 csoutheren
* Replaced pseudo-RTTI with real RTTI
*
* Revision 1.84 2004/02/22 03:31:50 ykiryanov
* Added current thread id routine to BeOS code
*
* Revision 1.83 2003/09/17 09:02:14 csoutheren
* Removed memory leak detection code
*
* Revision 1.82 2003/01/14 04:43:21 robertj
* Improved output on error in getting service status.
*
* Revision 1.81 2002/12/12 00:54:29 robertj
* Fixed issue with setting max file handles causing a log file to be created
* as root (real uid) rather than as the user determined by the -u arg.
* Utilised new PProcess functions for setting user and group.
*
* Revision 1.80 2002/12/02 08:27:43 robertj
* Fixed incorrectly set #if statement from RTEMS patch.
*
* Revision 1.79 2002/12/02 03:57:18 robertj
* More RTEMS support patches, thank you Vladimir Nesic.
*
* Revision 1.78 2002/11/02 00:32:21 robertj
* Further fixes to VxWorks (Tornado) port, thanks Andreas Sikkema.
*
* Revision 1.77 2002/10/30 03:14:15 robertj
* Added tab character between time and thread in system log (for db import).
*
* Revision 1.76 2002/10/23 04:26:27 robertj
* Fixed extra debug levels in system log dump.
*
* Revision 1.75 2002/10/17 13:44:27 robertj
* Port to RTEMS, thanks Vladimir Nesic.
*
* Revision 1.74 2002/10/17 12:57:24 robertj
* Added ability to increase maximum file handles on a process.
*
* Revision 1.73 2002/10/10 04:43:44 robertj
* VxWorks port, thanks Martijn Roest
*
* Revision 1.72 2002/10/03 01:27:51 robertj
* Added fail safe _exit() as it appears raise(SIGQUIT) does not always dump
* core and exit the app causing endless SEGV's to appear the log file!
*
* Revision 1.71 2002/10/01 06:03:44 robertj
* Attempt to prevent recursive signals for SEGV etc
*
* Revision 1.70 2002/09/06 13:29:06 robertj
* Added missing help line for status command.
*
* Revision 1.69 2002/07/15 06:39:23 craigs
* Added function to allow raising of per-process file handle limit
*
* Revision 1.68 2002/06/13 08:50:11 rogerh
* GCC 3.1 uses slightly different #includes
*
* Revision 1.67 2002/06/05 12:29:16 craigs
* Changes for gcc 3.1
*
* Revision 1.66 2002/04/17 03:31:48 robertj
* Renamed system log file member variable to be common with Windows version.
*
* Revision 1.65 2002/03/18 08:03:30 robertj
* Fixed hex output of thread pid.
* Added ability to have -tk option wich attempt to terminate a daemon and
* if no response in 10 seconds kills it.
* Fixed leaving .pid file behind when using -k option.
*
* Revision 1.64 2002/02/19 07:12:36 rogerh
* Mac Carbon fix
*
* Revision 1.63 2001/12/16 23:40:16 robertj
* Fixed system log so does not crash if current thread not created by PWLib.
*
* Revision 1.62 2001/12/09 23:45:20 craigs
* Set debugMode flag when in .... debug mode!
*
* Revision 1.61 2001/09/20 05:35:47 robertj
* Fixed crash (race condition) if shutdown service via signal and exit main.
*
* Revision 1.60 2001/08/11 15:38:43 rogerh
* Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
*
* Revision 1.59 2001/08/07 03:05:54 robertj
* Expanded thread name field width in system log.
*
* Revision 1.58 2001/07/09 04:26:08 yurik
* Fixed lack of pthread_self function on BeOS
*
* Revision 1.57 2001/07/04 08:54:23 robertj
* Added dump of thread in SEGV signal handler, this one seems to work.
*
* Revision 1.56 2001/07/03 04:41:25 yurik
* Corrections to Jac's submission from 6/28
*
* Revision 1.55 2001/06/30 06:59:07 yurik
* Jac Goudsmit from Be submit these changes 6/28. Implemented by Yuri Kiryanov
*
* Revision 1.54 2001/05/03 01:13:10 robertj
* Closed stdin if in background, should never block in tty I/O if daemon!
*
* Revision 1.53 2001/04/20 05:41:35 craigs
* Added ability to set core dump size from command line under Linux
*
* Revision 1.52 2001/04/20 05:08:42 robertj
* Removed dump of thread in SEGV signal, it does not work.
*
* Revision 1.51 2001/04/17 03:13:21 robertj
* Added dump of thread address in SEGV etc log output.
*
* Revision 1.50 2001/04/05 03:09:29 robertj
* Changed so output to PError goes to system log. Useful for asserts.
*
* Revision 1.49 2001/03/29 03:25:03 robertj
* Added dumping to log file of SEGV etc if running as daemon.
*
* Revision 1.48 2001/03/28 23:47:26 robertj
* Added start log message and version numbers to start and stop log messages
*
* Revision 1.47 2001/03/28 05:36:14 robertj
* Added milliseconds to system log time output.
*
* Revision 1.46 2001/03/24 00:49:02 robertj
* Added status indication command for services
*
* Revision 1.45 2001/03/23 01:05:32 robertj
* Added check that log file is writable after setuid but before fork.
*
* Revision 1.44 2001/03/22 22:48:25 robertj
* Fixed errors in usage help text.
*
* Revision 1.43 2001/03/20 06:44:25 robertj
* Lots of changes to fix the problems with terminating threads that are I/O
* blocked, especially when doing orderly shutdown of service via SIGTERM.
*
* Revision 1.42 2001/03/20 01:04:46 robertj
* Fixed some difficulties with terminating a service process from signals or
* from simply dropping out of Main().
*
* Revision 1.41 2001/03/19 02:41:13 robertj
* Extra trace output on exiting service.
*
* Revision 1.40 2001/03/19 00:20:55 robertj
* Added test for if deamon actually stops
*
* Revision 1.39 2001/03/19 00:11:03 robertj
* Added information message when killing service.
*
* Revision 1.38 2001/03/14 01:30:35 robertj
* Do setgid before so setuid, ie when still root.
*
* Revision 1.37 2001/03/14 01:16:11 robertj
* Fixed signals processing, now uses housekeeping thread to handle signals
* synchronously. This also fixes issues with stopping PServiceProcess.
*
* Revision 1.36 2001/03/13 03:47:18 robertj
* Added ability to set pid file from command line.
*
* Revision 1.35 2001/03/09 06:31:22 robertj
* Added ability to set default PConfig file or path to find it.
*
* Revision 1.34 2000/05/02 03:17:13 robertj
* Added display of thread name in SystemLog, thanks Ashley Unitt.
*
* Revision 1.33 2000/04/03 18:36:50 robertj
* Fix for BeOS support (stupid prototype in system header files).
*
* Revision 1.32 1999/09/14 13:02:53 robertj
* Fixed PTRACE to PSYSTEMLOG conversion problem under Unix.
*
* Revision 1.31 1999/08/17 09:29:22 robertj
* Added long name versions of parameters.
*
* Revision 1.30 1999/08/12 12:12:47 robertj
* GCC 2.95 compatibility.
*
* Revision 1.29 1999/06/23 14:19:46 robertj
* Fixed core dump problem with SIGINT/SIGTERM terminating process.
*
* Revision 1.28 1999/05/13 04:44:18 robertj
* Added SIGHUP and SIGWINCH handlers to increase and decrease the log levels.
*
* Revision 1.27 1999/03/02 05:41:59 robertj
* More BeOS changes
*
* Revision 1.26 1999/01/11 12:10:32 robertj
* Improved operating system version display.
*
* Revision 1.26 1999/01/11 05:20:12 robertj
* Added OS to the -v display text.
*
* Revision 1.25 1998/12/21 06:37:14 robertj
* Fixed GNu warning on solaris x86
*
* Revision 1.24 1998/12/16 12:41:25 robertj
* Fixed bug where .ini file is not written when service run as a daemon.
*
* Revision 1.23 1998/11/30 21:52:00 robertj
* New directory structure.
*
* Revision 1.22 1998/11/06 03:44:55 robertj
* Fixed bug in argument list parsing, not doing it to member variable.
* Added check for daemon already running before starting a new daemon.
*
* Revision 1.21 1998/10/11 02:26:46 craigs
* Added thread ID to output messages
*
* Revision 1.20 1998/09/24 04:12:20 robertj
* Added open software license.
*
*/
#include <ptlib.h>
#pragma implementation "svcproc.h"
#include <ptlib/svcproc.h>
#ifdef P_VXWORKS
#include <logLib.h>
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARNING 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
#else
#include <syslog.h>
#include <pwd.h>
#include <grp.h>
#endif
#include <stdarg.h>
#if (__GNUC__ >= 3)
#include <fstream>
#else
#include <fstream.h>
#endif
#include <signal.h>
#include "uerror.h"
#ifdef P_LINUX
#include <sys/resource.h>
#endif
#define new PNEW
extern void PXSignalHandler(int);
#define MAX_LOG_LINE_LEN 1024
#ifndef P_VXWORKS
static int PwlibLogToUnixLog[PSystemLog::NumLogLevels] = {
LOG_CRIT, // LogFatal,
LOG_ERR, // LogError,
LOG_WARNING, // LogWarning,
LOG_INFO, // LogInfo,
LOG_DEBUG, // LogDebug
LOG_DEBUG,
LOG_DEBUG,
LOG_DEBUG,
LOG_DEBUG,
LOG_DEBUG
};
#endif // !P_VXWORKS
static const char * const PLevelName[PSystemLog::NumLogLevels+1] = {
"Message",
"Fatal error",
"Error",
"Warning",
"Info",
"Debug",
"Debug2",
"Debug3",
"Debug4",
"Debug5",
"Debug6",
};
#ifdef P_MAC_MPTHREADS
// alas, this can't be statically initialized
// XXX This ought to be an MPCriticalRegionID, but they're broken in
// XXX Mac OS X 10.0.x!
static MPSemaphoreID logMutex;
// yuck.
static void SetUpLogMutex()
{
if (logMutex == 0) {
MPSemaphoreID tempCrit;
long err = MPCreateSemaphore(1, 1, &tempCrit);
PAssertOS(err == 0);
if (!OTCompareAndSwap32(0, (UInt32)tempCrit, (UInt32*)&logMutex)) {
// lost the race
MPDeleteSemaphore(tempCrit);
}
}
}
#endif
#ifdef P_PTHREADS
static pthread_mutex_t logMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
void PSystemLog::Output(Level level, const char * cmsg)
{
PString systemLogFileName = PServiceProcess::Current().systemLogFileName;
if (systemLogFileName.IsEmpty()) {
#ifdef P_VXWORKS
printf("%s\n",cmsg);
logMsg((char *)(const char)cmsg,0,0,0,0,0,0);
#else
syslog(PwlibLogToUnixLog[level], "%s", cmsg);
#endif
}
else {
#ifdef P_PTHREADS
pthread_mutex_lock(&logMutex);
#endif
#ifdef P_MAC_MPTHREADS
SetUpLogMutex();
(void)MPWaitOnSemaphore(logMutex, kDurationForever);
#endif
ostream * out;
if (systemLogFileName == "-")
out = &cerr;
else
out = new ofstream(systemLogFileName, ios::app);
PTime now;
*out << now.AsString("yyyy/MM/dd hh:mm:ss.uuu\t");
PThread * thread = PThread::Current();
if (thread == NULL) {
#ifdef P_MAC_MPTHREADS
unsigned tid = (unsigned)MPCurrentTaskID();
#elif defined(P_VXWORKS)
unsigned tid = ::taskIdSelf();
#elif defined(BE_THREADS)
thread_id tid = ::find_thread(NULL);
#else
unsigned tid = (unsigned) pthread_self();
#endif
*out << "ThreadID=0x"
<< setfill('0') << ::hex
<< setw(8) << tid
<< setfill(' ') << ::dec;
} else {
PString threadName = thread->GetThreadName();
if (threadName.GetLength() <= 23)
*out << setw(23) << threadName;
else
*out << threadName.Left(10) << "..." << threadName.Right(10);
}
*out << '\t'
<< PLevelName[level+1]
<< '\t'
<< cmsg << endl;
if (out != &cerr)
delete out;
#ifdef P_PTHREADS
pthread_mutex_unlock(&logMutex);
#endif
#ifdef P_MAC_MPTHREADS
MPSignalSemaphore(logMutex);
#endif
}
}
int PSystemLog::Buffer::overflow(int c)
{
if (pptr() >= epptr()) {
int ppos = pptr() - pbase();
char * newptr = string.GetPointer(string.GetSize() + 10);
setp(newptr, newptr + string.GetSize() - 1);
pbump(ppos);
}
if (c != EOF) {
*pptr() = (char)c;
pbump(1);
}
return 0;
}
int PSystemLog::Buffer::underflow()
{
return EOF;
}
int PSystemLog::Buffer::sync()
{
PSystemLog::Output(log->logLevel, string);
string = PString();
char * base = string.GetPointer(10);
setp(base, base + string.GetSize() - 1);
return 0;
}
PServiceProcess::PServiceProcess(const char * manuf,
const char * name,
WORD majorVersion,
WORD minorVersion,
CodeStatus status,
WORD buildNumber)
: PProcess(manuf, name, majorVersion, minorVersion, status, buildNumber)
{
currentLogLevel = PSystemLog::Warning;
isTerminating = FALSE;
}
PServiceProcess::~PServiceProcess()
{
PSetErrorStream(NULL);
PTrace::SetStream(NULL);
PTrace::ClearOptions(PTrace::SystemLogStream);
if (!pidFileToRemove)
PFile::Remove(pidFileToRemove);
#ifndef P_VXWORKS
// close the system log
if (systemLogFileName.IsEmpty())
closelog();
#endif // !P_VXWORKS
}
PServiceProcess & PServiceProcess::Current()
{
PProcess & process = PProcess::Current();
PAssert(PIsDescendant(&process, PServiceProcess), "Not a service process!");
return (PServiceProcess &)process;
}
#ifndef P_VXWORKS
static int KillProcess(int pid, int sig)
{
if (kill(pid, sig) != 0)
return -1;
cout << "Sent SIG";
if (sig == SIGTERM)
cout << "TERM";
else
cout << "KILL";
cout << " to daemon at pid " << pid << ' ' << flush;
for (PINDEX retry = 1; retry <= 10; retry++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -