#!/usr/bin/env python2 import os import sys import argparse import time import adsl def doublefork(pidfile, logfile): """Create a daemon process by double-forking, detaching standard streams and creating a pidfile.""" def panic(message): f = open(logfile, "aw") f.write("panic: %s\n" % message) f.close() try: pid = os.fork() except OSError as e: panic("%s [%d]" % (e.strerror, e.errno)) return False if pid == 0: # we are the first child #os.setsid() try: pid = os.fork() except OSError as e: panic("%s [%d]" % (e.strerror, e.errno)) return False if pid == 0: # we are the second child os.chdir("/") os.umask(0) else: os._exit(0) else: os._exit(0) pid = open(pidfile, "w") pid.write("%i" % os.getpid()) pid.close() class Unbuffered: def __init__(self, stream): self.stream = stream def write(self, data): timestamp = time.strftime("[%d/%m/%Y %H:%M:%S] ") self.stream.write(timestamp) self.stream.write(data) self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) # redirect stdout and stderr to file - for subprocesses and whatever f = os.open(logfile, os.O_APPEND | os.O_NDELAY | os.O_WRONLY) os.dup2(f, sys.stdout.fileno()) os.dup2(f, sys.stderr.fileno()) # python workaround - make stdout unbuffered sys.stdout = Unbuffered(sys.stdout) return True if __name__ == "__main__": parser = argparse.ArgumentParser(description="Make sure the ADSL network is up and display info on the FWA fron panel.") parser.add_argument("--daemonize", default="true", help="Whether we should daemonize the bouncer.") parser.add_argument("--pidfile", default="/var/run/adsl-bouncer.pid", help="When daemonized, the path of file to write dameon PID to.") parser.add_argument("--logfile", default="/var/log/adsl-bouncer.log", help="When daemonized, the path of log file.") args = parser.parse_args() daemonize = True if args.daemonize.lower() in ["true", "t", "yes", "y"] else False if daemonize: # see if daemon is already running if os.path.exists(args.pidfile): with open(args.pidfile, "r") as f: try: pid = int(f.read()) except: pass else: try: os.kill(pid, 0) except OSError: pass else: # daemon is running raise Exception("Daemon is already running on PID %i!" % pid) # try to open logfile try: f = open(args.logfile, "aw") f.write("Daemon starting...\n") f.close() except IOError as e: raise Exception("Could not open logfile %s! %s" % (args.logfile, str(e))) if not doublefork(args.pidfile, args.logfile): raise Exception("Could not doublefork! See logfile for details.") sys.stderr.write("Daemon running! PID %i.\n" % os.getpid()) adsl.loop()