Salome HOME
Try to kill Salome application when a YACS Launcher job is killed
[modules/kernel.git] / bin / runSalome.py
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2011  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.
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 ## @package runSalome
26 # \brief Module that provides services to launch SALOME
27 #
28
29 import sys, os, string, glob, time, pickle, re
30 import orbmodule
31 import setenv
32 from server import *
33 from launchConfigureParser import verbose
34 from server import process_id
35
36 if sys.platform == "win32":
37     SEP = ";"
38 else:
39     SEP = ":"
40
41 # -----------------------------------------------------------------------------
42
43 from killSalome import killAllPorts
44
45 def killLocalPort():
46     """
47     kill servers from a previous SALOME exection, if needed,
48     on the CORBA port given in args of runSalome
49     """
50     
51     from killSalomeWithPort import killMyPort
52     my_port=str(args['port'])
53     try:
54         killMyPort(my_port)
55     except:
56         print "problem in killLocalPort()"
57         pass
58     pass
59     
60 def givenPortKill(port):
61     """
62     kill servers from a previous SALOME exection, if needed,
63     on the same CORBA port
64     """
65     
66     from killSalomeWithPort import killMyPort
67     my_port=port
68     try:
69         killMyPort(my_port)
70     except:
71         print "problem in LocalPortKill(), killMyPort("<<port<<")"
72         pass
73     pass
74
75 def kill_salome(args):
76     """
77     Kill servers from previous SALOME executions, if needed;
78     depending on args 'killall' or 'portkill', kill all executions,
79     or only execution on the same CORBA port
80     """
81
82     if args['killall']:
83         killAllPorts()
84     elif args['portkill']:
85         givenPortKill(str(args['port']))
86
87 # -----------------------------------------------------------------------------
88 #
89 # Class definitions to launch CORBA Servers
90 #
91
92 class InterpServer(Server):
93     def __init__(self,args):
94         self.args=args
95         if sys.platform != "win32":
96           env_ld_library_path=['env', 'LD_LIBRARY_PATH=' + os.getenv("LD_LIBRARY_PATH")]
97           self.CMD=['xterm', '-e']+ env_ld_library_path + ['python']
98         else:
99           self.CMD=['cmd', '/c', 'start cmd.exe', '/K', 'python']
100        
101     def run(self):
102         global process_id
103         command = self.CMD
104         print "INTERPSERVER::command = ", command
105         if sys.platform == "win32":
106           import win32pm
107           pid = win32pm.spawnpid( string.join(command, " "),'-nc' )
108         else:
109           pid = os.spawnvp(os.P_NOWAIT, command[0], command)
110         process_id[pid]=self.CMD
111         self.PID = pid
112
113 # ---
114
115 def get_cata_path(list_modules,modules_root_dir):
116     """Build a list of catalog paths (cata_path) to initialize the ModuleCatalog server
117     """
118     modules_cata={}
119     cata_path=[]
120
121     for module in list_modules:
122         if modules_root_dir.has_key(module):
123             module_root_dir=modules_root_dir[module]
124             module_cata=module+"Catalog.xml"
125             cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources",module.lower(), module_cata)
126
127             if os.path.exists(cata_file):
128                 cata_path.append(cata_file)
129                 modules_cata[module]=cata_file
130             else:
131                 cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources", module_cata)
132                 if os.path.exists(cata_file):
133                     cata_path.append(cata_file)
134                     modules_cata[module]=cata_file
135
136     for path in os.getenv("SALOME_CATALOGS_PATH","").split(SEP):
137         if os.path.exists(path):
138             for cata_file in glob.glob(os.path.join(path,"*Catalog.xml")):
139                 module_name= os.path.basename(cata_file)[:-11]
140                 if not modules_cata.has_key(module_name):
141                     cata_path.append(cata_file)
142                     modules_cata[module_name]=cata_file
143
144     return cata_path
145
146
147
148 class CatalogServer(Server):
149     def __init__(self,args):
150         self.args=args
151         self.initArgs()
152         self.SCMD1=['SALOME_ModuleCatalog_Server','-common']
153         self.SCMD2=[]
154         home_dir=os.getenv('HOME')
155         if home_dir is not None:
156             self.SCMD2=['-personal',os.path.join(home_dir,'Salome/resources/CatalogModulePersonnel.xml')] 
157
158     def setpath(self,modules_list,modules_root_dir):
159         list_modules = modules_list[:]
160         list_modules.reverse()
161         if self.args["gui"] :
162             list_modules = ["KERNEL", "GUI"] + list_modules
163         else :
164             list_modules = ["KERNEL"] + list_modules
165
166         cata_path=get_cata_path(list_modules,modules_root_dir)
167
168         self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
169
170 # ---
171
172 class SalomeDSServer(Server):
173     def __init__(self,args):
174         self.args=args
175         self.initArgs()
176         self.CMD=['SALOMEDS_Server']
177
178 # ---
179
180 class ConnectionManagerServer(Server):
181     def __init__(self,args):
182         self.args=args
183         self.initArgs()
184         self.CMD=['SALOME_ConnectionManagerServer']
185
186 # ---
187
188 class RegistryServer(Server):
189     def __init__(self,args):
190         self.args=args
191         self.initArgs()
192         self.CMD=['SALOME_Registry_Server', '--salome_session','theSession']
193
194 # ---
195
196 class ContainerCPPServer(Server):
197     def __init__(self,args):
198         self.args=args
199         self.initArgs()
200         self.CMD=['SALOME_Container','FactoryServer']
201
202 # ---
203
204 class ContainerPYServer(Server):
205     def __init__(self,args):
206         self.args=args
207         self.initArgs()
208         if sys.platform == "win32":
209           self.CMD=[os.environ["PYTHONBIN"], '\"'+os.environ["KERNEL_ROOT_DIR"] + '/bin/salome/SALOME_ContainerPy.py'+'\"','FactoryServerPy']
210         else:
211           self.CMD=['SALOME_ContainerPy.py','FactoryServerPy']
212
213 # ---
214
215 class LoggerServer(Server):
216     def __init__(self,args):
217         self.args=args
218         self.initArgs()
219         from salome_utils import generateFileName
220         if sys.platform == "win32": dirpath = os.environ["HOME"]
221         else:                       dirpath = "/tmp"
222         logfile = generateFileName( dirpath,
223                                     prefix="logger",
224                                     extension="log",
225                                     with_username=True,
226                                     with_hostname=True,
227                                     with_port=True)
228         print "==========================================================="
229         print "Logger server: put log to the file:"
230         print logfile
231         print "==========================================================="
232         self.CMD=['SALOME_Logger_Server', logfile]
233         pass
234     pass # end of LoggerServer class
235
236 # ---
237
238 class SessionServer(Server):
239     def __init__(self,args,modules_list,modules_root_dir):
240         self.args = args.copy()
241         # Bug 11512 (Problems with runSalome --xterm on Mandrake and Debian Sarge)
242         #self.args['xterm']=0
243         #
244         self.initArgs()
245         self.SCMD1=['SALOME_Session_Server']
246         self.SCMD2=[]
247         if 'registry' in self.args['embedded']:
248             self.SCMD1+=['--with','Registry',
249                          '(','--salome_session','theSession',')']
250         if 'moduleCatalog' in self.args['embedded']:
251             self.SCMD1+=['--with','ModuleCatalog','(','-common']
252             home_dir=os.getenv('HOME')
253             if home_dir is not None:
254                 self.SCMD2+=['-personal',os.path.join(home_dir,'Salome/resources/CatalogModulePersonnel.xml')] 
255             self.SCMD2+=[')']
256         if 'study' in self.args['embedded']:
257             self.SCMD2+=['--with','SALOMEDS','(',')']
258         if 'cppContainer' in self.args['embedded']:
259             self.SCMD2+=['--with','Container','(','FactoryServer',')']
260         if 'SalomeAppEngine' in self.args['embedded']:
261             self.SCMD2+=['--with','SalomeAppEngine','(',')']
262             
263         if 'cppContainer' in self.args['standalone'] or 'cppContainer' in self.args['embedded']:
264             self.SCMD2+=['CPP']
265         if 'pyContainer' in self.args['standalone'] or 'pyContainer' in self.args['embedded']:
266             self.SCMD2+=['PY']
267         if self.args['gui']:
268             session_gui = True
269             if self.args.has_key('session_gui'):
270                 session_gui = self.args['session_gui']
271             if session_gui:
272                 self.SCMD2+=['GUI']
273                 if self.args['splash']:
274                     self.SCMD2+=['SPLASH']
275                     pass
276                 if self.args['study_hdf'] is not None:
277                     self.SCMD2+=['--study-hdf=%s'%self.args['study_hdf']]
278                     pass
279                 pass
280             pass
281         if self.args['noexcepthandler']:
282             self.SCMD2+=['noexcepthandler']
283         if self.args.has_key('user_config'):
284             self.SCMD2+=['--resources=%s'%self.args['user_config']]
285         if self.args.has_key('modules'):
286             list_modules = []
287             #keep only modules with GUI
288             for m in modules_list:
289               if m not in modules_root_dir:
290                 list_modules.insert(0,m)
291               else:
292                 fr1 = os.path.join(modules_root_dir[m],"share","salome","resources",m.lower(),"SalomeApp.xml")
293                 fr2 = os.path.join(modules_root_dir[m],"share","salome","resources","SalomeApp.xml")
294                 if os.path.exists(fr1) or os.path.exists(fr2):
295                   list_modules.insert(0,m)
296             list_modules.reverse()
297             self.SCMD2+=['--modules (%s)' % ":".join(list_modules)]
298
299         if self.args.has_key('pyscript') and len(self.args['pyscript']) > 0:
300             self.SCMD2+=['--pyscript=%s'%(",".join(self.args['pyscript']))]
301
302     def setpath(self,modules_list,modules_root_dir):
303         list_modules = modules_list[:]
304         list_modules.reverse()
305         if self.args["gui"] :
306             list_modules = ["KERNEL", "GUI"] + list_modules
307         else :
308             list_modules = ["KERNEL"] + list_modules
309
310         cata_path=get_cata_path(list_modules,modules_root_dir)
311
312         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
313             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
314             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
315         else:
316             self.CMD=self.SCMD1 + self.SCMD2
317         if self.args.has_key('test'):
318             self.CMD+=['-test'] + self.args['test']
319         elif self.args.has_key('play'):
320             self.CMD+=['-play'] + self.args['play']
321
322         if self.args["gdb_session"] or self.args["ddd_session"]:
323             f = open(".gdbinit4salome", "w")
324             f.write("set args ")
325             args = " ".join(self.CMD[1:])
326             args = args.replace("(", "\(")
327             args = args.replace(")", "\)")
328             f.write(args)
329             f.write("\n")
330             f.close()
331             if self.args["ddd_session"]:
332                 self.CMD = ["ddd", "--command=.gdbinit4salome", self.CMD[0]]
333             elif self.args["gdb_session"]:
334                 self.CMD = ["xterm", "-e", "gdb", "--command=.gdbinit4salome", self.CMD[0]]
335                 pass
336             pass
337         
338         if self.args["valgrind_session"]:
339             l = ["valgrind"]
340             val = os.getenv("VALGRIND_OPTIONS")
341             if val:
342                 l += val.split()
343                 pass
344             self.CMD = l + self.CMD
345             pass
346         
347 # ---
348
349 class LauncherServer(Server):
350     def __init__(self,args):
351         self.args=args
352         self.initArgs()
353         self.SCMD1=['SALOME_LauncherServer']
354         self.SCMD2=[]
355         if args["gui"] :
356             if 'registry' in self.args['embedded']:
357                 self.SCMD1+=['--with','Registry',
358                              '(','--salome_session','theSession',')']
359             if 'moduleCatalog' in self.args['embedded']:
360                 self.SCMD1+=['--with','ModuleCatalog','(','-common']
361                 self.SCMD2+=['-personal',
362                              '${HOME}/Salome/resources/CatalogModulePersonnel.xml',')']
363             if 'study' in self.args['embedded']:
364                 self.SCMD2+=['--with','SALOMEDS','(',')']
365             if 'cppContainer' in self.args['embedded']:
366                 self.SCMD2+=['--with','Container','(','FactoryServer',')']
367
368     def setpath(self,modules_list,modules_root_dir):
369         list_modules = modules_list[:]
370         list_modules.reverse()
371         if self.args["gui"] :
372             list_modules = ["KERNEL", "GUI"] + list_modules
373         else :
374             list_modules = ["KERNEL"] + list_modules
375
376         cata_path=get_cata_path(list_modules,modules_root_dir)
377
378         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
379             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
380             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
381         else:
382             self.CMD=self.SCMD1 + self.SCMD2
383
384 class NotifyServer(Server):
385     def __init__(self,args,modules_root_dir):
386         self.args=args
387         self.initArgs()
388         self.modules_root_dir=modules_root_dir
389         myLogName = os.environ["LOGNAME"]
390         self.CMD=['notifd','-c',
391                   self.modules_root_dir["KERNEL"] +'/share/salome/resources/kernel/channel.cfg',
392                   '-DFactoryIORFileName=/tmp/'+myLogName+'_rdifact.ior',
393                   '-DChannelIORFileName=/tmp/'+myLogName+'_rdichan.ior',
394                   '-DReportLogFile=/tmp/'+myLogName+'_notifd.report',
395                   '-DDebugLogFile=/tmp/'+myLogName+'_notifd.debug',
396                   ]
397
398 #
399 # -----------------------------------------------------------------------------
400
401 def startGUI(clt):
402     """Salome Session Graphic User Interface activation"""
403     import Engines
404     import SALOME
405     import SALOMEDS
406     import SALOME_ModuleCatalog
407     import SALOME_Session_idl
408     session=clt.waitNS("/Kernel/Session",SALOME.Session)
409     session.GetInterface()
410   
411 # -----------------------------------------------------------------------------
412
413 def startSalome(args, modules_list, modules_root_dir):
414     """Launch all SALOME servers requested by args"""
415     init_time = os.times()
416
417     if verbose(): print "startSalome ", args
418     
419     #
420     # Wake up session option
421     #
422     if args['wake_up_session']:
423         if "OMNIORB_CONFIG" not in os.environ:
424             from salome_utils import generateFileName
425             home  = os.getenv("HOME")
426             appli = os.getenv("APPLI")
427             kwargs={}
428             if appli is not None: 
429                 home = os.path.join(home, appli,"USERS")
430                 kwargs["with_username"] = True
431                 pass
432             last_running_config = generateFileName(home, prefix="omniORB",
433                                                    suffix="last",
434                                                    extension="cfg",
435                                                    hidden=True,
436                                                    **kwargs)
437             os.environ['OMNIORB_CONFIG'] = last_running_config
438             pass
439         pass
440     
441     #
442     # Initialisation ORB and Naming Service
443     #
444    
445     clt=orbmodule.client(args)
446
447     #
448     # Wake up session option
449     #
450     if args['wake_up_session']:
451         import Engines
452         import SALOME
453         import SALOMEDS
454         import SALOME_ModuleCatalog
455         import SALOME_Session_idl
456         session = clt.waitNS("/Kernel/Session",SALOME.Session)
457         status = session.GetStatSession()
458         if status.activeGUI:
459             from salome_utils import getPortNumber
460             port = getPortNumber()
461             msg  = "Warning :"
462             msg += "\n"
463             msg += "Session GUI for port number %s is already active."%(port)
464             msg += "\n"
465             msg += "If you which to wake up another session,"
466             msg += "\n"
467             msg += "please use variable OMNIORB_CONFIG"
468             msg += "\n"
469             msg += "to get the correct session object in naming service."
470             sys.stdout.write(msg+"\n")
471             sys.stdout.flush()
472             return clt
473         session.GetInterface()
474         args["session_object"] = session
475         return clt
476     
477     # Save Naming service port name into
478     # the file args["ns_port_log_file"]
479     if args.has_key('ns_port_log_file'):
480       home = os.environ['HOME']
481       appli= os.environ.get("APPLI")
482       if appli is not None:
483         home = os.path.join(home, appli, "USERS")
484       file_name = os.path.join(home, args["ns_port_log_file"])
485       f = open(file_name, "w")
486       f.write(os.environ['NSPORT'])
487       f.close()
488
489     # Launch Logger Server (optional)
490     # and wait until it is registered in naming service
491     #
492
493     if args['logger']:
494         myServer=LoggerServer(args)
495         myServer.run()
496         clt.waitLogger("Logger")
497
498     # Notify Server launch
499     #
500
501     if sys.platform != "win32":
502       if verbose(): print "Notify Server to launch"
503     
504       myServer=NotifyServer(args,modules_root_dir)
505       myServer.run()
506
507     # Launch  Session Server (to show splash ASAP)
508     #
509
510     if args["gui"]:
511         mySessionServ = SessionServer(args,args['modules'],modules_root_dir)
512         mySessionServ.setpath(modules_list,modules_root_dir)
513         mySessionServ.run()
514
515     #
516     # Launch Registry Server,
517     # and wait until it is registered in naming service
518     #
519
520     if ('registry' not in args['embedded']) | (args["gui"] == 0) :
521         myServer=RegistryServer(args)
522         myServer.run()
523         if sys.platform == "win32":
524           clt.waitNS("/Registry")
525         else:
526           clt.waitNSPID("/Registry",myServer.PID)
527
528     #
529     # Launch Catalog Server,
530     # and wait until it is registered in naming service
531     #
532
533     if ('moduleCatalog' not in args['embedded']) | (args["gui"] == 0):
534         cataServer=CatalogServer(args)
535         cataServer.setpath(modules_list,modules_root_dir)
536         cataServer.run()
537         import SALOME_ModuleCatalog
538         if sys.platform == "win32":
539           clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
540         else:
541           clt.waitNSPID("/Kernel/ModulCatalog",cataServer.PID,SALOME_ModuleCatalog.ModuleCatalog)
542
543     #
544     # Launch SalomeDS Server,
545     # and wait until it is registered in naming service
546     #
547
548     #print "ARGS = ",args
549     if ('study' not in args['embedded']) | (args["gui"] == 0):
550         print "RunStudy"
551         myServer=SalomeDSServer(args)
552         myServer.run()
553         if sys.platform == "win32":
554           clt.waitNS("/myStudyManager")
555         else:
556           clt.waitNSPID("/myStudyManager",myServer.PID)
557
558     #
559     # Launch LauncherServer
560     #
561     
562     myCmServer = LauncherServer(args)
563     myCmServer.setpath(modules_list,modules_root_dir)
564     myCmServer.run()
565
566     #
567     # Launch ConnectionManagerServer
568     #
569
570     myConnectionServer = ConnectionManagerServer(args)
571     myConnectionServer.run()
572
573
574     from Utils_Identity import getShortHostName
575     
576     if os.getenv("HOSTNAME") == None:
577         if os.getenv("HOST") == None:
578             os.environ["HOSTNAME"]=getShortHostName()
579         else:
580             os.environ["HOSTNAME"]=os.getenv("HOST")
581
582     theComputer = getShortHostName()
583     
584     #
585     # Launch local C++ Container (FactoryServer),
586     # and wait until it is registered in naming service
587     #
588
589     if ('cppContainer' in args['standalone']) | (args["gui"] == 0) : 
590         myServer=ContainerCPPServer(args)
591         myServer.run()
592         if sys.platform == "win32":
593           clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
594         else:
595           clt.waitNSPID("/Containers/" + theComputer + "/FactoryServer",myServer.PID)
596
597     #
598     # Launch local Python Container (FactoryServerPy),
599     # and wait until it is registered in naming service
600     #
601
602     if 'pyContainer' in args['standalone']:
603         myServer=ContainerPYServer(args)
604         myServer.run()
605         if sys.platform == "win32":
606           clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy")
607         else:
608           clt.waitNSPID("/Containers/" + theComputer + "/FactoryServerPy",myServer.PID)
609
610     #
611     # Wait until Session Server is registered in naming service
612     #
613     
614     if args["gui"]:
615 ##----------------        
616         import Engines
617         import SALOME
618         import SALOMEDS
619         import SALOME_ModuleCatalog
620         import SALOME_Session_idl
621         if sys.platform == "win32":
622           session=clt.waitNS("/Kernel/Session",SALOME.Session)
623         else:
624           session=clt.waitNSPID("/Kernel/Session",mySessionServ.PID,SALOME.Session)
625         args["session_object"] = session
626     end_time = os.times()
627     if verbose(): print
628     print "Start SALOME, elapsed time : %5.1f seconds"% (end_time[4]
629                                                          - init_time[4])
630
631     # ASV start GUI without Loader
632     #if args['gui']:
633     #    session.GetInterface()
634
635     #
636     # additionnal external python interpreters
637     #
638     nbaddi=0
639     
640     try:
641         if 'interp' in args:
642             nbaddi = args['interp']
643     except:
644         import traceback
645         traceback.print_exc()
646         print "-------------------------------------------------------------"
647         print "-- to get an external python interpreter:runSalome --interp=1"
648         print "-------------------------------------------------------------"
649         
650     if verbose(): print "additional external python interpreters: ", nbaddi
651     if nbaddi:
652         for i in range(nbaddi):
653             print "i=",i
654             anInterp=InterpServer(args)
655             anInterp.run()
656
657     # set PYTHONINSPECT variable (python interpreter in interactive mode)
658     if args['pinter']:
659         os.environ["PYTHONINSPECT"]="1"
660         try:
661             import readline
662         except ImportError:
663             pass
664         
665     return clt
666
667 # -----------------------------------------------------------------------------
668
669 def useSalome(args, modules_list, modules_root_dir):
670     """
671     Launch all SALOME servers requested by args,
672     save list of process, give info to user,
673     show registered objects in Naming Service.
674     """
675     global process_id
676     
677     clt=None
678     try:
679         clt = startSalome(args, modules_list, modules_root_dir)
680     except:
681         import traceback
682         traceback.print_exc()
683         print
684         print
685         print "--- Error during Salome launch ---"
686         
687     #print process_id
688
689     from addToKillList import addToKillList
690     from killSalomeWithPort import getPiDict
691
692     filedict = getPiDict(args['port'])
693     for pid, cmd in process_id.items():
694         addToKillList(pid, cmd, args['port'])
695         pass
696
697     if verbose(): print """
698     Saving of the dictionary of Salome processes in %s
699     To kill SALOME processes from a console (kill all sessions from all ports):
700       python killSalome.py 
701     To kill SALOME from the present interpreter, if it is not closed :
702       killLocalPort()      --> kill this session
703                                (use CORBA port from args of runSalome)
704       givenPortKill(port)  --> kill a specific session with given CORBA port 
705       killAllPorts()       --> kill all sessions
706     
707     runSalome, with --killall option, starts with killing
708     the processes resulting from the previous execution.
709     """%filedict
710     
711     #
712     #  Print Naming Service directory list
713     #
714     
715     if clt != None:
716         if verbose():
717             print
718             print " --- registered objects tree in Naming Service ---"
719             clt.showNS()
720             pass
721         
722         if not args['gui'] or not args['session_gui']:
723             if args['shutdown_servers']:
724                 class __utils__(object):
725                     def __init__(self, port):
726                         self.port = port
727                         import killSalomeWithPort
728                         self.killSalomeWithPort = killSalomeWithPort
729                         return
730                     def __del__(self):
731                         self.killSalomeWithPort.killMyPort(self.port)
732                         return
733                     pass
734                 args['shutdown_servers'] = __utils__(args['port'])
735                 pass
736             pass
737         
738         # run python scripts, passed via --execute option
739         toimport = []
740         if args.has_key('pyscript'):
741             if args.has_key('gui') and args.has_key('session_gui'):
742                 if not args['gui'] or not args['session_gui']:
743                     toimport = args['pyscript']
744
745         for srcname in toimport :
746             if srcname == 'killall':
747                 clt.showNS()
748                 killAllPorts()
749                 sys.exit(0)
750             else:
751                 if os.path.isabs(srcname):
752                     if os.path.exists(srcname):
753                         execScript(srcname)
754                     elif os.path.exists(srcname+".py"):
755                         execScript(srcname+".py")
756                     else:
757                         print "Can't execute file %s" % srcname
758                     pass
759                 else:
760                     found = False
761                     for path in [os.getcwd()] + sys.path:
762                         if os.path.exists(os.path.join(path,srcname)):
763                             execScript(os.path.join(path,srcname))
764                             found = True
765                             break
766                         elif os.path.exists(os.path.join(path,srcname+".py")):
767                             execScript(os.path.join(path,srcname+".py"))
768                             found = True
769                             break
770                         pass
771                     if not found:
772                         print "Can't execute file %s" % srcname
773                         pass
774                     pass
775                 pass
776             pass
777         pass
778     return clt
779     
780 def execScript(script_path):
781     print 'executing', script_path
782     sys.path.insert(0, os.path.dirname(script_path))
783     execfile(script_path,globals())
784     del sys.path[0]
785
786 # -----------------------------------------------------------------------------
787
788 def registerEnv(args, modules_list, modules_root_dir):
789     """
790     Register args, modules_list, modules_root_dir in a file
791     for further use, when SALOME is launched embedded in an other application.
792     """
793     if sys.platform == "win32":
794       fileEnv = os.getenv('TEMP')
795     else:
796       fileEnv = '/tmp/'
797
798     fileEnv += os.getenv('USER') + "_" + str(args['port']) \
799             + '_' + args['appname'].upper() + '_env'
800     fenv=open(fileEnv,'w')
801     pickle.dump((args, modules_list, modules_root_dir),fenv)
802     fenv.close()
803     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
804
805 # -----------------------------------------------------------------------------
806
807 def searchFreePort(args, save_config=1):
808     print "Searching for a free port for naming service:",
809     #
810     if sys.platform == "win32":
811         tmp_file = os.getenv('TEMP');
812     else:
813         tmp_file = '/tmp'
814     tmp_file = os.path.join(tmp_file, '.netstat_%s'%os.getpid())
815     #
816     ###status = os.system("netstat -ltn | grep -E :%s > /dev/null 2>&1"%(NSPORT))
817     os.system( "netstat -a -n > %s" % tmp_file );
818     f = open( tmp_file, 'r' );
819     ports = f.readlines();
820     f.close();
821     os.remove( tmp_file );
822     #
823     def portIsUsed(port, data):
824         regObj = re.compile( ".*tcp.*:([0-9]+).*:.*listen", re.IGNORECASE );
825         for item in data:
826             try:
827                 p = int(regObj.match(item).group(1))
828                 if p == port: return True
829                 pass
830             except:
831                 pass
832             pass
833         return False
834     #
835     NSPORT=2810
836     limit=NSPORT+100
837     #
838     while 1:
839         if not portIsUsed(NSPORT, ports):
840             print "%s - OK"%(NSPORT)
841             #
842             from salome_utils import generateFileName, getHostName
843             hostname = getHostName()
844             #
845             home  = os.getenv("HOME")
846             appli = os.getenv("APPLI")
847             kwargs={}
848             if appli is not None: 
849               home = os.path.join(home, appli,"USERS")
850               kwargs["with_username"]=True
851             #
852             omniorb_config = generateFileName(home, prefix="omniORB",
853                                               extension="cfg",
854                                               hidden=True,
855                                               with_hostname=True,
856                                               with_port=NSPORT,
857                                               **kwargs)
858             orbdata = []
859             initref = "NameService=corbaname::%s:%s"%(hostname, NSPORT)
860             from omniORB import CORBA
861             if CORBA.ORB_ID == "omniORB4":
862                 orbdata.append("InitRef = %s"%(initref))
863                 orbdata.append("giopMaxMsgSize = 2097152000  # 2 GBytes")
864                 orbdata.append("traceLevel = 0 # critical errors only")
865             else:
866                 orbdata.append("ORBInitRef %s"%(initref))
867                 orbdata.append("ORBgiopMaxMsgSize = 2097152000  # 2 GBytes")
868                 orbdata.append("ORBtraceLevel = 0 # critical errors only")
869                 pass
870             orbdata.append("")
871             f = open(omniorb_config, "w")
872             f.write("\n".join(orbdata))
873             f.close()
874             #
875             os.environ['OMNIORB_CONFIG'] = omniorb_config
876             os.environ['NSPORT'] = "%s"%(NSPORT)
877             os.environ['NSHOST'] = "%s"%(hostname)
878             args['port'] = os.environ['NSPORT']
879             #
880             if save_config:
881                 last_running_config = generateFileName(home, prefix="omniORB",
882                                                        suffix="last",
883                                                        extension="cfg",
884                                                        hidden=True,
885                                                        **kwargs)
886                 try:
887                     if sys.platform == "win32":
888                         import shutil       
889                         shutil.copyfile(omniorb_config, last_running_config)
890                     else:
891                         try:
892                             os.remove(last_running_config)
893                         except OSError:
894                             pass
895                         os.symlink(omniorb_config, last_running_config)
896                         pass
897                     pass
898                 except:
899                     pass
900             break
901         print "%s"%(NSPORT),
902         if NSPORT == limit:
903             msg  = "\n"
904             msg += "Can't find a free port to launch omniNames\n"
905             msg += "Try to kill the running servers and then launch SALOME again.\n"
906             raise RuntimeError, msg
907         NSPORT=NSPORT+1
908         pass
909     return
910     
911 # -----------------------------------------------------------------------------
912
913 def no_main():
914     """Salome Launch, when embedded in other application"""
915     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
916     fenv=open(fileEnv,'r')
917     args, modules_list, modules_root_dir = pickle.load(fenv)
918     fenv.close()
919     kill_salome(args)
920     searchFreePort(args, 0)
921     clt = useSalome(args, modules_list, modules_root_dir)
922     return clt
923
924 # -----------------------------------------------------------------------------
925
926 def main():
927     """Salome launch as a main application"""
928     from salome_utils import getHostName
929     print "runSalome running on %s" % getHostName()
930     args, modules_list, modules_root_dir = setenv.get_config()
931     kill_salome(args)
932     save_config = True
933     if args.has_key('save_config'):
934         save_config = args['save_config']
935     # --
936     test = True
937     if args['wake_up_session']:
938         test = False
939         pass
940     if test:
941         searchFreePort(args, save_config)
942         pass
943     # --
944     #setenv.main()
945     setenv.set_env(args, modules_list, modules_root_dir)
946     clt = useSalome(args, modules_list, modules_root_dir)
947     return clt,args
948
949 # -----------------------------------------------------------------------------
950
951 def foreGround(clt, args):
952     # --
953     if "session_object" not in args:
954         return
955     session = args["session_object"]
956     # --
957     # Wait until gui is arrived
958     # tmax = nbtot * dt
959     # --
960     gui_detected = False
961     dt = 0.1
962     nbtot = 100
963     nb = 0
964     while 1:
965         try:
966             status = session.GetStatSession()
967             gui_detected = status.activeGUI
968         except:
969             pass
970         if gui_detected:
971             break
972         from time import sleep
973         sleep(dt)
974         nb += 1
975         if nb == nbtot:
976             break
977         pass
978     # --
979     if not gui_detected:
980         return
981     # --
982     from salome_utils import getPortNumber
983     port = getPortNumber()
984     # --
985     server = Server({})
986     if sys.platform == "win32":
987       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(os.getpid()), "%s"%(port)]
988     else:
989       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(os.getpid()), "%s"%(port)]
990     server.run()   
991     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
992     # --
993     dt = 1.0
994     try:
995         while 1:
996             try:
997                 status = session.GetStatSession()
998                 assert status.activeGUI
999             except:
1000                 break
1001             from time import sleep
1002             sleep(dt)
1003             pass
1004         pass
1005     except KeyboardInterrupt:
1006         from killSalomeWithPort import killMyPort
1007         killMyPort(port)
1008         pass
1009     return
1010
1011 # -----------------------------------------------------------------------------
1012
1013 if __name__ == "__main__":
1014     import user
1015     clt,args = main()
1016     # --
1017     test = args['gui'] and args['session_gui']
1018     test = test or args['wake_up_session']
1019     # --
1020     # The next test covers the --pinter option or var PYTHONINSPECT setted
1021     # --
1022     test = test and not os.environ.get('PYTHONINSPECT')
1023     # --
1024     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
1025     # --
1026     try:
1027         from ctypes import POINTER, c_int, cast, pythonapi
1028         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
1029         test = test and not iflag_ptr.contents.value
1030     except:
1031         pass
1032     # --
1033     test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
1034     test = test and args['foreground']
1035     # --
1036     if test:
1037         foreGround(clt, args)
1038         pass
1039     # --
1040     pass