commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r9785 - trunk/gnue-common/src/apps


From: johannes
Subject: [gnue] r9785 - trunk/gnue-common/src/apps
Date: Thu, 27 Sep 2007 03:57:01 -0500 (CDT)

Author: johannes
Date: 2007-09-27 03:57:00 -0500 (Thu, 27 Sep 2007)
New Revision: 9785

Modified:
   trunk/gnue-common/src/apps/GBaseApp.py
   trunk/gnue-common/src/apps/GServerApp.py
Log:
Properly close the open filehandles, so we're not connected to the 
controlling terminal anymore.

issue122 testing


Modified: trunk/gnue-common/src/apps/GBaseApp.py
===================================================================
--- trunk/gnue-common/src/apps/GBaseApp.py      2007-09-26 13:35:03 UTC (rev 
9784)
+++ trunk/gnue-common/src/apps/GBaseApp.py      2007-09-27 08:57:00 UTC (rev 
9785)
@@ -313,10 +313,11 @@
         serr = open('nul', 'w')
 
       try:
-        sys.stdout.close()
+        os.close(sys.stdout.fileno())
         sys.stdout = sout
-        sys.stderr.close()
+        os.close(sys.stderr.fileno())
         sys.stderr = serr
+
       except:
         pass
 

Modified: trunk/gnue-common/src/apps/GServerApp.py
===================================================================
--- trunk/gnue-common/src/apps/GServerApp.py    2007-09-26 13:35:03 UTC (rev 
9784)
+++ trunk/gnue-common/src/apps/GServerApp.py    2007-09-27 08:57:00 UTC (rev 
9785)
@@ -1,9 +1,12 @@
+# GNU Enterprise Common Library - Application Services - Server applications
 #
-# This file is part of GNU Enterprise.
+# Copyright 2001-2007 Free Software Foundation
 #
-# GNU Enterprise 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; either 
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise 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; either
 # version 2, or (at your option) any later version.
 #
 # GNU Enterprise is distributed in the hope that it will be
@@ -16,225 +19,240 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# Copyright 2000-2007 Free Software Foundation
-#
-# FILE:
-# GServerApp.py
-#
-# DESCRIPTION:
-# Class that provides a basis for GNUe server applications.
-#
-# NOTES:
-# This will eventually have features only needed by "server"
-# applications, such as abstracted client RPC calls via
-# CORBA, RPC-XML, SOAP, etc and daemon/forking/threading.
-#
+# $Id$
 
-from gnue.common.apps.GBaseApp import GBaseApp
-from gnue.common.apps import GConfig, errors
-from gnue.common.apps.GLogger import Logger
 import sys
 import os
 import os.path
 import signal
 
+from gnue.common.apps.GBaseApp import GBaseApp
+from gnue.common.apps import GConfig, errors
+from gnue.common.apps.GLogger import Logger
 
+
+# =============================================================================
+# Exceptions
+# =============================================================================
+
 class ServerRunningError (errors.UserError):
-  def __init__ (self, pid):
-    msg = u_("The server is already running on pid %s") % pid
-    errors.UserError.__init__ (self, msg)
+    """ The server is already running on a given pid """
+    def __init__ (self, pid):
+        msg = u_("The server is already running on pid %s") % pid
+        errors.UserError.__init__ (self, msg)
 
 
+# =============================================================================
+# Base class for server applications
+# =============================================================================
+
 class GServerApp(GBaseApp):
+    """
+    This is the basse class for server applications
+    """
 
-  def __init__(self, connections=None, application=None, defaults=None):
+    # -------------------------------------------------------------------------
+    # Constructor
+    # -------------------------------------------------------------------------
 
-    self.COMMAND_OPTIONS.append (
-      [ 'foreground','Z','no-detach',0,0, None,
-        u_("Do not send the server into the background. For a POSIX system, "
-          "this option keeps the server process from forking and detaching "
-          "from its controlling terminal.")],
-    )
+    def __init__(self, connections=None, application=None, defaults=None):
 
-    self.COMMAND_OPTIONS.append (
-        ['pidfile', 'P', 'pidfile', True,
-         '/var/run/gnue/%s.pid' % application or 'gnue', u_('pid-file'),
-        u_("Filename to store the server's process id.")])
+        self.COMMAND_OPTIONS.append(
+          ['foreground','Z','no-detach',0,0, None,
+           u_("Do not send the server into the background. For a POSIX system, 
"
+              "this option keeps the server process from forking and detaching 
"
+              "from its controlling terminal.")],
+        )
 
-    GBaseApp.__init__(self, connections, application, defaults)
+        self.COMMAND_OPTIONS.append(
+            ['pidfile', 'P', 'pidfile', True,
+             '/var/run/gnue/%s.pid' % application or 'gnue', u_('pid-file'),
+            u_("Filename to store the server's process id.")])
 
