Salome HOME
manage extra environment files
[modules/kernel.git] / bin / server.py
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
4 #
5 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 #
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #
24
25 import os, sys, string
26 from salome_utils import getHostName
27 process_id = {}
28
29 # -----------------------------------------------------------------------------
30 #
31 # Definition des classes d'objets pour le lancement des Server CORBA
32 #
33
34 class Server:
35     """Generic class for CORBA server launch"""
36
37     server_launch_mode = "daemon"
38
39     def initArgs(self):
40         self.PID=None
41         self.CMD=[]
42         self.ARGS=[]
43         if self.args.get('xterm'):
44           if sys.platform != "win32":
45             self.ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-hold']
46           else:
47             self.ARGS=['cmd', '/c', 'start  cmd.exe', '/K']
48
49     def __init__(self,args):
50         self.args=args
51         self.initArgs()
52
53     @staticmethod
54     def set_server_launch_mode(mode):
55       if mode == "daemon" or mode == "fork":
56         Server.server_launch_mode = mode
57       else:
58         raise Exception("Unsupported server launch mode: %s" % mode)
59
60     def run(self):
61         global process_id
62         myargs=self.ARGS
63         if self.args.get('xterm'):
64             # (Debian) send LD_LIBRARY_PATH to children shells (xterm)
65             if sys.platform != "win32":
66               env_ld_library_path=['env', 'LD_LIBRARY_PATH='
67                                    + os.getenv("LD_LIBRARY_PATH")]
68               myargs = myargs +['-T']+self.CMD[:1]+['-e'] + env_ld_library_path
69         command = myargs + self.CMD
70         #print "command = ", command
71         if sys.platform == "win32":
72           import win32pm
73           pid = win32pm.spawnpid( command, '-nc' )
74         elif Server.server_launch_mode == "fork":
75           pid = os.spawnvp(os.P_NOWAIT, command[0], command)
76         else: # Server launch mode is daemon
77           pid=self.daemonize(command)
78         if pid is not None:
79           #store process pid if it really exists
80           process_id[pid]=self.CMD
81         self.PID = pid
82         return pid
83
84     def daemonize(self,args):
85         # to daemonize a process need to do the UNIX double-fork magic
86         # see Stevens, "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177)
87         # and UNIX Programming FAQ 1.7 How do I get my program to act like a daemon?
88         #     http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
89         #open a pipe
90         c2pread, c2pwrite = os.pipe()
91         #do first fork
92         pid=os.fork()
93         if pid > 0:
94           #first parent
95           os.close(c2pwrite)
96           #receive real pid from child
97           data=os.read(c2pread,24) #read 24 bytes
98           os.waitpid(pid,0) #remove zombie
99           os.close(c2pread)
100           # return : first parent
101           childpid=int(data)
102           if childpid==-1:
103             return None
104           try:
105             os.kill(childpid,0)
106             return childpid
107           except:
108             return None
109
110         #first child
111         # decouple from parent environment
112         os.setsid()
113         os.close(c2pread)
114
115         # do second fork : second child not a session leader
116         try:
117           pid = os.fork()
118           if pid > 0:
119             #send real pid to parent
120             os.write(c2pwrite,"%d" % pid)
121             os.close(c2pwrite)
122             # exit from second parent
123             os._exit(0)
124         except OSError, e:
125           print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
126           os.write(c2pwrite,"-1")
127           os.close(c2pwrite)
128           sys.exit(1)
129
130         #I am a daemon
131         os.close(0) #close stdin
132         os.open("/dev/null", os.O_RDWR)  # redirect standard input (0) to /dev/null
133         try:
134           os.execvp(args[0], args)
135         except OSError, e:
136           print >>sys.stderr, "(%s) launch failed: %d (%s)" % (args[0],e.errno, e.strerror)
137           os._exit(127)