From ad1f0af5bbd1df62eb3d8cebf5e9a19e402647dd Mon Sep 17 00:00:00 2001 From: Pierre Date: Wed, 25 Sep 2013 22:30:39 +0200 Subject: [PATCH 1/2] Correct import error of pidfile in daemon, python can't find file. And maybe make a confusing with https://github.com/bmhatfield/python-pidfile. --- daemonic/daemon.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/daemonic/daemon.py b/daemonic/daemon.py index b6af181..9e482a4 100644 --- a/daemonic/daemon.py +++ b/daemonic/daemon.py @@ -10,7 +10,7 @@ import signal import time -import pidfile +import daemonic.pidfile class daemon(object): 'Context manager for POSIX daemon processes' @@ -71,22 +71,23 @@ def daemonize(self): if self.pidfile is not None: pid = str(os.getpid()) try: - pidfile.make_pidfile(self.pidfile, pid) - except pidfile.PIDFileError as e: + daemonic.pidfile.make_pidfile(self.pidfile, pid) + except daemonic.pidfile.PIDFileError as e: + sys.stederr.write('Creating PID file failed. ({})'.format(e)) os._exit(os.EX_OSERR) atexit.register(self.stop) def stop(self): if self.pidfile is not None: - pid = pidfile.readpid(self.pidfile) + pid = daemonic.pidfile.readpid(self.pidfile) try: while True: - os.kill(pid, signal.SIGTERM) + os.kill(int(pid), signal.SIGTERM) time.sleep(0.1) except OSError as e: if e.errno == errno.ESRCH: - pidfile.remove_pidfile(self.pidfile) + daemonic.pidfile.remove_pidfile(self.pidfile) else: raise From e9f1935b56e2ba535f68f1133a16ccd189dee65e Mon Sep 17 00:00:00 2001 From: Pierre Date: Thu, 26 Sep 2013 20:37:21 +0200 Subject: [PATCH 2/2] Add possibilty to change the daemon user. --- daemonic/daemon.py | 26 +++++++++++++++++++++++--- daemonic/pidfile.py | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/daemonic/daemon.py b/daemonic/daemon.py index 9e482a4..68c6e8b 100644 --- a/daemonic/daemon.py +++ b/daemonic/daemon.py @@ -9,6 +9,7 @@ import atexit import signal import time +import pwd import daemonic.pidfile @@ -22,10 +23,13 @@ def __init__(self, stdin=None, stdout=None, stderr=None, + user=None ): self.pidfile = pidfile self.workingdir = workingdir self.umask = umask + self.daemon_user = user + self.old_env = os.environ.copy() devnull = os.open(os.devnull, os.O_RDWR) self.stdin = stdin.fileno() if stdin is not None else devnull @@ -73,12 +77,28 @@ def daemonize(self): try: daemonic.pidfile.make_pidfile(self.pidfile, pid) except daemonic.pidfile.PIDFileError as e: - - sys.stederr.write('Creating PID file failed. ({})'.format(e)) + sys.stderr.write('Creating PID file failed. ({})'.format(e)) os._exit(os.EX_OSERR) + + # Change user if need + if self.daemon_user is not None: + pw_record = pwd.getpwnam(self.daemon_user) + user_name = pw_record.pw_name + user_home_dir = pw_record.pw_dir + user_uid = pw_record.pw_uid + user_gid = pw_record.pw_gid + env = os.environ.copy() + env[ 'HOME' ] = user_home_dir + env[ 'LOGNAME' ] = user_name + env[ 'USER' ] = user_name + os.setgid(user_gid) + os.setuid(user_uid) + os.environ = env + atexit.register(self.stop) def stop(self): + os.environ = self.old_env if self.pidfile is not None: pid = daemonic.pidfile.readpid(self.pidfile) try: @@ -97,6 +117,6 @@ def _getchildfork(n): if pid > 0: sys.exit(os.EX_OK) # Exit in parent except OSError as e: - sys.stederr.write('Fork #{} failed: {} ({})\n'.format( + sys.stderr.write('Fork #{} failed: {} ({})\n'.format( n, e.errno, e.strerror)) os._exit(os.EX_OSERR) diff --git a/daemonic/pidfile.py b/daemonic/pidfile.py index 2b68b87..f03c6f0 100644 --- a/daemonic/pidfile.py +++ b/daemonic/pidfile.py @@ -52,6 +52,7 @@ def is_pid_running(pid): def make_pidfile(path, pid): '''Create a PID file. ''' + fd = None try: fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL) except OSError as e: