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

[email protected]
Newsgroups gmane.comp.cms.gnue.cvs
Message-ID <[email protected]>
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()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.