Skip to content

Instantly share code, notes, and snippets.

@itolosa
Created February 25, 2015 19:59
Show Gist options
  • Save itolosa/5f0a5bcb9356bbd7b3a8 to your computer and use it in GitHub Desktop.
Save itolosa/5f0a5bcb9356bbd7b3a8 to your computer and use it in GitHub Desktop.
Daemon Script based on Turkmenbashi (@spicymagpie)
#!/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