Salome HOME
Win32: remove obsolete win32pm implementation
[modules/kernel.git] / bin / killSalomeWithPort.py
index c28fba52a5496365830c1e955a234bfa4ab6f992..95497f0dbefe80091c4591fdd648211e5516122e 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/env python
 #  -*- coding: iso-8859-1 -*-
 #! /usr/bin/env python
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #
 
 import os, sys, pickle, signal, commands,glob
 #
 
 import os, sys, pickle, signal, commands,glob
+import subprocess
+import shlex
 from salome_utils import verbose
 from salome_utils import verbose
-import salome_utils
 
 
-def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with2809pid=False):
+
+def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None):
     """
     Get file with list of SALOME processes.
     This file is located in the user's home directory
     """
     Get file with list of SALOME processes.
     This file is located in the user's home directory
@@ -52,7 +54,14 @@ def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with280
     - hidden  : if True, file name is prefixed with . (dot) symbol; this internal parameter is used
     to support compatibility with older versions of SALOME
     """
     - hidden  : if True, file name is prefixed with . (dot) symbol; this internal parameter is used
     to support compatibility with older versions of SALOME
     """
-    from salome_utils import generateFileName, getTmpDir
+    # bug fix: ensure port is an integer
+    # Note: this function is also called with port='#####' !!!
+    try:
+        port = int(port)
+    except:
+        pass
+
+    from salome_utils import generateFileName, getLogDir
     dir = ""
     if not hostname:
         hostname = os.getenv("NSHOST")
     dir = ""
     if not hostname:
         hostname = os.getenv("NSHOST")
@@ -63,7 +72,7 @@ def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with280
         if hidden:
             # new-style dot-prefixed pidict files
             # are in the system-dependant temporary diretory
         if hidden:
             # new-style dot-prefixed pidict files
             # are in the system-dependant temporary diretory
-            dir = getTmpDir()
+            dir = getLogDir()
         else:
             # old-style non-dot-prefixed pidict files
             # are in the user's home directory
         else:
             # old-style non-dot-prefixed pidict files
             # are in the user's home directory
@@ -71,11 +80,8 @@ def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with280
             pass
         pass
 
             pass
         pass
 
