code: def io_op(func, *args):
      
      while True:
          try:
              return func(*args), None
          except (select.error, OSError, IOError):
              e = sys.exc_info()[1]
              _vv and IOLOG.debug('io_op(%r) -> OSError: %s', func, e)
              if e.args[0] == errno.EINTR:
                  continue
              if e.args[0] in (errno.EIO, errno.ECONNRESET, errno.EPIPE):
                  return None, e
              raise
docs: Wrap `func(*args)` that may raise :class:`select.error`,
      :class:`IOError`, or :class:`OSError`, trapping UNIX error codes relating
      to disconnection and retry events in various subsystems:
  
      * When a signal is delivered to the process on Python 2, system call retry
        is signalled through :data:`errno.EINTR`. The invocation is automatically
        restarted.
      * When performing IO against a TTY, disconnection of the remote end is
        signalled by :data:`errno.EIO`.
      * When performing IO against a socket, disconnection of the remote end is
        signalled by :data:`errno.ECONNRESET`.
      * When performing IO against a pipe, disconnection of the remote end is
        signalled by :data:`errno.EPIPE`.
  
      :returns:
          Tuple of `(return_value, disconnect_reason)`, where `return_value` is
          the return value of `func(*args)`, and `disconnected` is an exception
          instance when disconnection was detected, otherwise :data:`None`.