28 #define NEED_PACKAGE_INFO
37 # include <iostream.h>
41 #ifdef HAVE_STD_IOSTREAM
52 #ifdef HAVE_SYS_TYPES_H
53 # include <sys/types.h>
56 #ifdef HAVE_SYS_STAT_H
57 # include <sys/stat.h>
85 #define STRERR_FILE_LINE strerror(errno)<<" "<<__FILE__<<":"<<__LINE__
96 Daemon::Daemon(
int&,
char**&)
119 DaemonImpl::DaemonImpl(){}
122 DaemonImpl::~DaemonImpl()
131 void DaemonImpl::tracefile(
const char* val)
133 _tracefile=::strdup(val);
137 void DaemonImpl::foreground(
bool val)
143 void DaemonImpl::pidfile(
const char* val)
145 string pidfileStr =val;
146 if(pidfileStr[0]!=
'/')
147 pidfileStr=string(
"/var/run/")+pidfileStr;
148 DaemonImpl::_pidfile=::strdup(pidfileStr.c_str());
152 void DaemonImpl::initialize(
int&,
char**&)
158 void DaemonImpl::daemonize()
162 if( ::on_exit(shutdown2,NULL) <0)
164 if( ::atexit(shutdown0) <0)
167 cerr<<
"Failed to set exit handler."<<endl;
178 checkPidfileOrShutdown();
192 if(_tracefile && _tracefile[0]!=
'\0')
194 redirectStreamsTo(_tracefile);
198 #ifndef HAVE_OMNIORB3
200 ::openlog(
PACKAGE_NAME ": ",LOG_PID|LOG_PERROR,LOG_DAEMON);
207 cerr<<
"You must use option -t to set the file for trace messages."
208 "\n(This is because omniORB3 cannot redirect messages to syslog.)"<<endl;
215 void DaemonImpl::runningOk()
231 redirectStreamsTo(
"/dev/null");
236 void DaemonImpl::shutdown(
int status)
239 if(_havePidfile && _pidfile && 0!=::unlink(_pidfile))
241 cerr<<
"Failed to remove pidfile '"<<_pidfile<<
"': "
258 notifyParent(status);
265 void DaemonImpl::log(
const char* message)
267 int priority =LOG_INFO;
271 const char* mPos( message );
272 const char* pPos(
"omniEvents: " );
273 while(*mPos && (*mPos==*pPos || *pPos==
':'))
281 case '!': priority=LOG_ERR;
282 case ':': message=mPos;
288 ::syslog(priority,
"%s",message);
293 cerr<<message<<flush;
298 void DaemonImpl::checkPidfileOrShutdown()
304 pid_t pidFromFile =0;
306 if(0==::stat(_pidfile,&buf))
308 if(!S_ISREG(buf.st_mode))
310 cerr<<
"Pidfile '"<<_pidfile<<
"' is not a regular file."<<endl;
315 ifstream infile(_pidfile);
321 cerr<<
"Failed to read pidfile'"<<_pidfile<<
"'."<<endl;
325 else if(errno!=ENOENT)
327 cerr<<
"Failed to stat pidfile '"<<_pidfile<<
"': "
335 if(0==::kill(pidFromFile,0))
337 cerr<<
"Quitting because process "<<pidFromFile
338 <<
" defined in pidfile '"<<_pidfile<<
"'"
339 <<
" is already running."<<endl;
342 else if(errno!=ESRCH)
344 cerr<<
"Failed to test for process "<<pidFromFile
345 <<
" defined in pidfile '"<<_pidfile<<
"': "
353 void DaemonImpl::writePidfile()
359 #ifdef FSTREAM_OPEN_PROT
360 ofstream outfile(_pidfile,ios::out|ios::trunc,0644);
362 ofstream outfile(_pidfile,ios::out|ios::trunc);
364 outfile<<::getpid()<<endl;
371 cerr<<
"Failed to write pidfile '"<<_pidfile<<
"'."<<endl;
378 void DaemonImpl::fork()
380 if( ::pipe(_pipe) <0)
403 ::_exit(waitForChild());
417 pid_t sid =::setsid();
426 void DaemonImpl::redirectStreamsTo(
const char* filename)
433 if(openFileFor(
STDOUT_FILENO,filename,O_WRONLY|O_CREAT|O_APPEND)<0)
438 if(openFileFor(STDERR_FILENO,filename,O_WRONLY|O_CREAT|O_APPEND)<0)
446 int DaemonImpl::openFileFor(
int fd,
const char* filename,
int flags)
448 int newfd =::open(filename,flags,0644);
453 if(::dup2(newfd,fd)<0)
460 int DaemonImpl::waitForChild()
463 ssize_t bytes =::read(_pipe[
PIPE_READ],&status,
sizeof(status));
464 if(bytes<
sizeof(status))
477 void DaemonImpl::notifyParent(
int status)
479 ssize_t r =::write(_pipe[
PIPE_WRITE],&status,
sizeof(status));
483 cerr<<
"read() failed while writing return value to pipe: "
486 cerr<<
"write() too short while writing return value from pipe: "