Salome HOME
Port manager's lock file should be created with proper permissions; we must use umask...
[modules/kernel.git] / bin / searchFreePort.py
old mode 100644 (file)
new mode 100755 (executable)
index 4b5d0ca..3240663
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2013  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
@@ -8,7 +8,7 @@
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
-# version 2.1 of the License.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -45,7 +45,7 @@ def __setup_config(nsport, args, save_config):
                                            extension="cfg",
                                            hidden=True,
                                            **kwargs)
-    #os.environ['LAST_RUNNING_CONFIG'] = last_running_config
+    os.environ['LAST_RUNNING_CONFIG'] = last_running_config
     try:
       if sys.platform == "win32":
         import shutil
@@ -64,35 +64,128 @@ def __setup_config(nsport, args, save_config):
   #
 #
 
-def searchFreePort(args={}, save_config=1, use_port=None):
-  """
-  Search free port for SALOME session.
-  Returns first found free port number.
-  """
+def searchFreePort_withoutPortManager(args={}, save_config=1, use_port=None):
+  # :NOTE: Under windows:
+  #        netstat options -l and -t are unavailable
+  #        grep command is unavailable
+  from subprocess import Popen, PIPE
+  (stdout, stderr) = Popen(['netstat','-an'], stdout=PIPE).communicate()
+  import StringIO
+  buf = StringIO.StringIO(stdout)
+  ports = buf.readlines()
+
+  #
+  def portIsUsed(port, data):
+    import re
+    regObj = re.compile( ".*tcp.*:([0-9]+).*:.*listen", re.IGNORECASE );
+    for item in data:
+      try:
+        p = int(regObj.match(item).group(1))
+        if p == port: return True
+        pass
+      except:
+        pass
+      pass
+    return False
+  #
+
+  if use_port:
+    print "Check if port can be used: %d" % use_port,
+    if not portIsUsed(use_port, ports):
+      print "- OK"
+      __setup_config(use_port, args, save_config)
+      return
+    else:
+      print "- KO: port is busy"
+    pass
+  #
+
+  print "Searching for a free port for naming service:",
+  #
+
+  NSPORT=2810
+  limit=NSPORT+100
+  #
 
-  #import PortManager
-  #client = PortManager.start_client() # :NOTE: might specify a (remote) IP
-  #portManager = client.PortManager()
+  while 1:
+    if not portIsUsed(NSPORT, ports):
+      print "%s - OK"%(NSPORT)
+      __setup_config(NSPORT, args, save_config)
+      break
+    print "%s"%(NSPORT),
+    if NSPORT == limit:
+      msg  = "\n"
+      msg += "Can't find a free port to launch omniNames\n"
+      msg += "Try to kill the running servers and then launch SALOME again.\n"
+      raise RuntimeError, msg
+    NSPORT=NSPORT+1
+    pass
+  #
+#
+
+def searchFreePort_withPortManager(queue, args={}, save_config=1, use_port=None):
   from PortManager import getPort
   port = getPort(use_port)
 
-  #PortManager.getPort()
-  #PortManager.test_value()
-
   if use_port:
     print "Check if port can be used: %d" % use_port,
-    #if not portManager.isPortUsed(use_port):
-    if port == use_port:
+    if port == use_port and port != -1:
       print "- OK"
       __setup_config(use_port, args, save_config)
+      queue.put([os.environ['OMNIORB_CONFIG'],
+                 os.environ['NSPORT'],
+                 os.environ['NSHOST']])
       return
     else:
       print "- KO: port is busy"
       pass
   #
   print "Searching for a free port for naming service:",
-  #port = portManager.getPort()
-  print "%s - OK"%(port)
-  __setup_config(port, args, save_config)
-  #port = portManager.releasePort(port)
+  if port == -1: # try again
+    port = getPort(use_port)
+
+  if port != -1:
+    print "%s - OK"%(port)
+    __setup_config(port, args, save_config)
+  else:
+    print "Unable to obtain port"
+
+  queue.put([os.environ['OMNIORB_CONFIG'],
+             os.environ['NSPORT'],
+             os.environ['NSHOST']])
+#
+
+def __savePortToFile(args):
+  # Save Naming service port name into
+  # the file args["ns_port_log_file"]
+  if args.has_key('ns_port_log_file'):
+    omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
+    file_name = os.path.join(omniorbUserPath, args["ns_port_log_file"])
+    with open(file_name, "w") as f:
+      f.write(os.environ['NSPORT'])
+#
+
+def searchFreePort(args={}, save_config=1, use_port=None):
+  """
+  Search free port for SALOME session.
+  Returns first found free port number.
+  """
+  try:
+    import PortManager # mandatory
+    from multiprocessing import Process, Queue
+    queue = Queue()
+    p = Process(target = searchFreePort_withPortManager, args=(queue, args, save_config, use_port,))
+    p.start()
+    info = queue.get()
+
+    os.environ['OMNIORB_CONFIG'] = info[0]
+    os.environ['NSPORT'] = info[1]
+    args['port'] = os.environ['NSPORT']
+    os.environ['NSHOST'] = info[2]
+    __savePortToFile(args)
+
+    p.join() # this blocks until the process terminates
+  except ImportError:
+    searchFreePort_withoutPortManager(args, save_config, use_port)
+    __savePortToFile(args)
 #