-    if not self.OPTIONS ['foreground']:
-      if os.name == 'posix':
-        self.__removeStaleFile ()
-        self.__createPidFile (0)
-
-    try:
-      signal.signal (signal.SIGTERM, self._terminate)
-    except ValueError:
-      # signal only works in main thread, but
-      # in a win32 service we are not in the main thread here
-      pass
+        GBaseApp.__init__(self, connections, application, defaults)
 
+        if not self.OPTIONS['foreground']:
+            if os.name == 'posix':
+                self.__removeStaleFile()
+                self.__createPidFile(0)
 
+        try:
+            signal.signal(signal.SIGTERM, self._terminate)
 
-  # This can be overwritten by code necessary
-  # for startup.  If overwritten, do not first
-  # call the original GServerApp.run(self) as
-  # this would send to background immediately.
-  # Instead, call the original GServerApp.run(self)
-  # after you are sure you are finished with
-  # startup code and are ready to go to server
-  # mode.
-  def run(self):
+        except ValueError:
+            # signal only works in main thread, but
+            # in a win32 service we are not in the main thread here
+            pass
 
-    # Fork, if applicable/possible, and send to background
-    if not self.OPTIONS ["foreground"]:
-      self.daemonize ()
 
+    # -------------------------------------------------------------------------
+    # Run der Server applictaion
+    # -------------------------------------------------------------------------
 
-  # Called when a request to shutdown the server is received
-  def shutdown(self):
-    pass
+    def run(self):
+        """
+        This can be overwritten by code necessary for startup.  If overwritten,
+        do not first call the original GServerApp.run(self) as this would send
+        to background immediately.  Instead, call the original
+        GServerApp.run(self) after you are sure you are finished with startup
+        code and are ready to go to server mode.
+        """
 
+        # Fork, if applicable/possible, and send to background
+        if not self.OPTIONS["foreground"]:
+            self.daemonize()
 
-  # Turn ourselves into a daemon/service/etc.
-  # Returns 1 if program successfully converted,
-  # 0 otherwise.
-  #
-  def daemonize (self):
 
-    # For an overview of what we're doing here,
-    # check out the Unix Programmer's FAQ at:
-    # http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
+    # -------------------------------------------------------------------------
+    # Shutdown the server application
+    # -------------------------------------------------------------------------
 
-    # We enclose these actions in try: blocks so that
-    # this doesn't fail on non-Unix environments.
+    def shutdown(self):
+        """
+        Called when a request to shutdown the server is received
+        """
+        pass
 
-    self.__removeStaleFile ()
 
-    try:
-      # Fork #1
-      pid = os.fork()
-      if pid != 0:
-        # Close main process
-        sys.exit(0)
+    # -------------------------------------------------------------------------
+    # Daemonize the server application
+    # -------------------------------------------------------------------------
 
-      # Open new filehandles for stdin, stdout, stderr
-      # TODO: This may eventually be log files. 
-      sin = open('/dev/null','r')
-      sout = open('/dev/null','w')
-      serr = open('/dev/null','w')
+    def daemonize(self):
+        """
+        Turn ourselves into a daemon/service/etc.
 
-    except AttributeError:
-      return 0
-    except IOError:
-      return 0
-    except OSError:
-      return 0
+        @returns: 1 if the program successfully converted, 0 otherwise
+        """
 
+        # For an overview of what we're doing here, check out the Unix
+        # Programmer's FAQ at:
+        # http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
 
-    # Disassociate ourselves
-    try:
-      os.chdir('/')
-      os.setsid()
-      os.umask(0)
-    except AttributeError:
-      pass
-    except OSError:
-      pass
+        # We enclose these actions in try: blocks so that this doesn't fail on
+        # non-Unix environments.
 
+        self.__removeStaleFile()
 
-    try:
-      # Fork #2
-      pid = os.fork()
-      if pid != 0:
-        self.__createPidFile (pid)
+        try:
+            # Fork #1
+            pid = os.fork()
+            if pid != 0:
+                # Close main process
+                sys.exit(0)
 
-        sys.exit(0)
-    except OSError:
-      pass
+        except AttributeError:
+            return 0
+        except IOError:
+            return 0
+        except OSError:
+            return 0
 
 
-    # Redirect all the stdio channels.
-    # (after all, we have no terminal :)
-    try:
-      sys.stdin.close()
-      sys.stdin = sin
+        # Disassociate ourselves
+        try:
+            os.chdir('/')
+            os.setsid()
+            os.umask(0)
+        except AttributeError:
+            pass
+        except OSError:
+            pass
 
