Package rocon_utilities :: Module system
[frames] | no frames]

Source Code for Module rocon_utilities.system

  1  #!/usr/bin/env python 
  2  # 
  3  # License: BSD 
  4  #   https://raw.github.com/robotics-in-concert/rocon_multimaster/master/rocon_utilities/LICENSE 
  5  # 
  6   
  7  ############################################################################## 
  8  # Imports 
  9  ############################################################################## 
 10   
 11  import os 
 12  import time 
 13  import errno 
 14  # Local imports 
 15  from .exceptions import TimeoutExpiredError 
 16   
 17  ############################################################################## 
 18  # Methods 
 19  ############################################################################## 
 20   
 21   
22 -def which(program):
23 24 def is_exe(fpath): 25 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
26 27 fpath, unused_fname = os.path.split(program) 28 if fpath: 29 if is_exe(program): 30 return program 31 else: 32 for path in os.environ["PATH"].split(os.pathsep): 33 path = path.strip('"') 34 exe_file = os.path.join(path, program) 35 if is_exe(exe_file): 36 return exe_file 37 38 return None 39 40 41 ############################################################################## 42 # PID 43 ############################################################################## 44 45
46 -def pid_exists(pid):
47 """Check whether pid exists in the current process table.""" 48 if pid < 0: 49 return False 50 try: 51 os.kill(pid, 0) 52 except OSError, e: 53 return e.errno == errno.EPERM 54 else: 55 return True
56 57
58 -def wait_pid(pid, timeout=None):
59 """Wait for process with pid 'pid' to terminate and return its 60 exit status code as an integer. 61 62 If pid is not a children of os.getpid() (current process) just 63 waits until the process disappears and return None. 64 65 If pid does not exist at all return None immediately. 66 67 Raise TimeoutExpiredError on timeout expired (if specified). 68 """ 69 def check_timeout(delay): 70 if timeout is not None: 71 if time.time() >= stop_at: 72 raise TimeoutExpiredError 73 time.sleep(delay) 74 return min(delay * 2, 0.04)
75 76 if timeout is not None: 77 waitcall = lambda: os.waitpid(pid, os.WNOHANG) 78 stop_at = time.time() + timeout 79 else: 80 waitcall = lambda: os.waitpid(pid, 0) 81 82 delay = 0.0001 83 while 1: 84 try: 85 retpid, status = waitcall() 86 except OSError, err: 87 if err.errno == errno.EINTR: 88 delay = check_timeout(delay) 89 continue 90 elif err.errno == errno.ECHILD: 91 # This has two meanings: 92 # - pid is not a child of os.getpid() in which case 93 # we keep polling until it's gone 94 # - pid never existed in the first place 95 # In both cases we'll eventually return None as we 96 # can't determine its exit status code. 97 while 1: 98 if pid_exists(pid): 99 delay = check_timeout(delay) 100 else: 101 return 102 else: 103 raise 104 else: 105 if retpid == 0: 106 # WNOHANG was used, pid is still running 107 delay = check_timeout(delay) 108 continue 109 # process exited due to a signal; return the integer of 110 # that signal 111 if os.WIFSIGNALED(status): 112 return os.WTERMSIG(status) 113 # process exited using exit(2) system call; return the 114 # integer exit(2) system call has been called with 115 elif os.WIFEXITED(status): 116 return os.WEXITSTATUS(status) 117 else: 118 # should never happen 119 raise RuntimeError("unknown process exit status") 120