Created
February 25, 2015 19:59
-
-
Save itolosa/5f0a5bcb9356bbd7b3a8 to your computer and use it in GitHub Desktop.
Daemon Script based on Turkmenbashi (@spicymagpie)
This file contains hidden or 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
#!/usr/bin/env python | |
# encoding: utf-8 | |
import os | |
import sys | |
import signal | |
class MasterDaemon(object): | |
def __init__(self, infn, outfn, errfn): | |
self.infn = infn | |
self.outfn = outfn | |
self.errfn = errfn | |
self.pidfile = '/tmp/daemon.pid' | |
self.wdir = '/' | |
self.fmask = 0 | |
self.efail = 1 | |
self.eok = 0 | |
self.rstreams = True | |
def start(self): | |
try: | |
#check for a pid file | |
try: | |
pf = file(self.pidfile, 'r', 0) | |
pid = int(pf.read(100).strip()) | |
pf.close() | |
except (AttributeError, TypeError, IOError): | |
pid = None | |
if pid: | |
#pid already exists | |
sys.exit(self.efail) | |
#create a child process and | |
#exit master process inmediately | |
try: | |
pid = os.fork() | |
if pid > 0: | |
sys.exit(self.eok) | |
elif pid < 0: | |
raise OSError | |
except OSError, e: | |
sys.exit(self.efail) | |
#get the session leader flag | |
try: | |
sid = os.setsid() | |
#if sid < 0: | |
# raise Exception | |
except Exception: | |
sys.exit(self.efail) | |
#create a second, orphan, child | |
#and exit the parent | |
try: | |
pid = os.fork() | |
if pid > 0: | |
sys.exit(self.eok) | |
elif pid < 0: | |
raise OSError | |
except OSError, e: | |
sys.exit(self.efail) | |
#set working directory | |
#must be available while program is running | |
os.chdir(self.wdir) | |
#set file permissions mask (rwx) | |
#0 means all: (777) | |
os.umask(self.fmask) | |
if self.rstreams: | |
#create new fd's | |
errfd = os.open(self.errfn, os.O_WRONLY) | |
infd = os.open(self.infn, os.O_RDONLY) | |
outfd = os.open(self.outfn, os.O_WRONLY) | |
#close fdescriptors and file entry in unix file table | |
#then redirect standard file descriptors | |
os.dup2(errfd, sys.stderr.fileno()) | |
os.dup2(infd, sys.stderr.fileno()) | |
os.dup2(outfd, sys.stdout.fileno()) | |
else: | |
#close standard file descriptors and handlers | |
sys.stderr.close() | |
sys.stdout.close() | |
sys.stdin.close() | |
#at exit delete pid lock file | |
atexit.register(self.delpid) | |
#save actual pid as a lock file | |
pid = str(os.getpid()) | |
fp = file(self.pidfile, 'w+') | |
fp.write("%s\n" % pid) | |
fp.close() | |
#run the main task | |
self.run() | |
sys.exit(self.eok) | |
except Exception: | |
sys.exit(self.efail) | |
def delpid(self): | |
try: | |
os.remove(self.pidfile) | |
except OSError, e: | |
pass | |
def stop(self): | |
#get the pid from the pidfile | |
try: | |
pf = file(self.pidfile, 'r', 0) | |
pid = int(pf.read().strip()) | |
pf.close() | |
except IOError: | |
pid = None | |
if not pid: | |
message = "pidfile %s does not exist. Daemon not running?\n" | |
sys.stderr.write(message % self.pidfile) | |
return # not an error in a restart | |
#try killing the daemon process | |
try: | |
while True: | |
os.kill(pid, signal.SIGTERM) | |
time.sleep(0.1) | |
except OSError, err: | |
err = str(err) | |
if err.find("No such process") > 0: | |
self.delpid() | |
else: | |
print err | |
sys.exit(1) | |
def restart(self): | |
self.stop() | |
self.start() | |
def run(self): | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment