Salome HOME
Bug fix: running scripts in embedded python console
[modules/yacs.git] / bin / runSalome.py
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2014  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
227         if sys.platform == "win32": dirpath = os.environ["HOME"]
228         else:                       dirpath = "/tmp"
229         logfile = generateFileName( dirpath,
230                                     prefix="logger",
231                                     extension="log",
232                                     with_username=True,
233                                     with_hostname=True,
234                                     with_port=True)
235         print "==========================================================="
236         print "Logger server: put log to the file:"
237         print logfile
238         print "==========================================================="
239         self.CMD=['SALOME_Logger_Server', logfile]
240         pass
241     pass # end of LoggerServer class
242
243 # ---
244
245 class SessionServer(Server):
246     def __init__(self,args,modules_list,modules_root_dir):
247         self.args = args.copy()
248         # Bug 11512 (Problems with runSalome --xterm on Mandrake and Debian Sarge)
249         #self.args['xterm']=0
250         #
251         self.initArgs()
252         self.SCMD1=['SALOME_Session_Server']
253         self.SCMD2=[]
254         if 'registry' in self.args['embedded']:
255             self.SCMD1+=['--with','Registry',
256                          '(','--salome_session','theSession',')']
257         if 'moduleCatalog' in self.args['embedded']:
258             self.SCMD1+=['--with','ModuleCatalog','(','-common']
259             home_dir=os.getenv('HOME')
260             if home_dir is not None:
261                 self.SCMD2+=['-personal',os.path.join(home_dir,'Salome/resources/CatalogModulePersonnel.xml')]
262             self.SCMD2+=[')']
263         if 'study' in self.args['embedded']:
264             self.SCMD2+=['--with','SALOMEDS','(',')']
265         if 'cppContainer' in self.args['embedded']:
266             self.SCMD2+=['--with','Container','(','FactoryServer',')']
267         if 'SalomeAppEngine' in self.args['embedded']:
268             self.SCMD2+=['--with','SalomeAppEngine','(',')']
269
270         if 'cppContainer' in self.args['standalone'] or 'cppContainer' in self.args['embedded']:
271             self.SCMD2+=['CPP']
272         if 'pyContainer' in self.args['standalone'] or 'pyContainer' in self.args['embedded']:
273             raise Exception('Python containers no longer supported')
274         if self.args['gui']:
275             session_gui = True
276             if self.args.has_key('session_gui'):
277                 session_gui = self.args['session_gui']
278             if session_gui:
279                 self.SCMD2+=['GUI']
280                 if self.args['splash']:
281                     self.SCMD2+=['SPLASH']
282                     pass
283                 if self.args['study_hdf'] is not None:
284                     self.SCMD2+=['--study-hdf=%s'%self.args['study_hdf']]
285                     pass
286                 if simanStudyName(self.args):
287                     self.SCMD2+=['--siman-study=%s'%simanStudyName(self.args)]
288                     pass
289                 pass
290                 if self.args.has_key('pyscript') and len(self.args['pyscript']) > 0:
291                     msg = json.dumps(self.args['pyscript'], cls=ScriptAndArgsObjectEncoder)
292                     self.SCMD2+=['--pyscript=%s'%(msg)]
293                     pass
294                 pass
295             pass
296         if self.args['noexcepthandler']:
297             self.SCMD2+=['noexcepthandler']
298         if self.args.has_key('user_config'):
299             self.SCMD2+=['--resources=%s'%self.args['user_config']]
300         if self.args.has_key('modules'):
301             list_modules = []
302             #keep only modules with GUI
303             for m in modules_list:
304               if m not in modules_root_dir:
305                 list_modules.insert(0,m)
306               else:
307                 fr1 = os.path.join(modules_root_dir[m],"share","salome","resources",m.lower(),"SalomeApp.xml")
308                 fr2 = os.path.join(modules_root_dir[m],"share","salome","resources","SalomeApp.xml")
309                 if os.path.exists(fr1) or os.path.exists(fr2):
310                   list_modules.insert(0,m)
311             list_modules.reverse()
312             self.SCMD2+=['--modules (%s)' % ":".join(list_modules)]
313             pass
314         pass
315
316     def setpath(self,modules_list,modules_root_dir):
317         list_modules = modules_list[:]
318         list_modules.reverse()
319         if self.args["gui"] :
320             list_modules = ["KERNEL", "GUI"] + list_modules
321         else :
322             list_modules = ["KERNEL"] + list_modules
323
324         cata_path=get_cata_path(list_modules,modules_root_dir)
325
326         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
327             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
328             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
329         else:
330             self.CMD=self.SCMD1 + self.SCMD2
331         if self.args.has_key('test'):
332             self.CMD+=['-test'] + self.args['test']
333         elif self.args.has_key('play'):
334             self.CMD+=['-play'] + self.args['play']
335
336         if self.args["gdb_session"] or self.args["ddd_session"]:
337             f = open(".gdbinit4salome", "w")
338             f.write("set args ")
339             args = " ".join(self.CMD[1:])
340             args = args.replace("(", "\(")
341             args = args.replace(")", "\)")
342             f.write(args)
343             f.write("\n")
344             f.close()
345             if self.args["ddd_session"]:
346                 self.CMD = ["ddd", "--command=.gdbinit4salome", self.CMD[0]]
347             elif self.args["gdb_session"]:
348                 self.CMD = ["xterm", "-e", "gdb", "--command=.gdbinit4salome", self.CMD[0]]
349                 pass
350             pass
351
352         if self.args["valgrind_session"]:
353             l = ["valgrind"]
354             val = os.getenv("VALGRIND_OPTIONS")
355             if val:
356                 l += val.split()
357                 pass
358             self.CMD = l + self.CMD
359             pass
360
361 # ---
362
363 class LauncherServer(Server):
364     def __init__(self,args):
365         self.args=args
366         self.initArgs()
367         self.SCMD1=['SALOME_LauncherServer']
368         self.SCMD2=[]
369         if args["gui"] :
370             if 'registry' in self.args['embedded']:
371                 self.SCMD1+=['--with','Registry',
372                              '(','--salome_session','theSession',')']
373             if 'moduleCatalog' in self.args['embedded']:
374                 self.SCMD1+=['--with','ModuleCatalog','(','-common']
375                 self.SCMD2+=['-personal',
376                              '${HOME}/Salome/resources/CatalogModulePersonnel.xml',')']
377             if 'study' in self.args['embedded']:
378                 self.SCMD2+=['--with','SALOMEDS','(',')']
379             if 'cppContainer' in self.args['embedded']:
380                 self.SCMD2+=['--with','Container','(','FactoryServer',')']
381
382     def setpath(self,modules_list,modules_root_dir):
383         list_modules = modules_list[:]
384         list_modules.reverse()
385         if self.args["gui"] :
386             list_modules = ["KERNEL", "GUI"] + list_modules
387         else :
388             list_modules = ["KERNEL"] + list_modules
389
390         cata_path=get_cata_path(list_modules,modules_root_dir)
391
392         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
393             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
394             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
395         else:
396             self.CMD=self.SCMD1 + self.SCMD2
397 #
398 # -----------------------------------------------------------------------------
399
400 def startGUI(clt):
401     """Salome Session Graphic User Interface activation"""
402     import Engines
403     import SALOME
404     import SALOMEDS
405     import SALOME_ModuleCatalog
406     import SALOME_Session_idl
407     session=clt.waitNS("/Kernel/Session",SALOME.Session)
408     session.GetInterface()
409
410 # -----------------------------------------------------------------------------
411
412 def startSalome(args, modules_list, modules_root_dir):
413     """Launch all SALOME servers requested by args"""
414     init_time = os.times()
415
416     if verbose(): print "startSalome ", args
417
418     #
419     # Set server launch command
420     #
421     if args.has_key('server_launch_mode'):
422         Server.set_server_launch_mode(args['server_launch_mode'])
423
424     #
425     # Wake up session option
426     #
427     if args['wake_up_session']:
428         if "OMNIORB_CONFIG" not in os.environ:
429             from salome_utils import generateFileName
430             omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
431             kwargs={}
432             if omniorbUserPath is not None:
433                 kwargs["with_username"]=True
434
435             last_running_config = generateFileName(omniorbUserPath, prefix="omniORB",
436                                                    suffix="last",
437                                                    extension="cfg",
438                                                    hidden=True,
439                                                    **kwargs)
440             os.environ['OMNIORB_CONFIG'] = last_running_config
441             pass
442         pass
443
444     #
445     # Initialisation ORB and Naming Service
446     #
447
448     clt=orbmodule.client(args)
449
450     #
451     # Wake up session option
452     #
453     if args['wake_up_session']:
454         import Engines
455         import SALOME
456         import SALOMEDS
457         import SALOME_ModuleCatalog
458         import SALOME_Session_idl
459         session = clt.waitNS("/Kernel/Session",SALOME.Session)
460         status = session.GetStatSession()
461         if status.activeGUI:
462             from salome_utils import getPortNumber
463             port = getPortNumber()
464             msg  = "Warning :"
465             msg += "\n"
466             msg += "Session GUI for port number %s is already active."%(port)
467             msg += "\n"
468             msg += "If you which to wake up another session,"
469             msg += "\n"
470             msg += "please use variable OMNIORB_CONFIG"
471             msg += "\n"
472             msg += "to get the correct session object in naming service."
473             sys.stdout.write(msg+"\n")
474             sys.stdout.flush()
475             return clt
476         session.GetInterface()
477         args["session_object"] = session
478         return clt
479
480     # Launch Logger Server (optional)
481     # and wait until it is registered in naming service
482     #
483
484     if args['logger']:
485         myServer=LoggerServer(args)
486         myServer.run()
487         clt.waitLogger("Logger")
488
489     # set siman python path before the session server launching to import scripts inside python console
490     if simanStudyName(args):
491         # MPV: use os.environ here because session server is launched in separated process and sys.path is missed in this case
492         os.environ["PYTHONPATH"] = "/tmp/SimanSalome/" + args['siman_study'] + "/" + \
493                                    args['siman_scenario'] + "/" + args['siman_user'] + 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.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     if sys.platform == "win32":
775       fileEnv = os.getenv('TEMP')
776     else:
777       fileEnv = '/tmp/'
778
779     fileEnv += os.getenv('USER') + "_" + str(args['port']) \
780             + '_' + args['appname'].upper() + '_env'
781     fenv=open(fileEnv,'w')
782     pickle.dump((args, modules_list, modules_root_dir),fenv)
783     fenv.close()
784     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
785
786 # -----------------------------------------------------------------------------
787
788 def no_main():
789     """Salome Launch, when embedded in other application"""
790     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
791     fenv=open(fileEnv,'r')
792     args, modules_list, modules_root_dir = pickle.load(fenv)
793     fenv.close()
794     kill_salome(args)
795     from searchFreePort import searchFreePort
796     searchFreePort(args, 0)
797     clt = useSalome(args, modules_list, modules_root_dir)
798     return clt
799
800 # -----------------------------------------------------------------------------
801
802 def main():
803     """Salome launch as a main application"""
804
805     # define folder to store omniorb config (initially in virtual application folder)
806     try:
807         from salomeContextUtils import setOmniOrbUserPath
808         setOmniOrbUserPath()
809     except Exception, e:
810         print e
811         sys.exit(1)
812
813     from salome_utils import getHostName
814     args, modules_list, modules_root_dir = setenv.get_config()
815     print "runSalome running on %s" % getHostName()
816
817     kill_salome(args)
818     save_config = True
819     if args.has_key('save_config'):
820         save_config = args['save_config']
821     # --
822     test = True
823     if args['wake_up_session']:
824         test = False
825         pass
826     if test:
827         from searchFreePort import searchFreePort
828         searchFreePort(args, save_config, args.get('useport'))
829         pass
830     # --
831     #setenv.main()
832     setenv.set_env(args, modules_list, modules_root_dir)
833     clt = useSalome(args, modules_list, modules_root_dir)
834     return clt,args
835
836 # -----------------------------------------------------------------------------
837
838 def foreGround(clt, args):
839     # --
840     if "session_object" not in args:
841         return
842     session = args["session_object"]
843     # --
844     # Wait until gui is arrived
845     # tmax = nbtot * dt
846     # --
847     gui_detected = False
848     dt = 0.1
849     nbtot = 100
850     nb = 0
851     while 1:
852         try:
853             status = session.GetStatSession()
854             gui_detected = status.activeGUI
855         except:
856             pass
857         if gui_detected:
858             break
859         from time import sleep
860         sleep(dt)
861         nb += 1
862         if nb == nbtot:
863             break
864         pass
865     # --
866     if not gui_detected:
867         return
868     # --
869     from salome_utils import getPortNumber
870     port = getPortNumber()
871     # --
872     server = Server({})
873     if sys.platform == "win32":
874       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(os.getpid()), "%s"%(port)]
875     else:
876       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(os.getpid()), "%s"%(port)]
877     server.run()
878     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
879     # --
880     dt = 1.0
881     try:
882         while 1:
883             try:
884                 status = session.GetStatSession()
885                 assert status.activeGUI
886             except:
887                 break
888             from time import sleep
889             sleep(dt)
890             pass
891         pass
892     except KeyboardInterrupt:
893         from killSalomeWithPort import killMyPort
894         killMyPort(port)
895         pass
896     return
897 #
898
899 def runSalome():
900     import user
901     clt,args = main()
902     # --
903     test = args['gui'] and args['session_gui']
904     test = test or args['wake_up_session']
905     # --
906     # The next test covers the --pinter option or var PYTHONINSPECT setted
907     # --
908     test = test and not os.environ.get('PYTHONINSPECT')
909     # --
910     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
911     # --
912     try:
913         from ctypes import POINTER, c_int, cast, pythonapi
914         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
915         test = test and not iflag_ptr.contents.value
916     except:
917         pass
918     # --
919     test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
920     test = test and args['foreground']
921     # --
922     if test:
923         foreGround(clt, args)
924         pass
925     pass
926 #
927
928 # -----------------------------------------------------------------------------
929
930 if __name__ == "__main__":
931     runSalome()
932 #