-      sys.stdout.close()
-      sys.stdout = sout
 
-      sys.stderr.close()
-      sys.stderr = serr
-    except AttributeError:
-      pass
+        try:
+            # Fork #2
+            pid = os.fork()
+            if pid != 0:
+                self.__createPidFile(pid)
 
-    return 1
+                sys.exit(0)
+        except OSError:
+            pass
 
 
-  # ---------------------------------------------------------------------------
-  # Create a new pid file
-  # ---------------------------------------------------------------------------
+        # Redirect all the stdio channels.
+        # (after all, we have no terminal :)
+        try:
+            os.close(sys.stdin.fileno())
+            sys.stdin = open('/dev/null','r')
 
-  def __createPidFile (self, pid):
-    """
-    This function creates a new pid file for the current process.
+            os.close(sys.stdout.fileno())
+            sys.stdout = open('/dev/null','w')
 
-    @param pid: Process id to store in the pid file
-    """
+            os.close(sys.stderr.fileno())
+            sys.stderr = serr = open('/dev/null','w')
 
-    piddir = os.path.dirname (self.OPTIONS ['pidfile'])
-    if not os.path.exists (piddir):
-      os.makedirs (piddir)
+        except AttributeError:
+            pass
 
-    pidfile = open (self.OPTIONS ['pidfile'], 'w')
-    pidfile.write ("%s%s" % (pid, os.linesep))
-    pidfile.close ()
+        return 1
 
 
-  # ---------------------------------------------------------------------------
-  # Remove a stale pid file
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Create a new pid file
+    # -------------------------------------------------------------------------
 
-  def __removeStaleFile (self):
-    """
-    This function checks for a stale pid file. If a file exists, this function
-    raises a ServerRunningError exception if the process is till alive.
-    """
+    def __createPidFile(self, pid):
+        """
+        This function creates a new pid file for the current process.
 
-    if os.path.exists (self.OPTIONS ['pidfile']):
-      pidfile = open (self.OPTIONS ['pidfile'], 'r')
+        @param pid: Process id to store in the pid file
+        """
 
-      try:
-        oldPid = int (pidfile.readline ().strip ())
+        piddir = os.path.dirname(self.OPTIONS['pidfile'])
+        if not os.path.exists(piddir):
+            os.makedirs(piddir)
 
-        if oldPid:
-          try:
-            os.kill (oldPid, 0)
+        pidfile = open(self.OPTIONS['pidfile'], 'w')
+        pidfile.write("%s%s" % (pid, os.linesep))
+        pidfile.close()
 
-          except OSError:
-            # remove the stale pid-file
-            os.unlink (self.OPTIONS ['pidfile'])
 
-          else:
-            raise ServerRunningError, oldPid
+    # -------------------------------------------------------------------------
+    # Remove a stale pid file
+    # -------------------------------------------------------------------------
 
-      finally:
-        pidfile.close ()
+    def __removeStaleFile(self):
+        """
+        This function checks for a stale pid file. If a file exists, this
+        function raises a ServerRunningError exception if the process is till
+        alive.
+        """
 
+        if os.path.exists(self.OPTIONS['pidfile']):
+            pidfile = open(self.OPTIONS['pidfile'], 'r')
 
-  # ---------------------------------------------------------------------------
-  # Handle a SIGTERM signal
-  # ---------------------------------------------------------------------------
+            try:
+                old_pid = int(pidfile.readline().strip())
 
-  def _terminate (self, signal, frame):
-    """
-    This function handles a SIGTERM signal and removes the pid-file if the
-    server is running in the background.
-    """
+                if old_pid:
+                    try:
+                        os.kill(old_pid, 0)
 
-    if not self.OPTIONS ["foreground"] and \
-        os.path.exists (self.OPTIONS ['pidfile']):
-      os.unlink (self.OPTIONS ['pidfile'])
+                    except OSError:
+                        # remove the stale pid-file
+                        os.unlink(self.OPTIONS['pidfile'])
 
-    sys.exit ()
+                    else:
+                        raise ServerRunningError, old_pid
+
+            finally:
+                pidfile.close()
+
+
+    # -------------------------------------------------------------------------
+    # Handle a SIGTERM signal
+    # -------------------------------------------------------------------------
+
+    def _terminate(self, signal, frame):
+        """
+        This function handles a SIGTERM signal and removes the pid-file if the
+        server is running in the background.
+        """
+
+        if not self.OPTIONS["foreground"] and \
+            os.path.exists(self.OPTIONS['pidfile']):
+            os.unlink(self.OPTIONS['pidfile'])
+
+        sys.exit()





reply via email to

[Prev in Thread] Current Thread [Next in Thread]