Exemple #1
0
 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")
Exemple #2
0
    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_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
Exemple #5
0
 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 ""
Exemple #6
0
 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
Exemple #7
0
 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
Exemple #8
0
 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
Exemple #9
0
    def get_children(self, recursive=False):
        """Return the children of this process as a list of Process
        objects.
        If recursive is True return all the parent descendants.

        Example (A == this process):

         A ─┐
            │
            ├─ B (child) ─┐
            │             └─ X (grandchild) ─┐
            │                                └─ Y (great grandchild)
            ├─ C (child)
            └─ D (child)

        >>> p.get_children()
        B, C, D
        >>> p.get_children(recursive=True)
        B, X, Y, C, D

        Note that in the example above if process X disappears
        process Y won't be returned either as the reference to
        process A is lost.
        """
        if not self.is_running():
            name = self._platform_impl._process_name
            raise NoSuchProcess(self.pid, name)

        ret = []
        if not recursive:
            for p in process_iter():
                try:
                    if p.ppid == self.pid:
                        ret.append(p)
                except NoSuchProcess:
                    pass
        else:
            # construct a dict where 'values' are all the processes
            # having 'key' as their parent
            table = defaultdict(list)
            for p in process_iter():
                try:
                    table[p.ppid].append(p)
                except NoSuchProcess:
                    pass
            # At this point we have a mapping table where table[self.pid]
            # are the current process's children.
            # Below, we look for all descendants recursively, similarly
            # to a recursive function call.
            checkpids = [self.pid]
            for pid in checkpids:
                for proc in table[pid]:
                    ret.append(proc)
                    if proc.pid not in checkpids:
                        checkpids.append(proc.pid)
        return ret
 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
Exemple #11
0
 def kill(self):
     """Kill the current process."""
     # 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':
         self.send_signal(signal.SIGKILL)
     else:
         self._platform_impl.kill_process()
Exemple #12
0
 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
Exemple #13
0
 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
Exemple #14
0
 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
Exemple #15
0
 def resume(self):
     """Resume process execution."""
     # 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)
     # windows
     if hasattr(self._platform_impl, "resume_process"):
         self._platform_impl.resume_process()
     else:
         # posix
         self.send_signal(signal.SIGCONT)
Exemple #16
0
 def __init__(self, pid):
     """Create a new Process object, raises NoSuchProcess if the PID
     does not exist, and ValueError if the parameter is not an
     integer PID."""
     if not isinstance(pid, int):
         raise ValueError("An integer is required")
     if not pid_exists(pid):
         raise NoSuchProcess(pid, None, "no process found with PID %s" % pid)
     self._pid = pid
     # platform-specific modules define an PlatformProcess
     # implementation class
     self._platform_impl = PlatformProcess(pid)
     self._last_sys_cpu_times = None
     self._last_proc_cpu_times = None
Exemple #17
0
 def __init__(self, *args, **kwargs):
     self.__subproc = subprocess.Popen(*args, **kwargs)
     self._pid = self.__subproc.pid
     self._gone = False
     self._platform_impl = _psplatform.Process(self._pid)
     self._last_sys_cpu_times = None
     self._last_proc_cpu_times = None
     try:
         self.create_time
     except AccessDenied:
         pass
     except NoSuchProcess:
         raise NoSuchProcess(self._pid, None,
                             "no process found with pid %s" % pid)
Exemple #18
0
 def get_children(self):
     """Return the children of this process as a list of Process
     objects.
     """
     if not self.is_running():
         name = self._platform_impl._process_name
         raise NoSuchProcess(self.pid, name)
     retlist = []
     for proc in process_iter():
         try:
             if proc.ppid == self.pid:
                 retlist.append(proc)
         except NoSuchProcess:
             pass
     return retlist
Exemple #19
0
 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)
Exemple #20
0
 def __init__(self, pid):
     """Create a new Process object for the given pid.
     Raises NoSuchProcess if pid does not exist.
     """
     self._pid = pid
     self._gone = False
     # platform-specific modules define an _psplatform.Process
     # implementation class
     self._platform_impl = _psplatform.Process(pid)
     self._last_sys_cpu_times = None
     self._last_proc_cpu_times = None
     # cache creation time for later use in is_running() method
     try:
         self.create_time
     except AccessDenied:
         pass
     except NoSuchProcess:
         raise NoSuchProcess(pid, None, 'no process found with pid %s' % pid)
Exemple #21
0
 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
Exemple #22
0
 def get_process_exe(self):
     # no such thing as "exe" on OS X; it will maybe be determined
     # later from cmdline[0]
     if not pid_exists(self.pid):
         raise NoSuchProcess(self.pid, self._process_name)
     return ""
Exemple #23
0
 def get_process_cmdline(self):
     """Return process cmdline as a list of arguments."""
     if not pid_exists(self.pid):
         raise NoSuchProcess(self.pid, self._process_name)
     return _psutil_osx.get_process_cmdline(self.pid)
Exemple #24
0
 def get_process_gid(self):
     # no such thing as gid on Windows
     if not pid_exists(self.pid):
         raise NoSuchProcess(self.pid, self._process_name)
     return -1