# Path: psutil/_compat.py
# def namedtuple(typename, field_names, verbose=False, rename=False):
#     """A collections.namedtuple implementation written in Python
#     to support Python versions < 2.6.
# 
#     Taken from: http://code.activestate.com/recipes/500261/
#     """
#     # Parse and validate the field names.  Validation serves two
#     # purposes, generating informative error messages and preventing
#     # template injection attacks.
#     if isinstance(field_names, basestring):
#          # names separated by whitespace and/or commas
#         field_names = field_names.replace(',', ' ').split()
#     field_names = tuple(map(str, field_names))
#     if rename:
#         names = list(field_names)
#         seen = set()
#         for i, name in enumerate(names):
#             if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
#                 or not name or name[0].isdigit() or name.startswith('_')
#                 or name in seen):
#                     names[i] = '_%d' % i
#             seen.add(name)
#         field_names = tuple(names)
#     for name in (typename,) + field_names:
#         if not min(c.isalnum() or c=='_' for c in name):
#             raise ValueError('Type names and field names can only contain ' \
#                              'alphanumeric characters and underscores: %r'
#                              % name)
#         if _iskeyword(name):
#             raise ValueError('Type names and field names cannot be a keyword: %r' \
#                              % name)
#         if name[0].isdigit():
#             raise ValueError('Type names and field names cannot start with a ' \
#                              'number: %r' % name)
#     seen_names = set()
#     for name in field_names:
#         if name.startswith('_') and not rename:
#             raise ValueError('Field names cannot start with an underscore: %r'
#                              % name)
#         if name in seen_names:
#             raise ValueError('Encountered duplicate field name: %r' % name)
#         seen_names.add(name)
# 
#     # Create and fill-in the class template
#     numfields = len(field_names)
#     # tuple repr without parens or quotes
#     argtxt = repr(field_names).replace("'", "")[1:-1]
#     reprtxt = ', '.join('%s=%%r' % name for name in field_names)
#     template = '''class %(typename)s(tuple):
#     '%(typename)s(%(argtxt)s)' \n
#     __slots__ = () \n
#     _fields = %(field_names)r \n
#     def __new__(_cls, %(argtxt)s):
#         return _tuple.__new__(_cls, (%(argtxt)s)) \n
#     @classmethod
#     def _make(cls, iterable, new=tuple.__new__, len=len):
#         'Make a new %(typename)s object from a sequence or iterable'
#         result = new(cls, iterable)
#         if len(result) != %(numfields)d:
#             raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
#         return result \n
#     def __repr__(self):
#         return '%(typename)s(%(reprtxt)s)' %% self \n
#     def _asdict(self):
#         'Return a new dict which maps field names to their values'
#         return dict(zip(self._fields, self)) \n
#     def _replace(_self, **kwds):
#         'Return a new %(typename)s object replacing specified fields with new values'
#         result = _self._make(map(kwds.pop, %(field_names)r, _self))
#         if kwds:
#             raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
#         return result \n
#     def __getnewargs__(self):
#         return tuple(self) \n\n''' % locals()
#     for i, name in enumerate(field_names):
#         template += '        %s = _property(_itemgetter(%d))\n' % (name, i)
#     if verbose:
#         print template
# 
#     # Execute the template string in a temporary namespace
#     namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
#                      _property=property, _tuple=tuple)
#     try:
#         exec template in namespace
#     except SyntaxError, e:
#         raise SyntaxError(e.message + ':\n' + template)
#     result = namespace[typename]
# 
#     # For pickling to work, the __module__ variable needs to be set
#     # to the frame where the named tuple is created.  Bypass this
#     # step in enviroments where sys._getframe is not defined (Jython
#     # for example) or sys._getframe is not defined for arguments
#     # greater than 0 (IronPython).
#     try:
#         result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
#     except (AttributeError, ValueError):
#         pass
# 
#     return result


import os
import errno
import subprocess
import psutil
import socket
import re
import sys
import warnings
import time
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
from psutil._compat import namedtuple
                    else:
                        return
            else:
                raise
        else:
            if retpid == 0:
                check_timeout()
                continue
            # process exited due to a signal; return the integer of
            # that signal
            if os.WIFSIGNALED(status):
                return os.WTERMSIG(status)
            # process exited using exit(2) system call; return the
            # integer exit(2) system call has been called with
            elif os.WIFEXITED(status):
                return os.WEXITSTATUS(status)
            else:
                # should never happen
                raise RuntimeError("unknown process exit status")


class LsofParser:
    """A wrapper for lsof command line utility.
    Executes lsof in subprocess and parses its output.
    """
    socket_table = {'TCP' : socket.SOCK_STREAM,
                    'UDP' : socket.SOCK_DGRAM,
                    'IPv4' : socket.AF_INET,
                    'IPv6' : socket.AF_INET6}
    _openfile_ntuple = namedtuple('openfile', 'path fd')

