Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP creation of generic daemonizer with virtuals for sig handlers.
- Loading branch information
0 parents
commit a984990
Showing
8 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#include "daemon.h" | ||
|
||
#include <cerrno> | ||
#include <csignal> | ||
#include <cstdio> | ||
#include <cstdlib> | ||
#include <cstring> | ||
#include <iostream> | ||
#include <string> | ||
|
||
#include <fcntl.h> | ||
#include <syslog.h> | ||
#include <sys/resource.h> | ||
#include <sys/stat.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
using namespace std; | ||
|
||
daemond::daemond(){ | ||
//ctor | ||
} | ||
|
||
daemond::daemond(string cmd, string pidfile, sighandler sigh){ | ||
startDaemon(cmd, pidfile, sigh); | ||
} | ||
|
||
daemond::~daemond(){ | ||
//dtor | ||
} | ||
|
||
void daemond::daemonize(string cmd){ | ||
unsigned int i; | ||
int fd0, fd1, fd2; | ||
pid_t pid; | ||
struct rlimit rl; | ||
struct sigaction sa; | ||
|
||
umask(0); | ||
|
||
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) | ||
exit(1); | ||
|
||
if ((pid = fork()) < 0) | ||
exit(1); | ||
else if (pid != 0) | ||
exit(0); | ||
setsid(); | ||
|
||
sa.sa_handler = SIG_IGN; | ||
sigemptyset(&sa.sa_mask); | ||
sa.sa_flags = 0; | ||
if (sigaction(SIGHUP, &sa, NULL) < 0) | ||
exit(1); | ||
if ((pid = fork()) < 0) | ||
exit(1); | ||
else if (pid != 0) | ||
exit(0); | ||
|
||
|
||
if (chdir("/") < 0) | ||
exit(1); | ||
|
||
if (rl.rlim_max == RLIM_INFINITY) | ||
rl.rlim_max = 1024; | ||
for (i = 0; i < rl.rlim_max; i++) | ||
close(i); | ||
|
||
fd0 = open("/dev/null", O_RDWR); | ||
fd1 = dup(0); | ||
fd2 = dup(0); | ||
|
||
openlog(cmd.c_str(), LOG_CONS, LOG_DAEMON); | ||
if (fd0 != 0 || fd1 != 1 || fd2 != 2) { | ||
syslog(LOG_ERR, "unexpected file descriptors %d %d %d", | ||
fd0, fd1, fd2); | ||
exit(1); | ||
} | ||
} | ||
|
||
int daemond::running(string pidfile){ | ||
int fd; | ||
char buf[16]; | ||
|
||
fd = open(pidfile.c_str(), O_RDWR|O_CREAT, LOCKMODE); | ||
if (fd < 0) { | ||
syslog(LOG_ERR, "can't open %s: %s", pidfile.c_str(), strerror(errno)); | ||
exit(1); | ||
} | ||
if (lockfile(fd) < 0) { | ||
if (errno == EACCES || errno == EAGAIN) { | ||
close(fd); | ||
return(1); | ||
} | ||
syslog(LOG_ERR, "can't lock %s: %s", pidfile.c_str(), strerror(errno)); | ||
exit(1); | ||
} | ||
ftruncate(fd, 0); | ||
sprintf(buf, "%ld", (long)getpid()); | ||
write(fd, buf, strlen(buf)+1); | ||
return(0); | ||
} | ||
|
||
void daemond::startDaemon(string cmd, string pidfile, sighandler sigh){ | ||
struct sigaction sa; | ||
|
||
daemonize(cmd); | ||
|
||
if (running(pidfile)) { | ||
syslog(LOG_ERR, "daemon already running"); | ||
exit(1); | ||
} | ||
|
||
pid_t pid = getpid(); | ||
syslog(LOG_WARNING, "pid: %d", pid); | ||
|
||
sa.sa_handler = sigh.sigterm; | ||
sigemptyset(&sa.sa_mask); | ||
sigaddset(&sa.sa_mask, SIGHUP); | ||
sa.sa_flags = 0; | ||
if (sigaction(SIGTERM, &sa, NULL) < 0) { | ||
syslog(LOG_ERR, "can't catch SIGTERM: %s", strerror(errno)); | ||
exit(1); | ||
} | ||
|
||
sa.sa_handler = sigh.sigint; | ||
sigemptyset(&sa.sa_mask); | ||
sigaddset(&sa.sa_mask, SIGHUP); | ||
sa.sa_flags = 0; | ||
if (sigaction(SIGINT, &sa, NULL) < 0) { | ||
syslog(LOG_ERR, "can't catch SIGTERM: %s", strerror(errno)); | ||
exit(1); | ||
} | ||
|
||
sa.sa_handler = sigh.sighup; | ||
sigemptyset(&sa.sa_mask); | ||
sigaddset(&sa.sa_mask, SIGTERM); | ||
sa.sa_flags = 0; | ||
if (sigaction(SIGHUP, &sa, NULL) < 0) { | ||
syslog(LOG_ERR, "can't catch SIGHUP: %s", strerror(errno)); | ||
exit(1); | ||
} | ||
} | ||
|
||
int daemond::lockfile(int fd){ | ||
struct flock fl; | ||
fl.l_type = F_WRLCK; | ||
fl.l_start = 0; | ||
fl.l_whence = SEEK_SET; | ||
fl.l_len = 0; | ||
return(fcntl(fd, F_SETLK, &fl)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#ifndef DAEMON_H | ||
#define DAEMON_H | ||
|
||
#include <string> | ||
|
||
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) | ||
|
||
using namespace std; | ||
|
||
|
||
struct sighandler{ | ||
void (*sigterm)(int); | ||
void (*sigint)(int); | ||
void (*sighup)(int); | ||
}; | ||
|
||
class daemond | ||
{ | ||
public: | ||
daemond(); | ||
daemond(string cmd, string pidfile, sighandler sigh); | ||
virtual ~daemond(); | ||
void startDaemon(string cmd, string pidfile, sighandler sigh); | ||
protected: | ||
private: | ||
int lockfile(int fd); | ||
void daemonize(string cmd); | ||
int running(string pidfile); | ||
}; | ||
|
||
|
||
template <class T> | ||
class iProc { | ||
public: | ||
sighandler sigh; | ||
iProc(){ | ||
iProcMemFn s_term = &T::sigterm; | ||
iProcMemFn s_int = &T::sigint; | ||
iProcMemFn s_hup = &T::sighup; | ||
sigh.sigterm = (iProcFn)s_term; | ||
sigh.sigint = (iProcFn)s_int; | ||
sigh.sighup = (iProcFn)s_hup; | ||
} | ||
void start(string cmd, string pidfile){ | ||
daemond *dd; | ||
dd = new daemond(cmd,pidfile,sigh); | ||
} | ||
typedef void (T::*iProcMemFn)(int); | ||
typedef void (*iProcFn)(int); | ||
virtual void sigterm(){}; | ||
virtual void sigint(){}; | ||
virtual void sighup(){}; | ||
}; | ||
|
||
#endif // DAEMON_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | ||
<CodeBlocks_project_file> | ||
<FileVersion major="1" minor="6" /> | ||
<Project> | ||
<Option title="hpccd" /> | ||
<Option pch_mode="2" /> | ||
<Option compiler="gcc" /> | ||
<Build> | ||
<Target title="Debug"> | ||
<Option output="bin/Debug/hpccd" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="obj/Debug/" /> | ||
<Option type="1" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-g" /> | ||
</Compiler> | ||
</Target> | ||
<Target title="Release"> | ||
<Option output="bin/Release/hpccd" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="obj/Release/" /> | ||
<Option type="1" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-O2" /> | ||
</Compiler> | ||
<Linker> | ||
<Add option="-s" /> | ||
</Linker> | ||
</Target> | ||
</Build> | ||
<Compiler> | ||
<Add option="-Wall" /> | ||
<Add option="-fexceptions" /> | ||
</Compiler> | ||
<Unit filename="daemon.cpp" /> | ||
<Unit filename="daemon.h" /> | ||
<Unit filename="main.cpp" /> | ||
<Extensions> | ||
<code_completion /> | ||
<debugger /> | ||
</Extensions> | ||
</Project> | ||
</CodeBlocks_project_file> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# depslib dependency file v1.0 | ||
1312405579 source:/home/phschwartz/src/hpccd/daemon.cpp | ||
"daemon.h" | ||
<cerrno> | ||
<csignal> | ||
<cstdio> | ||
<cstdlib> | ||
<cstring> | ||
<iostream> | ||
<string> | ||
<fcntl.h> | ||
<syslog.h> | ||
<sys/resource.h> | ||
<sys/stat.h> | ||
<sys/types.h> | ||
<unistd.h> | ||
|
||
1312460985 /home/phschwartz/src/hpccd/daemon.h | ||
<string> | ||
|
||
1312461002 source:/home/phschwartz/src/hpccd/main.cpp | ||
<cstring> | ||
<cstdlib> | ||
<fcntl.h> | ||
<iostream> | ||
<string> | ||
<syslog.h> | ||
<unistd.h> | ||
"daemon.h" | ||
|
||
1311962916 source:/home/phschwartz/src/hpccd/process.cpp | ||
|
||
1311962896 source:/home/phschwartz/src/hpccd/service.cpp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | ||
<CodeBlocks_layout_file> | ||
<ActiveTarget name="Debug" /> | ||
<File name="daemon.h" open="0" top="0" tabpos="0"> | ||
<Cursor position="887" topLine="14" /> | ||
</File> | ||
<File name="main.cpp" open="0" top="0" tabpos="0"> | ||
<Cursor position="523" topLine="8" /> | ||
</File> | ||
</CodeBlocks_layout_file> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include <cstring> | ||
#include <cstdlib> | ||
#include <fcntl.h> | ||
#include <iostream> | ||
#include <string> | ||
#include <syslog.h> | ||
#include <unistd.h> | ||
|
||
#include "daemon.h" | ||
|
||
using namespace std; | ||
|
||
class proc_d : public iProc<proc_d>{ | ||
public: | ||
proc_d():iProc(){} | ||
|
||
void sigterm(int signo){ | ||
syslog(LOG_INFO, "got SIGTERM; exiting"); | ||
exit(0); | ||
} | ||
|
||
void sigint(int signo){ | ||
syslog(LOG_INFO, "got SIGINT; exiting"); | ||
exit(0); | ||
} | ||
|
||
void sighup(int signo){ | ||
syslog(LOG_INFO, "Re-reading configuration file"); | ||
} | ||
}; | ||
|
||
int main(int argc, char **argv){ | ||
string cmd; | ||
string pidfile = "/var/run/daemon/daemon.pid"; | ||
string args(argv[0]); | ||
size_t found = args.rfind('/'); | ||
if ( found != string::npos ){ | ||
cmd = args.substr(found+1); | ||
}else{ | ||
cmd = string(argv[0]); | ||
} | ||
|
||
proc_d pd; | ||
pd.start(cmd,pidfile); | ||
while(1){ | ||
sleep(30); | ||
} | ||
exit(0); | ||
} |
Empty file.
Empty file.