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