-    suffix = "pidict"
-    if port == 2809 and with2809pid:
-        suffix = suffix + "-%s"%(os.getpid())
     return generateFileName(dir,
     return generateFileName(dir,
-                            suffix=suffix,
+                            suffix="pidict",
                             hidden=hidden,
                             with_username=True,
                             with_hostname=hostname or True,
                             hidden=hidden,
                             with_username=True,
                             with_hostname=hostname or True,
@@ -89,6 +95,9 @@ def appliCleanOmniOrbConfig(port):
     - ${OMNIORB_USER_PATH}/.omniORB_${USER}_last.cfg
     the last is removed only if the link points to the first file.
     """
     - ${OMNIORB_USER_PATH}/.omniORB_${USER}_last.cfg
     the last is removed only if the link points to the first file.
     """
+    if verbose():
+        print "clean OmniOrb config for port %s"%port
+
     from salome_utils import generateFileName, getUserName
     omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
     if omniorbUserPath is None:
     from salome_utils import generateFileName, getUserName
     omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
     if omniorbUserPath is None:
@@ -157,6 +166,8 @@ def shutdownMyPort(port, cleanup=True):
     - port - port number
     """
     if not port: return
     - port - port number
     """
     if not port: return
+    # bug fix: ensure port is an integer
+    port = int(port)
 
     try:
         from PortManager import releasePort
 
     try:
         from PortManager import releasePort
@@ -186,14 +197,16 @@ def shutdownMyPort(port, cleanup=True):
     try:
         import time
         from omniORB import CORBA
     try:
         import time
         from omniORB import CORBA
+
         from LifeCycleCORBA import LifeCycleCORBA
         # shutdown all
         orb = CORBA.ORB_init([''], CORBA.ORB_ID)
         from LifeCycleCORBA import LifeCycleCORBA
         # shutdown all
         orb = CORBA.ORB_init([''], CORBA.ORB_ID)
-        lcc = LifeCycleCORBA(orb)
+        lcc = LifeCycleCORBA(orb) # see (1)
+        print "Terminating SALOME on port %s..."%(port)
         lcc.shutdownServers()
         # give some time to shutdown to complete
         time.sleep(1)
         lcc.shutdownServers()
         # give some time to shutdown to complete
         time.sleep(1)
-        # shutdown omniNames and notifd
+        # shutdown omniNames
         if cleanup:
             lcc.killOmniNames()
             time.sleep(1)
         if cleanup:
             lcc.killOmniNames()
             time.sleep(1)
@@ -201,26 +214,31 @@ def shutdownMyPort(port, cleanup=True):
         pass
     except:
         pass
         pass
     except:
         pass
+    exit(0) # see (1)
     pass
     pass
+# (1) If --shutdown-servers option is set to 1, session close procedure is
+# called twice: first explicitely by salome command, second by automatic
+# atexit to handle Ctrl-C. During second call, LCC does not exist anymore and
+# a RuntimeError is raised; we explicitely exit this function with code 0 to
+# prevent parent thread from crashing.
 
 def __killMyPort(port, filedict):
 
 def __killMyPort(port, filedict):
+    # bug fix: ensure port is an integer
+    if port:
+        port = int(port)
+
     try:
         with open(filedict, 'r') as fpid:
             #
     try:
         with open(filedict, 'r') as fpid:
             #
-            from salome_utils import generateFileName
-            if sys.platform == "win32":
-                username = os.getenv( "USERNAME" )
-            else:
-                username = os.getenv('USER')
-            path = os.path.join('/tmp/logs', username)
-            fpidomniNames = generateFileName(path,
+            from salome_utils import generateFileName, getLogDir
+            fpidomniNames = generateFileName(getLogDir(),
                                              prefix="",
                                              suffix="Pid_omniNames",
                                              extension="log",
                                              with_port=port)
             if not sys.platform == 'win32':
                                              prefix="",
                                              suffix="Pid_omniNames",
                                              extension="log",
                                              with_port=port)
             if not sys.platform == 'win32':
-                cmd = 'pid=`ps -eo pid,command | egrep "[0-9] omniNames -start %s"` ; echo $pid > %s' % ( str(port), fpidomniNames )
-                a = os.system(cmd)
+                cmd = 'pid=$(ps -eo pid,command | egrep "[0-9] omniNames -start {0}") ; echo $pid > {1}'.format(port, fpidomniNames )
+                subprocess.call(cmd, shell=True)
                 pass
             try:
                 with open(fpidomniNames) as fpidomniNamesFile:
                 pass
             try:
                 with open(fpidomniNames) as fpidomniNamesFile:
@@ -230,12 +248,11 @@ def __killMyPort(port, filedict):
                 for l in lines:
                     try:
                         pidfield = l.split()[0] # pid should be at the first position
                 for l in lines:
                     try:
                         pidfield = l.split()[0] # pid should be at the first position
+                        if verbose(): print 'stop process '+pidfield+' : omniNames'
                         if sys.platform == "win32":
                         if sys.platform == "win32":
-                            import win32pm
-                            if verbose(): print 'stop process '+pidfield+' : omniNames'
-                            win32pm.killpid(int(pidfield),0)
+                            from salome_utils import win32killpid
+                            win32killpid(int(pidfield))
                         else:
                         else:
-                            if verbose(): print 'stop process '+pidfield+' : omniNames'
                             os.kill(int(pidfield),signal.SIGKILL)
                             pass
                         pass
                             os.kill(int(pidfield),signal.SIGKILL)
                             pass
                         pass
@@ -251,10 +268,35 @@ def __killMyPort(port, filedict):
                 for process_id in process_ids:
                     for pid, cmd in process_id.items():
                         if verbose(): print "stop process %s : %s"% (pid, cmd[0])
                 for process_id in process_ids:
                     for pid, cmd in process_id.items():
                         if verbose(): print "stop process %s : %s"% (pid, cmd[0])
+                        if cmd[0] == "omniNames":
+                            if not sys.platform == 'win32':
+                                proc1 = subprocess.Popen(shlex.split('ps -eo pid,command'),stdout=subprocess.PIPE)
+                                proc2 = subprocess.Popen(shlex.split('egrep "[0-9] omniNames -start"'),stdin=proc1.stdout, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+                                proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
+                                out,_ = proc2.communicate()
+                                # out looks like: PID omniNames -start PORT <other args>
+
+                                # extract omninames pid and port number
+                                try:
+                                    import re
+                                    omniNamesPid, omniNamesPort = re.search('(.+?) omniNames -start (.+?) ', out).group(1, 2)
+                                    if omniNamesPort == port:
+                                        if verbose():
+                                            print "stop omniNames [pid=%s] on port %s"%(omniNamesPid, omniNamesPort)
+                                        appliCleanOmniOrbConfig(omniNamesPort)
+                                        from PortManager import releasePort
+                                        releasePort(omniNamesPort)
+                                        os.kill(int(omniNamesPid),signal.SIGKILL)
+                                except (ImportError, AttributeError, OSError):
+                                    pass
+                                except:
+                                    import traceback
+                                    traceback.print_exc()
+
                         try:
                             if sys.platform == "win32":
                         try:
                             if sys.platform == "win32":
-                                import win32pm
-                                win32pm.killpid(int(pid),0)
+                                from salome_utils import win32killpid
+                                win32killpid(int(pid))
                             else:
                                 os.kill(int(pid),signal.SIGKILL)
                                 pass
                             else:
                                 os.kill(int(pid),signal.SIGKILL)
                                 pass
@@ -271,6 +313,7 @@ def __killMyPort(port, filedict):
         #
         os.remove(filedict)
         cmd='ps -eo pid,command | egrep "[0-9] omniNames -start '+str(port)+'" | sed -e "s%[^0-9]*\([0-9]*\) .*%\\1%g"'
         #
         os.remove(filedict)
         cmd='ps -eo pid,command | egrep "[0-9] omniNames -start '+str(port)+'" | sed -e "s%[^0-9]*\([0-9]*\) .*%\\1%g"'
+#        pid = subprocess.check_output(shlex.split(cmd))
         pid = commands.getoutput(cmd)
         a = ""
         while pid and len(a.split()) < 2:
         pid = commands.getoutput(cmd)
         a = ""
         while pid and len(a.split()) < 2:
@@ -284,14 +327,65 @@ def __killMyPort(port, filedict):
     #
 #
 
     #
 #
 
+def __guessPiDictFilename(port):
+    from salome_utils import getShortHostName, getHostName
+    filedicts = [
+        # new-style dot-prefixed pidict file
+        getPiDict(port, hidden=True),
+        # provide compatibility with old-style pidict file (not dot-prefixed)
+        getPiDict(port, hidden=False),
+        # provide compatibility with old-style pidict file (short hostname)
+        getPiDict(port, hidden=True, hostname=getShortHostName()),
+        # provide compatibility with old-style pidict file (not dot-prefixed, short hostname
+        getPiDict(port, hidden=False, hostname=getShortHostName()),
+        # provide compatibility with old-style pidict file (long hostname)
+        getPiDict(port, hidden=True, hostname=getHostName()),
+        # provide compatibility with old-style pidict file (not dot-prefixed, long hostname)
+        getPiDict(port, hidden=False, hostname=getHostName())
+        ]
+
+    log_msg = ""
+    for filedict in filedicts:
+        log_msg += "Trying %s..."%filedict
+        if os.path.exists(filedict):
+            log_msg += "   ... OK\n"
+            break
+        else:
+            log_msg += "   ... not found\n"
+
+    if verbose():
+        print log_msg
+
+    return filedict
+#
+
 def killMyPort(port):
     """
     Kill SALOME session running on the specified port.
     Parameters:
     - port - port number
     """
 def killMyPort(port):
     """
     Kill SALOME session running on the specified port.
     Parameters:
     - port - port number
     """
-    from salome_utils import getShortHostName, getHostName
-    print "Terminating SALOME on port %s..."%(port)
+    # bug fix: ensure port is an integer
+    if port:
+        port = int(port)
+
+    try:
+        import PortManager # do not remove! Test for PortManager availability!
+        filedict = getPiDict(port)
+        if not os.path.isfile(filedict): # removed by previous call, see (1)
+            if verbose():
+                print "SALOME on port %s: already removed by previous call"%port
+            # Remove port from PortManager config file
+            try:
+                from PortManager import releasePort
+                if verbose():
+                    print "Removing port from PortManager configuration file"
+                releasePort(port)
+            except ImportError:
+                pass
+            return
+    except:
+        pass
 
     # try to shutdown session normally
     import threading, time
 
     # try to shutdown session normally
     import threading, time
@@ -299,45 +393,33 @@ def killMyPort(port):
     time.sleep(3) # wait a little, then kill processes (should be done if shutdown procedure hangs up)
 
     try:
     time.sleep(3) # wait a little, then kill processes (should be done if shutdown procedure hangs up)
 
     try:
-        import PortManager
-        filedict = getPiDict(port, hidden=True, with2809pid=False)
+        import PortManager # do not remove! Test for PortManager availability!
+        filedict = getPiDict(port)
+        #filedict = __guessPiDictFilename(port)
         import glob
         all_files = glob.glob("%s*"%filedict)
         for f in all_files:
             __killMyPort(port, f)
     except ImportError:
         import glob
         all_files = glob.glob("%s*"%filedict)
         for f in all_files:
             __killMyPort(port, f)
     except ImportError:
-        # new-style dot-prefixed pidict file
-        filedict = getPiDict(port, hidden=True)
-        # provide compatibility with old-style pidict file (not dot-prefixed)
-        if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False)
-        # provide compatibility with old-style pidict file (short hostname)
-        if not os.path.exists(filedict): filedict = getPiDict(port, hidden=True,  hostname=getShortHostName())
-        # provide compatibility with old-style pidict file (not dot-prefixed, short hostname)
-        if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False, hostname=getShortHostName())
-        # provide compatibility with old-style pidict file (long hostname)
-        if not os.path.exists(filedict): filedict = getPiDict(port, hidden=True,  hostname=getHostName())
-        # provide compatibility with old-style pidict file (not dot-prefixed, long hostname)
-        if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False, hostname=getHostName())
+        filedict = __guessPiDictFilename(port)
         __killMyPort(port, filedict)
     #
         __killMyPort(port, filedict)
     #
