summaryrefslogtreecommitdiff
path: root/daemon/daemon.py
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/daemon.py')
-rw-r--r--daemon/daemon.py144
1 files changed, 81 insertions, 63 deletions
diff --git a/daemon/daemon.py b/daemon/daemon.py
index 28db695..b998966 100644
--- a/daemon/daemon.py
+++ b/daemon/daemon.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# daemon/daemon.py
-# Part of python-daemon, an implementation of PEP 3143.
+# Part of ‘python-daemon’, an implementation of PEP 3143.
#
-# Copyright © 2008–2010 Ben Finney <ben+python@benfinney.id.au>
+# Copyright © 2008–2014 Ben Finney <ben+python@benfinney.id.au>
# Copyright © 2007–2008 Robert Niederreiter, Jens Klein
# Copyright © 2004–2005 Chad J. Schroeder
# Copyright © 2003 Clark Evans
@@ -11,13 +11,15 @@
# Copyright © 2001 Jürgen Hermann
#
# This is free software: you may copy, modify, and/or distribute this work
-# under the terms of the Python Software Foundation License, version 2 or
-# later as published by the Python Software Foundation.
-# No warranty expressed or implied. See the file LICENSE.PSF-2 for details.
+# under the terms of the Apache License, version 2.0 as published by the
+# Apache Software Foundation.
+# No warranty expressed or implied. See the file LICENSE.ASF-2 for details.
""" Daemon process behaviour.
"""
+from __future__ import (absolute_import, unicode_literals)
+
import os
import sys
import resource
@@ -26,6 +28,14 @@ import signal
import socket
import atexit
+
+try:
+ # Base type of strings in Python 2.
+ basestring
+except NameError:
+ # Python 3 only has one string type.
+ basestring = str
+
class DaemonError(Exception):
""" Base exception class for errors from this module. """
@@ -204,21 +214,21 @@ class DaemonContext(object):
"""
def __init__(
- self,
- chroot_directory=None,
- working_directory='/',
- umask=0,
- uid=None,
- gid=None,
- prevent_core=True,
- detach_process=None,
- files_preserve=None,
- pidfile=None,
- stdin=None,
- stdout=None,
- stderr=None,
- signal_map=None,
- ):
+ self,
+ chroot_directory=None,
+ working_directory='/',
+ umask=0,
+ uid=None,
+ gid=None,
+ prevent_core=True,
+ detach_process=None,
+ files_preserve=None,
+ pidfile=None,
+ stdin=None,
+ stdout=None,
+ stderr=None,
+ signal_map=None,
+ ):
""" Set up a new instance. """
self.chroot_directory = chroot_directory
self.working_directory = working_directory
@@ -394,8 +404,8 @@ class DaemonContext(object):
"""
exception = SystemExit(
- "Terminating on signal %(signal_number)r"
- % vars())
+ "Terminating on signal %(signal_number)r"
+ % vars())
raise exception
def _get_exclude_file_descriptors(self):
@@ -418,8 +428,8 @@ class DaemonContext(object):
if files_preserve is None:
files_preserve = []
files_preserve.extend(
- item for item in [self.stdin, self.stdout, self.stderr]
- if hasattr(item, 'fileno'))
+ item for item in [self.stdin, self.stdout, self.stderr]
+ if hasattr(item, 'fileno'))
exclude_descriptors = set()
for item in files_preserve:
if item is None:
@@ -458,8 +468,8 @@ class DaemonContext(object):
"""
signal_handler_map = dict(
- (signal_number, self._make_signal_handler(target))
- for (signal_number, target) in self.signal_map.items())
+ (signal_number, self._make_signal_handler(target))
+ for (signal_number, target) in self.signal_map.items())
return signal_handler_map
@@ -468,10 +478,10 @@ def change_working_directory(directory):
"""
try:
os.chdir(directory)
- except Exception, exc:
+ except Exception as exc:
error = DaemonOSEnvironmentError(
- "Unable to change working directory (%(exc)s)"
- % vars())
+ "Unable to change working directory (%(exc)s)"
+ % vars())
raise error
@@ -486,10 +496,10 @@ def change_root_directory(directory):
try:
os.chdir(directory)
os.chroot(directory)
- except Exception, exc:
+ except Exception as exc:
error = DaemonOSEnvironmentError(
- "Unable to change root directory (%(exc)s)"
- % vars())
+ "Unable to change root directory (%(exc)s)"
+ % vars())
raise error
@@ -498,10 +508,10 @@ def change_file_creation_mask(mask):
"""
try:
os.umask(mask)
- except Exception, exc:
+ except Exception as exc:
error = DaemonOSEnvironmentError(
- "Unable to change file creation mask (%(exc)s)"
- % vars())
+ "Unable to change file creation mask (%(exc)s)"
+ % vars())
raise error
@@ -516,10 +526,10 @@ def change_process_owner(uid, gid):
try:
os.setgid(gid)
os.setuid(uid)
- except Exception, exc:
+ except Exception as exc:
error = DaemonOSEnvironmentError(
- "Unable to change file creation mask (%(exc)s)"
- % vars())
+ "Unable to change process owner (%(exc)s)"
+ % vars())
raise error
@@ -535,15 +545,15 @@ def prevent_core_dump():
try:
# Ensure the resource limit exists on this platform, by requesting
- # its current value
+ # its current value.
core_limit_prev = resource.getrlimit(core_resource)
- except ValueError, exc:
+ except ValueError as exc:
error = DaemonOSEnvironmentError(
- "System does not support RLIMIT_CORE resource limit (%(exc)s)"
- % vars())
+ "System does not support RLIMIT_CORE resource limit (%(exc)s)"
+ % vars())
raise error
- # Set hard and soft limits to zero, i.e. no core dump at all
+ # Set hard and soft limits to zero, i.e. no core dump at all.
core_limit = (0, 0)
resource.setrlimit(core_resource, core_limit)
@@ -571,11 +581,12 @@ def detach_process_context():
pid = os.fork()
if pid > 0:
os._exit(0)
- except OSError, exc:
+ except OSError as exc:
exc_errno = exc.errno
exc_strerror = exc.strerror
error = DaemonProcessDetachError(
- "%(error_message)s: [%(exc_errno)d] %(exc_strerror)s" % vars())
+ "%(error_message)s: [%(exc_errno)d] %(exc_strerror)s"
+ % vars())
raise error
fork_then_exit_parent(error_message="Failed first fork")
@@ -612,17 +623,17 @@ def is_socket(fd):
try:
socket_type = file_socket.getsockopt(
- socket.SOL_SOCKET, socket.SO_TYPE)
- except socket.error, exc:
+ socket.SOL_SOCKET, socket.SO_TYPE)
+ except socket.error as exc:
exc_errno = exc.args[0]
if exc_errno == errno.ENOTSOCK:
- # Socket operation on non-socket
+ # Socket operation on non-socket.
pass
else:
- # Some other socket error
+ # Some other socket error.
result = True
else:
- # No error getting socket type
+ # No error getting socket type.
result = True
return result
@@ -673,15 +684,15 @@ def close_file_descriptor_if_open(fd):
"""
try:
os.close(fd)
- except OSError, exc:
+ except OSError as exc:
if exc.errno == errno.EBADF:
- # File descriptor was not open
+ # File descriptor was not open.
pass
else:
error = DaemonOSEnvironmentError(
- "Failed to close file descriptor %(fd)d"
- " (%(exc)s)"
- % vars())
+ "Failed to close file descriptor %(fd)d"
+ " (%(exc)s)"
+ % vars())
raise error
@@ -742,15 +753,15 @@ def make_default_signal_map():
"""
name_map = {
- 'SIGTSTP': None,
- 'SIGTTIN': None,
- 'SIGTTOU': None,
- 'SIGTERM': 'terminate',
- }
+ 'SIGTSTP': None,
+ 'SIGTTIN': None,
+ 'SIGTTOU': None,
+ 'SIGTERM': 'terminate',
+ }
signal_map = dict(
- (getattr(signal, name), target)
- for (name, target) in name_map.items()
- if hasattr(signal, name))
+ (getattr(signal, name), target)
+ for (name, target) in name_map.items()
+ if hasattr(signal, name))
return signal_map
@@ -774,3 +785,10 @@ def register_atexit_function(func):
"""
atexit.register(func)
+
+
+# Local variables:
+# coding: utf-8
+# mode: python
+# End:
+# vim: fileencoding=utf-8 filetype=python :