demon.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "demon.h"
00021 #include <unistd.h>
00022 #include <iostream>
00023 #include <fcntl.h>
00024 #include <sys/file.h>
00025 #include <errno.h>
00026 #include <stdio.h>
00027 #include <stdexcept>
00028 #include <string.h>
00029 #include <stdlib.h>
00030
00031 namespace container {
00032
00033 Demon::Demon()
00034 : m_cinName("/dev/zero")
00035 , m_coutName("./servlet.log")
00036 , m_cerrName(m_coutName)
00037 , m_detach(false)
00038 , m_pidF(-1)
00039 , m_pidFPath("/var/run/cppserv.pid")
00040 {
00041 }
00042
00043
00044 Demon::~Demon()
00045 {
00046 if(m_pidF != -1) {
00047 ::flock(m_pidF,LOCK_UN);
00048 ::close(m_pidF);
00049 ::unlink(m_pidFPath.c_str());
00050 }
00051 }
00052
00053
00054 }
00055
00056
00060 void container::Demon::start()
00061 {
00062 int pid;
00063 if(m_detach){
00064 pid=fork();
00065 if(pid==-1) {
00066 std::string err("Error forking while detaching:");
00067 err += strerror(errno);
00068 throw std::runtime_error(err);
00069 }
00070 if(pid!=0)
00071 exit(0);
00072
00073
00074
00075 std::cout.flush();
00076 std::cerr.flush();
00077 int cin=::open(m_cinName.c_str(),O_RDONLY|O_CREAT,S_IRUSR|S_IWUSR);
00078 if(cin == -1)std::cout<<"Unable to open CIN file ("<<m_cinName<<"): "<<strerror(errno)<<std::endl;
00079 int cout=::open(m_coutName.c_str(),O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);
00080 if(cout == -1)std::cout<<"Unable to open COUT file ("<<m_coutName<<"): "<<strerror(errno)<<std::endl;
00081 int cerr=::open(m_cerrName.c_str(),O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);
00082 if(cerr == -1)std::cout<<"Unable to open CIN file ("<<m_coutName<<"): "<<strerror(errno)<<std::endl;
00083 if(dup2(cin,0)==-1)std::cout<<"Couldn't reopen CIN! "<<errno<<':'<<strerror(errno)<<std::endl;
00084 if(dup2(cout,1)==-1)std::cout<<"Couldn't reopen COUT! "<<errno<<':'<<strerror(errno)<<std::endl;
00085 if(dup2(cerr,2)==-1)std::cout<<"Couldn't reopen CERR! "<<errno<<':'<<strerror(errno)<<std::endl;
00086 ::close(cin);
00087 ::close(cout);
00088 ::close(cerr);
00089
00090 ::setsid();
00091 }
00092 pid=getpid();
00093 m_pidF=::open(m_pidFPath.c_str(),O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
00094 if(m_pidF<0){
00095 std::cerr<<"Unable to open pid file: \""<<m_pidFPath<<"\": "<<strerror(errno)<<std::endl;
00096 return;
00097 }
00098 if(::flock(m_pidF,LOCK_EX|LOCK_NB)<0){
00099 std::cerr<<"Unable to lock pid file: \""<<m_pidFPath<<"\": "<<strerror(errno)<<std::endl;
00100 std::cerr<<"Is another cppserv already running?\n";
00101 return;
00102 }
00103 char buf[20];
00104 ::snprintf(buf,sizeof(buf)-1,"%d",pid);
00105 ::ftruncate(m_pidF,0);
00106 ::write(m_pidF,buf,strlen(buf));
00107 ::fsync(m_pidF);
00108 run();
00109 }