#include <daemon_unix.h>
Collaboration diagram for Omniifr::DaemonImpl:

Public Member Functions | |
| DaemonImpl () | |
| ~DaemonImpl () | |
| void | tracefile (const char *val) |
| Set _tracefile. | |
| void | pidfile (const char *val) |
| Set _pidfile. | |
| void | foreground (bool val) |
| Set _foreground. | |
| void | initialize (int &, char **&) |
| Does nothing on Unix. | |
| void | daemonize () |
| Puts the current process into the background. | |
| void | runningOk () |
| Called to signal that all startup operations have completed OK. | |
| void | shutdown (int status) |
| Exit handler called (indirectly) by ::on_exit() - shuts down the daemon. | |
Static Public Member Functions | |
| static void | log (const char *message) |
| Callback, used as a parameter to omniORB::setLogFunction(). | |
Public Attributes | |
| char * | _tracefile |
| The tracefile name (if any). | |
| bool | _foreground |
| TRUE for debug mode (run in foreground). | |
| char * | _pidfile |
| The pidfile name (if any). | |
| int | _pipe [2] |
| Unnamed pipe for child->parent comms. | |
| bool | _havePidfile |
| Is there a pidfile for us to clean up? | |
| bool | _haveParent |
| Is there a parent for us to clean up? | |
| bool | _haveSyslog |
| Should we close syslog before quitting? | |
Static Public Attributes | |
| static DaemonImpl | _inst |
Private Member Functions | |
| void | fork () |
| Performs the actual fork. | |
| void | redirectStreamsTo (const char *filename) |
| Redirect stdout & stderr to filename. | |
| int | openFileFor (int fd, const char *filename, int flags) |
| Opens a (new?) file called 'filename' for writing, and uses it to hijack stream 'fd'. | |
| void | checkPidfileOrShutdown () |
| If pidfile exists & contains a running process then shutdown() (Unix). | |
| void | writePidfile () |
| int | waitForChild () |
| Called by the parent process (Unix). | |
| void | notifyParent (int status) |
| Tells the parent to exit with the given status (Unix). | |
Features: pidfile support, forking, redirect omniORB trace to syslog (or tracefile).
Definition at line 37 of file daemon_unix.h.
|
|
Definition at line 119 of file daemon_unix.cc. 00119 {}
|
|
|
Definition at line 122 of file daemon_unix.cc. References _pidfile, and _tracefile. 00123 {
00124 delete[] _pidfile;
00125 delete[] _tracefile;
00126 _pidfile=NULL;
00127 _tracefile=NULL;
00128 }
|
|
|
If pidfile exists & contains a running process then shutdown() (Unix). Also shuts down if pidfile is inaccessible. Definition at line 283 of file daemon_unix.cc. References _pidfile, and STRERR_FILE_LINE. Referenced by daemonize(). 00284 {
00285 if(!_pidfile)
00286 return;
00287
00288 // Try to read pidfile.
00289 pid_t pidFromFile =0;
00290 struct stat buf;
00291 if(0==::stat(_pidfile,&buf))
00292 {
00293 if(!S_ISREG(buf.st_mode))
00294 {
00295 cerr<<"Pidfile '"<<_pidfile<<"' is not a regular file."<<endl;
00296 ::exit(-1);
00297 }
00298 try
00299 {
00300 ifstream infile(_pidfile);
00301 infile>>pidFromFile;
00302 infile.close();
00303 }
00304 catch(...)
00305 {
00306 cerr<<"Failed to read pidfile'"<<_pidfile<<"'."<<endl;
00307 ::exit(-1);
00308 }
00309 }
00310 else if(errno!=ENOENT)
00311 {
00312 cerr<<"Failed to stat pidfile '"<<_pidfile<<"': "
00313 <<STRERR_FILE_LINE<<endl;
00314 ::exit(-1);
00315 }
00316
00317 // If process 'pidFromFile' is running then exit, else remove pidfile.
00318 if(pidFromFile>0)
00319 {
00320 if(0==::kill(pidFromFile,0)) // tests for running 'pidFromFile'.
00321 {
00322 cerr<<"Quitting because process "<<pidFromFile
00323 <<" defined in pidfile '"<<_pidfile<<"'"
00324 <<" is already running."<<endl;
00325 ::exit(-1);
00326 }
00327 else if(errno!=ESRCH)
00328 {
00329 cerr<<"Failed to test for process "<<pidFromFile
00330 <<" defined in pidfile '"<<_pidfile<<"': "
00331 <<STRERR_FILE_LINE<<endl;
00332 ::exit(-1);
00333 }
00334 }
00335 }
|
|
|
Puts the current process into the background. Redirects the omniORB log output to syslog (or 'tracefile', if it is set). Definition at line 158 of file daemon_unix.cc. References _foreground, _haveSyslog, _tracefile, checkPidfileOrShutdown(), fork(), PACKAGE_NAME, redirectStreamsTo(), omniORB::setLogFunction(), Omniifr::shutdown0(), Omniifr::shutdown2(), STRERR_FILE_LINE, and writePidfile(). Referenced by Omniifr::Daemon::daemonize(). 00159 {
00160 // Register the shutdown function.
00161 #ifdef HAVE_ON_EXIT
00162 if( ::on_exit(shutdown2,NULL) <0)
00163 #else
00164 if( ::atexit(shutdown0) <0)
00165 #endif
00166 {
00167 cerr<<"Failed to set exit handler."<<endl;
00168 ::exit(-1);
00169 }
00170
00171 if(!_foreground)
00172 {
00173 this->fork();
00174 // ...now in the CHILD.
00175 }
00176
00177 // Check & write the pidfile (if _pidfile is set).
00178 checkPidfileOrShutdown();
00179 writePidfile();
00180
00181 // Change the file mode mask
00182 ::umask(0);
00183
00184 // Change the current working directory
00185 if(::chdir("/")!=0)
00186 {
00187 cerr<<STRERR_FILE_LINE<<endl;
00188 ::exit(-1);
00189 }
00190
00191 // If _tracefile is not set, then use syslog.
00192 if(_tracefile && _tracefile[0]!='\0')
00193 {
00194 redirectStreamsTo(_tracefile);
00195 }
00196 else
00197 {
00198 #ifndef HAVE_OMNIORB3
00199 # ifdef LOG_PERROR
00200 ::openlog(PACKAGE_NAME ": ",LOG_PID|LOG_PERROR,LOG_DAEMON);
00201 # else
00202 ::openlog(PACKAGE_NAME ": ",LOG_PID,LOG_DAEMON);
00203 # endif
00204 _haveSyslog=true;
00205 omniORB::setLogFunction(DaemonImpl::log);
00206 #else
00207 cerr<<"You must use option -t to set the file for trace messages."
00208 "\n(This is because omniORB3 cannot redirect messages to syslog.)"<<endl;
00209 ::exit(-1);
00210 #endif
00211 }
00212 } // end daemonize()
|
|
|
Set _foreground.
Definition at line 137 of file daemon_unix.cc. References _foreground. Referenced by Omniifr::Daemon::foreground(). 00138 {
00139 _foreground=val;
00140 }
|
|
|
Performs the actual fork.
Definition at line 363 of file daemon_unix.cc. References _haveParent, _pipe, PIPE_READ, PIPE_WRITE, STRERR_FILE_LINE, and waitForChild(). Referenced by daemonize(). 00364 {
00365 if( ::pipe(_pipe) <0)
00366 {
00367 cerr<<"Failed to open pipe: "<<STRERR_FILE_LINE<<endl;
00368 ::exit(-1);
00369 }
00370
00371 // Fork off from the parent process
00372 pid_t pid =::fork();
00373 if(pid<0)
00374 {
00375 cerr<<STRERR_FILE_LINE<<endl;
00376 ::exit(-1);
00377 }
00378 else if(pid>0)
00379 {
00380 //
00381 // Now in the PARENT
00382 //
00383
00384 // Close the write end of the pipe.
00385 if( ::close(_pipe[PIPE_WRITE]) <0)
00386 cerr<<"Failed to close pipe: "<<STRERR_FILE_LINE<<endl;
00387
00388 ::_exit(waitForChild()); // Exit without flushing buffers
00389 }
00390
00391 //
00392 // ...now in the CHILD.
00393 //
00394
00395 _haveParent=true;
00396
00397 // Close the read end of the pipe
00398 if( ::close(_pipe[PIPE_READ]) <0)
00399 cerr<<"Failed to close pipe: "<<STRERR_FILE_LINE<<endl;
00400
00401 // Create a new SID for the child process
00402 pid_t sid =::setsid();
00403 if(sid<0)
00404 {
00405 cerr<<STRERR_FILE_LINE<<endl;
00406 ::exit(-1);
00407 }
00408 }
|
|
||||||||||||
|
Does nothing on Unix.
Definition at line 152 of file daemon_unix.cc. 00153 {
00154 // Does nothing on Unix
00155 }
|
|
|
Callback, used as a parameter to omniORB::setLogFunction().
Definition at line 265 of file daemon_unix.cc. References _haveParent, and Omniifr::daemon. 00266 {
00267 // Cut off the redundant packageNamePrefix.
00268 static const char* packageNamePrefix ="omniIFR: ";
00269 static const size_t packageNamePrefixLen =::strlen(packageNamePrefix);
00270 if(0==::strncmp(message,packageNamePrefix,packageNamePrefixLen))
00271 message+=packageNamePrefixLen;
00272 // Send the message.
00273 ::syslog(LOG_INFO,message);
00274 #ifndef LOG_PERROR
00275 // If we don't have LOG_PERROR, then we'll have to manually send
00276 // log messages to stderr.
00277 if(daemon._haveParent)
00278 cerr<<message<<flush;
00279 #endif
00280 }
|
|
|
Tells the parent to exit with the given status (Unix).
Definition at line 462 of file daemon_unix.cc. References _pipe, PIPE_WRITE, and STRERR_FILE_LINE. Referenced by runningOk(), and shutdown(). 00463 {
00464 ssize_t r =::write(_pipe[PIPE_WRITE],&status,sizeof(status));
00465 if(r<sizeof(status))
00466 {
00467 if(r<0)
00468 cerr<<"read() failed while writing return value to pipe: "
00469 <<STRERR_FILE_LINE<<endl;
00470 else
00471 cerr<<"write() too short while writing return value from pipe: "
00472 <<STRERR_FILE_LINE<<endl;
00473 }
00474 if( ::close(_pipe[PIPE_WRITE]) !=0)
00475 cerr<<"Failed to close pipe: "<<STRERR_FILE_LINE<<endl;
00476 }
|
|
||||||||||||||||
|
Opens a (new?) file called 'filename' for writing, and uses it to hijack stream 'fd'.
Definition at line 431 of file daemon_unix.cc. Referenced by redirectStreamsTo(). 00432 {
00433 int newfd =::open(filename,flags,0644);
00434 if(newfd<0)
00435 return -1;
00436 if(newfd==fd)
00437 return fd;
00438 if(::dup2(newfd,fd)<0) // replace fd with a copy of newfd
00439 return -1;
00440 ::close(newfd);
00441 return fd;
00442 }
|
|
|
Set _pidfile.
Definition at line 143 of file daemon_unix.cc. Referenced by Omniifr::Daemon::pidfile(). 00144 {
00145 string pidfileStr =val;
00146 if(pidfileStr[0]!='/')
00147 pidfileStr=string("/var/run/")+pidfileStr;
00148 DaemonImpl::_pidfile=::strdup(pidfileStr.c_str());
00149 }
|
|
|
Redirect stdout & stderr to filename. Also redirects stdin from /dev/null Definition at line 411 of file daemon_unix.cc. References openFileFor(), and STRERR_FILE_LINE. Referenced by daemonize(), and runningOk(). 00412 {
00413 if(openFileFor(STDIN_FILENO,"/dev/null",O_RDONLY)<0)
00414 {
00415 cerr<<"Failed to open /dev/null for STDIN: "<<STRERR_FILE_LINE<<endl;
00416 ::exit(-1);
00417 }
00418 if(openFileFor(STDOUT_FILENO,filename,O_WRONLY|O_CREAT|O_APPEND)<0)
00419 {
00420 cerr<<"Failed to open "<<filename<<" for STDOUT: "<<STRERR_FILE_LINE<<endl;
00421 ::exit(-1);
00422 }
00423 if(openFileFor(STDERR_FILENO,filename,O_WRONLY|O_CREAT|O_APPEND)<0)
00424 {
00425 cerr<<"Failed to open "<<filename<<" for STDERR: "<<STRERR_FILE_LINE<<endl;
00426 ::exit(-1);
00427 }
00428 }
|
|
|
Called to signal that all startup operations have completed OK. Notifies the parent process and redirects stdout & stderr to 'tracefile' (or else /dev/null). Definition at line 215 of file daemon_unix.cc. References _haveParent, _haveSyslog, notifyParent(), PACKAGE_NAME, and redirectStreamsTo(). Referenced by Omniifr::Daemon::runningOk(). 00216 {
00217 if(_haveParent)
00218 {
00219 _haveParent=false;
00220 notifyParent(0);
00221 }
00222
00223 // No longer send syslog messages to stderr.
00224 if(_haveSyslog)
00225 {
00226 #ifdef LOG_PERROR
00227 ::closelog();
00228 // FIXME: Possible race here? If a log message is sent right now.
00229 ::openlog(PACKAGE_NAME ": ",LOG_PID,LOG_DAEMON);
00230 #endif
00231 redirectStreamsTo("/dev/null");
00232 }
00233 }
|
|
|
Exit handler called (indirectly) by ::on_exit() - shuts down the daemon. Deletes pidfile (if we have one), notifies the parent (if we have one). Definition at line 236 of file daemon_unix.cc. References _haveParent, _havePidfile, _haveSyslog, _pidfile, notifyParent(), and STRERR_FILE_LINE. Referenced by Omniifr::shutdown0(), Omniifr::shutdown2(), and Omniifr::Daemon::~Daemon(). 00237 {
00238 // Remove the pidfile.
00239 if(_havePidfile && _pidfile && 0!=::unlink(_pidfile))
00240 {
00241 cerr<<"Failed to remove pidfile '"<<_pidfile<<"': "
00242 <<STRERR_FILE_LINE<<endl;
00243 status=-1;
00244 }
00245 _havePidfile=false;
00246
00247 // Close syslog.
00248 if(_haveSyslog)
00249 {
00250 _haveSyslog=false;
00251 ::closelog();
00252 }
00253
00254 // Notify the parent.
00255 if(_haveParent)
00256 {
00257 _haveParent=false;
00258 notifyParent(status);
00259 }
00260
00261 // outtahere...
00262 }
|
|
|
Set _tracefile.
Definition at line 131 of file daemon_unix.cc. References _tracefile. Referenced by Omniifr::Daemon::tracefile(). 00132 {
00133 _tracefile=::strdup(val);
00134 }
|
|
|
Called by the parent process (Unix). Waits for the child to return an exit status. The status is usually '0' - indicating that the daemon has started successfully. Definition at line 445 of file daemon_unix.cc. References _pipe, PIPE_READ, and STRERR_FILE_LINE. Referenced by fork(). 00446 {
00447 int status =-1;
00448 ssize_t bytes =::read(_pipe[PIPE_READ],&status,sizeof(status));
00449 if(bytes<sizeof(status))
00450 {
00451 status=-1;
00452 if(bytes<0)
00453 cerr<<"Parent failed to read result from pipe: "<<STRERR_FILE_LINE<<endl;
00454 }
00455 if( ::close(_pipe[PIPE_READ]) !=0)
00456 cerr<<"Failed to close pipe: "<<STRERR_FILE_LINE<<endl;
00457
00458 return status;
00459 }
|
|
|
Definition at line 338 of file daemon_unix.cc. References _havePidfile, and _pidfile. Referenced by daemonize(). 00339 {
00340 if(_pidfile)
00341 {
00342 try
00343 {
00344 #ifdef FSTREAM_OPEN_PROT
00345 ofstream outfile(_pidfile,ios::out|ios::trunc,0644);
00346 #else
00347 ofstream outfile(_pidfile,ios::out|ios::trunc);
00348 #endif
00349 outfile<<::getpid()<<endl;
00350 outfile.close();
00351 // Tell shutdown() that the pidfile needs to be cleared away.
00352 _havePidfile=true;
00353 }
00354 catch(...)
00355 {
00356 cerr<<"Failed to write pidfile '"<<_pidfile<<"'."<<endl;
00357 ::exit(-1);
00358 }
00359 }
00360 }
|
|
|
TRUE for debug mode (run in foreground).
Definition at line 43 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), daemonize(), and foreground(). |
|
|
Is there a parent for us to clean up?
Definition at line 47 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), fork(), log(), runningOk(), and shutdown(). |
|
|
Is there a pidfile for us to clean up?
Definition at line 46 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), shutdown(), and writePidfile(). |
|
|
Should we close syslog before quitting?
Definition at line 48 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), daemonize(), runningOk(), and shutdown(). |
|
|
Definition at line 40 of file daemon_unix.h. |
|
|
The pidfile name (if any).
Definition at line 44 of file daemon_unix.h. Referenced by checkPidfileOrShutdown(), Omniifr::Daemon::Daemon(), shutdown(), writePidfile(), and ~DaemonImpl(). |
|
|
Unnamed pipe for child->parent comms.
Definition at line 45 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), fork(), notifyParent(), and waitForChild(). |
|
|
The tracefile name (if any).
Definition at line 42 of file daemon_unix.h. Referenced by Omniifr::Daemon::Daemon(), daemonize(), tracefile(), and ~DaemonImpl(). |
1.4.1