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