# Path: psutil/_compat.py
# def namedtuple(typename, field_names, verbose=False, rename=False):
#     """A collections.namedtuple implementation written in Python
#     to support Python versions < 2.6.
# 
#     Taken from: http://code.activestate.com/recipes/500261/
#     """
#     # Parse and validate the field names.  Validation serves two
#     # purposes, generating informative error messages and preventing
#     # template injection attacks.
#     if isinstance(field_names, basestring):
#          # names separated by whitespace and/or commas
#         field_names = field_names.replace(',', ' ').split()
#     field_names = tuple(map(str, field_names))
#     if rename:
#         names = list(field_names)
#         seen = set()
#         for i, name in enumerate(names):
#             if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
#                 or not name or name[0].isdigit() or name.startswith('_')
#                 or name in seen):
#                     names[i] = '_%d' % i
#             seen.add(name)
#         field_names = tuple(names)
#     for name in (typename,) + field_names:
#         if not min(c.isalnum() or c=='_' for c in name):
#             raise ValueError('Type names and field names can only contain ' \
#                              'alphanumeric characters and underscores: %r'
#                              % name)
#         if _iskeyword(name):
#             raise ValueError('Type names and field names cannot be a keyword: %r' \
#                              % name)
#         if name[0].isdigit():
#             raise ValueError('Type names and field names cannot start with a ' \
#                              'number: %r' % name)
#     seen_names = set()
#     for name in field_names:
#         if name.startswith('_') and not rename:
#             raise ValueError('Field names cannot start with an underscore: %r'
#                              % name)
#         if name in seen_names:
#             raise ValueError('Encountered duplicate field name: %r' % name)
#         seen_names.add(name)
# 
#     # Create and fill-in the class template
#     numfields = len(field_names)
#     # tuple repr without parens or quotes
#     argtxt = repr(field_names).replace("'", "")[1:-1]
#     reprtxt = ', '.join('%s=%%r' % name for name in field_names)
#     template = '''class %(typename)s(tuple):
#     '%(typename)s(%(argtxt)s)' \n
#     __slots__ = () \n
#     _fields = %(field_names)r \n
#     def __new__(_cls, %(argtxt)s):
#         return _tuple.__new__(_cls, (%(argtxt)s)) \n
#     @classmethod
#     def _make(cls, iterable, new=tuple.__new__, len=len):
#         'Make a new %(typename)s object from a sequence or iterable'
#         result = new(cls, iterable)
#         if len(result) != %(numfields)d:
#             raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
#         return result \n
#     def __repr__(self):
#         return '%(typename)s(%(reprtxt)s)' %% self \n
#     def _asdict(self):
#         'Return a new dict which maps field names to their values'
#         return dict(zip(self._fields, self)) \n
#     def _replace(_self, **kwds):
#         'Return a new %(typename)s object replacing specified fields with new values'
#         result = _self._make(map(kwds.pop, %(field_names)r, _self))
#         if kwds:
#             raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
#         return result \n
#     def __getnewargs__(self):
#         return tuple(self) \n\n''' % locals()
#     for i, name in enumerate(field_names):
#         template += '        %s = _property(_itemgetter(%d))\n' % (name, i)
#     if verbose:
#         print template
# 
#     # Execute the template string in a temporary namespace
#     namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
#                      _property=property, _tuple=tuple)
#     try:
#         exec template in namespace
#     except SyntaxError, e:
#         raise SyntaxError(e.message + ':\n' + template)
#     result = namespace[typename]
# 
#     # For pickling to work, the __module__ variable needs to be set
#     # to the frame where the named tuple is created.  Bypass this
#     # step in enviroments where sys._getframe is not defined (Jython
#     # for example) or sys._getframe is not defined for arguments
#     # greater than 0 (IronPython).
#     try:
#         result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
#     except (AttributeError, ValueError):
#         pass
# 
#     return result


# Path: psutil/_psposix.py
import os
import errno
import subprocess
import psutil
import socket
import re
import sys
import warnings
import time
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
from psutil._compat import namedtuple

                    else:
                        return
            else:
                raise
        else:
            if retpid == 0:
                check_timeout()
                continue
            # process exited due to a signal; return the integer of
            # that signal
            if os.WIFSIGNALED(status):
                return os.WTERMSIG(status)
            # process exited using exit(2) system call; return the
            # integer exit(2) system call has been called with
            elif os.WIFEXITED(status):
                return os.WEXITSTATUS(status)
            else:
                # should never happen
                raise RuntimeError("unknown process exit status")


class LsofParser:
    """A wrapper for lsof command line utility.
    Executes lsof in subprocess and parses its output.
    """
    socket_table = {'TCP' : socket.SOCK_STREAM,
                    'UDP' : socket.SOCK_DGRAM,
                    'IPv4' : socket.AF_INET,
                    'IPv6' : socket.AF_INET6}
    _openfile_ntuple = namedtuple('openfile', 'path fd')

    _connection_ntuple = namedtuple('connection', 'fd family type local_address '