+
     appliCleanOmniOrbConfig(port)
     pass
 
     appliCleanOmniOrbConfig(port)
     pass
 
-def killNotifdAndClean(port):
+def cleanApplication(port):
     """
     """
-    Kill notifd daemon and clean application running on the specified port.
+    Clean application running on the specified port.
     Parameters:
     - port - port number
     """
     Parameters:
     - port - port number
     """
+    # bug fix: ensure port is an integer
+    if port:
+        port = int(port)
+
     try:
         filedict=getPiDict(port)
     try:
         filedict=getPiDict(port)
-        with open(filedict, 'r') as f:
-            pids=pickle.load(f)
-            for d in pids:
-                for pid,process in d.items():
-                    if 'notifd' in process:
-                        cmd='kill -9 %d'% pid
-                        os.system(cmd)
         os.remove(filedict)
     except:
       #import traceback
         os.remove(filedict)
     except:
       #import traceback
@@ -350,8 +432,8 @@ def killMyPortSpy(pid, port):
     dt = 1.0
     while 1:
         if sys.platform == "win32":
     dt = 1.0
     while 1:
         if sys.platform == "win32":
-            from win32pm import killpid
-            if killpid(int(pid), 0) != 0:
+            from salome_utils import win32killpid
+            if win32killpid(int(pid)) != 0:
                 return
         else:
             from os import kill
                 return
         else:
             from os import kill
@@ -373,7 +455,7 @@ def killMyPortSpy(pid, port):
         orb = omniORB.CORBA.ORB_init(sys.argv, omniORB.CORBA.ORB_ID)
         import SALOME_NamingServicePy
         ns = SALOME_NamingServicePy.SALOME_NamingServicePy_i(orb)
         orb = omniORB.CORBA.ORB_init(sys.argv, omniORB.CORBA.ORB_ID)
         import SALOME_NamingServicePy
         ns = SALOME_NamingServicePy.SALOME_NamingServicePy_i(orb)
-        import SALOME
+        import SALOME #@UnresolvedImport @UnusedImport
         session = ns.Resolve("/Kernel/Session")
         assert session
     except:
         session = ns.Resolve("/Kernel/Session")
         assert session
     except:
@@ -408,7 +490,7 @@ if __name__ == "__main__":
         sys.exit(0)
         pass
     try:
         sys.exit(0)
         pass
     try:
-        from salomeLauncherUtils import setOmniOrbUserPath
+        from salomeContextUtils import setOmniOrbUserPath #@UnresolvedImport
         setOmniOrbUserPath()
     except Exception, e:
         print e
         setOmniOrbUserPath()
     except Exception, e:
         print e