[Top][All Lists]
[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()
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9785 - trunk/gnue-common/src/apps,
johannes <=