فهرست منبع

Pulled in the daemon class from the earlier stdd project and made some corrections to it.

Helmut Pozimski 10 سال پیش
والد
کامیت
8cdcfa10a0
1فایلهای تغییر یافته به همراه123 افزوده شده و 0 حذف شده
  1. 123 0
      jwmudlib/daemon.py

+ 123 - 0
jwmudlib/daemon.py

@@ -0,0 +1,123 @@
+# This file is part of jwmud, written by Helmut Pozimski in 2014.
+#
+#       jwmud is free software: you can redistribute it and/or modify
+#       it under the terms of the GNU General Public License as published by
+#       the Free Software Foundation, version 2 of the License.
+#
+#       jwmud is distributed in the hope that it will be useful,
+#       but WITHOUT ANY WARRANTY; without even the implied warranty of
+#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#       GNU General Public License for more details.
+#
+#       You should have received a copy of the GNU General Public License
+#       along with jwmud.  If not, see <http://www.gnu.org/licenses/>.
+
+# -*- coding: utf8 -*-
+
+import os
+import sys
+
+
+class Daemon(object):
+    """ Tries to implement a well behaving unix daemon in a generic way,
+    so the code could be used in different projects.
+
+    """
+
+    def __init__(self, pfile_path, pfile_name):
+        """ Initializes the object. """
+        self.__pfile_path = pfile_path
+        self.__pfile_name = pfile_name
+        self.__daemon = False
+        self.__pid = 0
+        self.__pidfile = ""
+
+    def Daemonize(self):
+        """ Turns the calling process into a daemon running on it's own """
+
+        try:
+            # Fork for the first time
+            self.__pid = os.fork()
+        except OSError:
+            sys.exit(os.EX_OSERR)
+        else:
+            if self.__pid > 0:
+                sys.exit(os.EX_OK)
+        # Become session and group leader
+        # noinspection PyArgumentList
+        os.setsid()
+        try:
+            #Fork for the second time
+            self.__pid = os.fork()
+        except OSError:
+            sys.exit(os.EX_OSERR)
+        else:
+            if self.__pid > 0:
+                sys.exit(os.EX_OK)
+        # Change cwd to / to avoid interfering with other mounted file systems
+        os.chdir("/")
+        # Reset the umask
+        os.umask(0)
+
+        # Close possibly open file descriptors
+        os.close(0)
+        os.close(1)
+        os.close(2)
+
+        # And redirect them to /dev/null
+        os.open("/dev/null", 0)
+        os.open("/dev/null", 1)
+        os.open("/dev/null", 2)
+
+        self.__daemon = True
+
+    def DropPriv(self, uid, gid):
+        """ If the daemon is running as root user, drop privileges and continue
+        running as the defined unprivileged user """
+        if os.getuid() == 0:
+            os.setgid(gid)
+            os.setuid(uid)
+
+    def SetName(self, name, cmdline):
+        """ Sets the name of the process shown visible in ps and top,
+        this allows to make your daemon look more like a standalone
+        program instead of a python script.
+
+        """
+        try:
+            # First check if prctl is available, otherwise this
+            # function does nothing
+            # noinspection PyUnresolvedReferences
+            import prctl
+        except ImportError:
+            return False
+        else:
+            prctl.set_name(name)
+            prctl.set_proctitle(cmdline)
+            return True
+
+    def Start(self):
+        """ Performs the operations needed to "start" the daemon """
+        if self.__daemon is True:
+            if os.access(self.__pfile_path, os.F_OK & os.W_OK):
+                self.__pidfile = open(os.path.join(self.__pfile_path,
+                                                   self.__pfile_name), "w")
+                self.__pidfile.write(str(os.getpid()) + "\n")
+                self.__pidfile.close()
+                return True
+            else:
+                return False
+        else:
+            return False
+
+    def Stop(self):
+        """ Performs the operations needed to stop the daemon """
+        if self.__daemon is True:
+            try:
+                os.remove(os.path.join(self.__pfile_path, self.__pfile_name))
+            except OSError:
+                return False
+            else:
+                return True
+        else:
+            return True