def get_process_exe(self): if self.pid in (0, 2): raise AccessDenied(self.pid, self._process_name) try: exe = os.readlink("/proc/%s/exe" % self.pid) except (OSError, IOError): err = sys.exc_info()[1] if err.errno == errno.ENOENT: # no such file error; might be raised also if the # path actually exists for system processes with # low pids (about 0-20) if os.path.lexists("/proc/%s/exe" % self.pid): return "" else: # ok, it is a process which has gone away raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise # readlink() might return paths containing null bytes causing # problems when used with other fs-related functions (os.*, # open(), ...) exe = exe.replace('\x00', '') # It seems symlinks can point to a deleted/invalid location # (this usually happens with "pulseaudio" process). # However, if we had permissions to execute readlink() it's # likely that we'll be able to figure out exe from argv[0] # later on. if exe.endswith(" (deleted)") and not os.path.isfile(exe): return "" return exe
def get_process_exe(self): try: exe = os.readlink("/proc/%s/exe" % self.pid) except (OSError, IOError): err = sys.exc_info()[1] if err.errno == errno.ENOENT: # no such file error; might be raised also if the # path actually exists for system processes with # low pids (about 0-20) if os.path.lexists("/proc/%s/exe" % self.pid): return "" else: # ok, it is a process which has gone away raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise # readlink() might return paths containing null bytes causing # problems when used with other fs-related functions (os.*, # open(), ...) exe = exe.replace('\x00', '') # Certain names have ' (deleted)' appended. Usually this is # bogus as the file actually exists. Either way that's not # important as we don't want to discriminate executables which # have been deleted. if exe.endswith(" (deleted)") and not os.path.exists(exe): exe = exe[:-10] return exe
def get_process_cwd(self): if self.pid in (0, 4) or self.pid == 8 and _WIN2000: raise AccessDenied(self.pid, self._process_name) # return a normalized pathname since the native C function appends # "\\" at the and of the path path = _psutil_mswindows.get_process_cwd(self.pid) return os.path.normpath(path)
def send_signal(self, sig): """Send a signal to process (see signal module constants). On Windows only SIGTERM is valid and is treated as an alias for kill(). """ # safety measure in case the current process has been killed in # meantime and the kernel reused its PID if not self.is_running(): name = self._platform_impl._process_name raise NoSuchProcess(self.pid, name) if os.name == 'posix': try: os.kill(self.pid, sig) except OSError: err = sys.exc_info()[1] name = self._platform_impl._process_name if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, name) if err.errno == errno.EPERM: raise AccessDenied(self.pid, name) raise else: if sig == signal.SIGTERM: self._platform_impl.kill_process() else: raise ValueError("only SIGTERM is supported on Windows")
def get_memory_maps(self): """Return process's mapped memory regions as a list of nameduples. Fields are explained in 'man proc'; here is an updated (Apr 2012) version: http://goo.gl/fmebo """ f = None try: f = open("/proc/%s/smaps" % self.pid) first_line = f.readline() current_block = [first_line] def get_blocks(): data = {} for line in f: fields = line.split(None, 5) if len(fields) >= 5: yield (current_block.pop(), data) current_block.append(line) else: data[fields[0]] = int(fields[1]) * 1024 yield (current_block.pop(), data) if first_line: # smaps file can be empty for header, data in get_blocks(): hfields = header.split(None, 5) try: addr, perms, offset, dev, inode, path = hfields except ValueError: addr, perms, offset, dev, inode, path = hfields + [''] if not path: path = '[anon]' else: path = path.strip() yield (addr, perms, path, data['Rss:'], data['Size:'], data.get('Pss:', 0), data['Shared_Clean:'], data['Shared_Clean:'], data['Private_Clean:'], data['Private_Dirty:'], data['Referenced:'], data.get('Anonymous:', 0), data['Swap:']) f.close() except EnvironmentError: # XXX - Can't use wrap_exceptions decorator as we're # returning a generator; this probably needs some # refactoring in order to avoid this code duplication. if f is not None: f.close() err = sys.exc_info()[1] if err.errno in (errno.ENOENT, errno.ESRCH): raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise except: if f is not None: f.close() raise
def get_process_exe(self): # no such thing as "exe" on Windows; it will maybe be determined # later from cmdline[0] if not pid_exists(self.pid): raise NoSuchProcess(self.pid, self._process_name) if self.pid in (0, 4): raise AccessDenied(self.pid, self._process_name) return ""
def get_process_cwd(self): if self.pid == 0: raise AccessDenied(self.pid, self._process_name) # readlink() might return paths containing null bytes causing # problems when used with other fs-related functions (os.*, # open(), ...) path = os.readlink("/proc/%s/cwd" % self.pid) return path.replace('\x00', '')
def get_process_exe(self): if self.pid in (0, 2): raise AccessDenied(self.pid, self._process_name) try: exe = os.readlink("/proc/%s/exe" % self.pid) except (OSError, IOError), err: if err.errno == errno.ENOENT: # no such file error; might be raised also if the # path actually exists for system processes with # low pids (about 0-20) if os.path.lexists("/proc/%s/exe" % self.pid): return "" else: # ok, it is a process which has gone away raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return method(self, *args, **kwargs) except OSError, err: if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return callable(self, *args, **kwargs) except OSError, err: if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED): raise AccessDenied(self.pid, self._process_name) if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return callable(self, *args, **kwargs) except (OSError, IOError), err: if err.errno == errno.ENOENT: # no such file or directory raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return callable(self, *args, **kwargs) except OSError: err = sys.exc_info()[1] if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def get_open_files(self): """Return files opened by process.""" if self.pid == 0: raise AccessDenied(self.pid, self._process_name) files = [] rawlist = _psutil_osx.get_process_open_files(self.pid) for path, fd in rawlist: if os.path.isfile(path): ntuple = ntuple_openfile(path, fd) files.append(ntuple) return files
def get_memory_maps(self): try: raw = _psutil_mswindows.get_process_memory_maps(self.pid) except OSError, err: # XXX - can't use wrap_exceptions decorator as we're # returning a generator; probably needs refactoring. if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED): raise AccessDenied(self.pid, self._process_name) if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return callable(self, *args, **kwargs) except EnvironmentError, err: # ENOENT (no such file or directory) gets raised on open(). # ESRCH (no such process) can get raised on read() if # process is gone in meantime. if err.errno in (errno.ENOENT, errno.ESRCH): raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def exe(self): """The process executable as an absolute path name.""" exe = self._platform_impl.get_process_exe() # if we have the cmdline but not the exe, figure it out from argv[0] if not exe: cmdline = self.cmdline if cmdline and hasattr(os, 'access') and hasattr(os, 'X_OK'): _exe = os.path.realpath(cmdline[0]) if os.path.isfile(_exe) and os.access(_exe, os.X_OK): return _exe if not exe: raise AccessDenied(self.pid, self._platform_impl._process_name) return exe
def get_process_environ(self): if self.pid in (0, 4): raise AccessDenied(self.pid, self._process_name) rawstr = _psutil_mswindows.get_process_environ(self.pid) ret = {} values = rawstr.split('\0\0')[0].split('\0') for line in values: pos = line.find('=') if pos: # os.environ forces upper keys; let's do the same key = line[:pos].upper() if key: value = line[pos + 1:] if value: ret[key] = value return ret
def get_memory_maps(self): try: raw = _psutil_mswindows.get_process_memory_maps(self.pid) except OSError: # XXX - can't use wrap_exceptions decorator as we're # returning a generator; probably needs refactoring. err = sys.exc_info()[1] if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED): raise AccessDenied(self.pid, self._process_name) if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) raise else: for addr, perm, path, rss in raw: path = _convert_raw_path(path) addr = hex(addr) yield (addr, perm, path, rss)
def runcmd(self, cmd): """Expects an lsof-related command line, execute it in a subprocess and return its output. If something goes bad stderr is parsed and proper exceptions raised as necessary. """ p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: stdout, stderr = [ x.decode(sys.stdout.encoding) for x in (stdout, stderr) ] if stderr: utility = cmd.split(' ')[0] if self._which(utility) is None: msg = "this functionnality requires %s command line utility " \ "to be installed on the system" % utility raise NotImplementedError(msg) elif "permission denied" in stderr.lower(): # "permission denied" can be found also in case of zombie # processes; p = psutil.Process(self.pid) if not p.is_running(): raise NoSuchProcess(self.pid, self.process_name) raise AccessDenied(self.pid, self.process_name) elif "lsof: warning:" in stderr.lower(): # usually appears when lsof is run for the first time and # complains about missing cache file in user home warnings.warn(stderr, RuntimeWarning) else: # this must be considered an application bug raise RuntimeError(stderr) if not stdout: p = psutil.Process(self.pid) if not p.is_running(): raise NoSuchProcess(self.pid, self.process_name) return "" return stdout