From b28e4b16276bb578a85dc674af6c7df05a13381e Mon Sep 17 00:00:00 2001 From: Anton Osten Date: Sun, 2 Jun 2013 22:24:14 -0500 Subject: [PATCH 1/4] python 3 support --- .travis.yml | 4 ++++ yapdi.py | 33 ++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3515083 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: python +python: + - "2.7" + - "3.3" \ No newline at end of file diff --git a/yapdi.py b/yapdi.py index c9db7bb..4b3967c 100644 --- a/yapdi.py +++ b/yapdi.py @@ -4,6 +4,7 @@ # YapDi - Yet another python Daemon implementation # Author Kasun Herath # +# Python 3 compatibility by Anton Osten ''' from signal import SIGTERM @@ -16,6 +17,14 @@ INSTANCE_NOT_RUNNING = 3 SET_USER_FAILED = 4 +# python 2 and 3 compatibility +pyversion = sys.version_info[0] + +if pyversion is 2: + no_file_error = IOError +else: + no_file_error = FileNotFoundError + class Daemon: def __init__(self, pidfile=None, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin @@ -40,7 +49,7 @@ def daemonize(self): if pid > 0: # exit first parent sys.exit(0) - except OSError, e: + except OSError as e: return OPERATION_FAILED # decouple from parent environment @@ -53,15 +62,15 @@ def daemonize(self): if pid > 0: # exit from second parent sys.exit(0) - except OSError, e: + except OSError as e: return OPERATION_FAILED # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() - si = file(self.stdin, 'r') - so = file(self.stdout, 'a+') - se = file(self.stderr, 'a+', 0) + si = open(self.stdin) + so = open(self.stdout, 'a+') + se = open(self.stderr, 'a+') os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) @@ -69,16 +78,18 @@ def daemonize(self): # write pidfile atexit.register(self.delpid) pid = str(os.getpid()) - file(self.pidfile,'w+').write("%s\n" % pid) + + with open(self.pidfile, 'w+') as file: + file.write("%s\n" % pid) # If daemon user is set change current user to self.daemon_user if self.daemon_user: try: uid = pwd.getpwnam(self.daemon_user)[2] os.setuid(uid) - except NameError, e: + except NameError as e: return SET_USER_FAILED - except OSError, e: + except OSError as e: return SET_USER_FAILED return OPERATION_SUCCESSFUL @@ -97,7 +108,7 @@ def kill(self): while 1: os.kill(pid, SIGTERM) time.sleep(0.1) - except OSError, err: + except OSError as err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): @@ -117,10 +128,10 @@ def restart(self): def status(self): ''' check whether an instance is already running. If running return pid or else False ''' try: - pf = file(self.pidfile,'r') + pf = open(self.pidfile) pid = int(pf.read().strip()) pf.close() - except IOError: + except no_file_error: pid = None return pid From f54166b2e2621f9d9d620b79ee3edc5a19ad68ca Mon Sep 17 00:00:00 2001 From: Anton Osten Date: Sun, 2 Jun 2013 23:50:47 -0500 Subject: [PATCH 2/4] more python3 compat + check if the process is actually running --- yapdi.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/yapdi.py b/yapdi.py index 4b3967c..282b0db 100644 --- a/yapdi.py +++ b/yapdi.py @@ -22,8 +22,10 @@ if pyversion is 2: no_file_error = IOError + no_process_error = OSError else: no_file_error = FileNotFoundError + no_process_error = ProcessLookupError class Daemon: def __init__(self, pidfile=None, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): @@ -108,9 +110,9 @@ def kill(self): while 1: os.kill(pid, SIGTERM) time.sleep(0.1) - except OSError as err: + except no_process_error as err: err = str(err) - if err.find("No such process") > 0: + if "No such process" in err: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: @@ -130,7 +132,14 @@ def status(self): try: pf = open(self.pidfile) pid = int(pf.read().strip()) - pf.close() + + # check if it is actually running + try: + os.kill(pid, 0) + except no_process_error: + os.remove(self.pidfile) + pid = None + except no_file_error: pid = None return pid From 631135db4383f71a8e212d780ce701c255a44983 Mon Sep 17 00:00:00 2001 From: Anton Osten Date: Mon, 3 Jun 2013 00:08:44 -0500 Subject: [PATCH 3/4] shows a warning if an instance is already running --- yapdi.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/yapdi.py b/yapdi.py index 282b0db..7c0e064 100644 --- a/yapdi.py +++ b/yapdi.py @@ -10,6 +10,7 @@ from signal import SIGTERM import sys, atexit, os, pwd import time +from warnings import warn OPERATION_SUCCESSFUL = 0 OPERATION_FAILED = 1 @@ -45,6 +46,7 @@ def __init__(self, pidfile=None, stdin='/dev/null', stdout='/dev/null', stderr=' def daemonize(self): ''' Daemonize the current process and return ''' if self.status(): + warn('YapDi: instance is already running', RuntimeWarning) return INSTANCE_ALREADY_RUNNING try: pid = os.fork() @@ -105,7 +107,7 @@ def kill(self): if not pid: return INSTANCE_NOT_RUNNING - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) @@ -133,13 +135,13 @@ def status(self): pf = open(self.pidfile) pid = int(pf.read().strip()) - # check if it is actually running + # check if it is actually running or even exists try: os.kill(pid, 0) except no_process_error: os.remove(self.pidfile) pid = None - + except no_file_error: pid = None return pid From deb3d224036aae54353f2f29aadac8fb86799c76 Mon Sep 17 00:00:00 2001 From: Anton Osten Date: Mon, 3 Jun 2013 00:16:23 -0500 Subject: [PATCH 4/4] fixed travis file --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3515083..93cd63a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,7 @@ language: python python: - "2.7" - - "3.3" \ No newline at end of file + - "3.3" + +install: + - "python setup.py install" \ No newline at end of file