Beispiel #1
0
    def _get_unix_sockets(self, pid):
        """Get UNIX sockets used by process by parsing 'pfiles' output."""
        # TODO: rewrite this in C (...but the damn netstat source code
        # does not include this part! Argh!!)
        cmd = "pfiles %s" % pid
        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 p.returncode != 0:
            if 'permission denied' in stderr.lower():
                raise AccessDenied(self.pid, self._process_name)
            if 'no such process' in stderr.lower():
                raise NoSuchProcess(self.pid, self._process_name)
            raise RuntimeError("%r command error\n%s" % (cmd, stderr))

        lines = stdout.split('\n')[2:]
        for i, line in enumerate(lines):
            line = line.lstrip()
            if line.startswith('sockname: AF_UNIX'):
                path = line.split(' ', 2)[2]
                type = lines[i - 2].strip()
                if type == 'SOCK_STREAM':
                    type = socket.SOCK_STREAM
                elif type == 'SOCK_DGRAM':
                    type = socket.SOCK_DGRAM
                else:
                    type = -1
                yield (-1, socket.AF_UNIX, type, path, "", CONN_NONE)
Beispiel #2
0
 def get_process_cwd(self):
     if self.pid in (0, 4):
         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)
Beispiel #3
0
    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
Beispiel #4
0
    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.get('Size:', 0), data.get('Pss:', 0),
                           data.get('Shared_Clean:',
                                    0), data.get('Shared_Dirty:', 0),
                           data.get('Private_Clean:',
                                    0), data.get('Private_Dirty:', 0),
                           data.get('Referenced:',
                                    0), data.get('Anonymous:',
                                                 0), data.get('Swap:', 0))
            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
        f.close()
Beispiel #5
0
 def set_process_nice(self, value):
     if self.pid in (2, 3):
         # Special case PIDs: internally setpriority(3) return ESRCH
         # (no such process), no matter what.
         # The process actually exists though, as it has a name,
         # creation time, etc.
         raise AccessDenied(self.pid, self._process_name)
     return _psutil_posix.setpriority(self.pid, value)
Beispiel #6
0
 def wrapper(self, *args, **kwargs):
     try:
         return fun(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
Beispiel #7
0
 def wrapper(self, *args, **kwargs):
     try:
         return callable(self, *args, **kwargs)
     except EnvironmentError:
         # 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.
         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
Beispiel #8
0
 def get_process_nice(self):
     # For some reason getpriority(3) return ESRCH (no such process)
     # for certain low-pid processes, no matter what (even as root).
     # The process actually exists though, as it has a name,
     # creation time, etc.
     # The best thing we can do here appears to be raising AD.
     # Note: tested on Solaris 11; on Open Solaris 5 everything is
     # fine.
     try:
         return _psutil_posix.getpriority(self.pid)
     except EnvironmentError:
         err = sys.exc_info()[1]
         if err.errno in (errno.ENOENT, errno.ESRCH):
             if pid_exists(self.pid):
                 raise AccessDenied(self.pid, self._process_name)
         raise
Beispiel #9
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)
Beispiel #10
0
 def send_signal(self, sig):
     """Send a signal to process pre-emptively checking whether
     PID has been reused (see signal module constants) .
     On Windows only SIGTERM is valid and is treated as an alias
     for kill().
     """
     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:
                 self._gone = True
                 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")