Exemplo n.º 1
0
    def __recv_windows(self, n):
        if self._read_pending:
            try:
                nBytesRead = winutils.get_overlapped_result(self.pipe,
                                                            self._read,
                                                            False)
                self._read_pending = False
                recvBuffer = self._read_buffer[:nBytesRead]

                return (0, winutils.get_decoded_buffer(recvBuffer))
            except pywintypes.error as e:
                if e.winerror == winutils.winerror.ERROR_IO_INCOMPLETE:
                    # The operation is still pending, try again
                    self._read_pending = True
                    return (errno.EAGAIN, "")
                elif e.winerror in winutils.pipe_disconnected_errors:
                    # If the pipe was disconnected, return 0.
                    return (0, "")
                else:
                    return (errno.EINVAL, "")

        (errCode, self._read_buffer) = winutils.read_file(self.pipe,
                                                          n,
                                                          self._read)
        if errCode:
            if errCode == winutils.winerror.ERROR_IO_PENDING:
                self._read_pending = True
                return (errno.EAGAIN, "")
            elif errCode in winutils.pipe_disconnected_errors:
                # If the pipe was disconnected, return 0.
                return (0, "")
            else:
                return (errCode, "")

        try:
            nBytesRead = winutils.get_overlapped_result(self.pipe,
                                                        self._read,
                                                        False)
            winutils.win32event.SetEvent(self._read.hEvent)
        except pywintypes.error as e:
            if e.winerror in winutils.pipe_disconnected_errors:
                # If the pipe was disconnected, return 0.
                return (0, "")
            else:
                return (e.winerror, "")

        recvBuffer = self._read_buffer[:nBytesRead]
        return (0, winutils.get_decoded_buffer(recvBuffer))
Exemplo n.º 2
0
    def __recv_windows(self, n):
        if self._read_pending:
            try:
                nBytesRead = winutils.get_overlapped_result(
                    self.pipe, self._read, False)
                self._read_pending = False
                recvBuffer = self._read_buffer[:nBytesRead]

                return (0, winutils.get_decoded_buffer(recvBuffer))
            except pywintypes.error as e:
                if e.winerror == winutils.winerror.ERROR_IO_INCOMPLETE:
                    # The operation is still pending, try again
                    self._read_pending = True
                    return (errno.EAGAIN, "")
                elif e.winerror in winutils.pipe_disconnected_errors:
                    # If the pipe was disconnected, return 0.
                    return (0, "")
                else:
                    return (errno.EINVAL, "")

        (errCode,
         self._read_buffer) = winutils.read_file(self.pipe, n, self._read)
        if errCode:
            if errCode == winutils.winerror.ERROR_IO_PENDING:
                self._read_pending = True
                return (errno.EAGAIN, "")
            elif errCode in winutils.pipe_disconnected_errors:
                # If the pipe was disconnected, return 0.
                return (0, "")
            else:
                return (errCode, "")

        try:
            nBytesRead = winutils.get_overlapped_result(
                self.pipe, self._read, False)
            winutils.win32event.SetEvent(self._read.hEvent)
        except pywintypes.error as e:
            if e.winerror in winutils.pipe_disconnected_errors:
                # If the pipe was disconnected, return 0.
                return (0, "")
            else:
                return (e.winerror, "")

        recvBuffer = self._read_buffer[:nBytesRead]
        return (0, winutils.get_decoded_buffer(recvBuffer))
Exemplo n.º 3
0
    def get_read_result(self, from_namedpipe=True):
        """Return the result from the overlapped structure.

        If there is no pending read operation, this function will return
        immediately. This call will return False if the reading operation
        has not completed yet and the read operation is still in progress.
        Otherwise, it will return the result.

        :param from_namedpipe: boolean representing from where to read
            True = the function reads from the named pipe handle
            False = he function reads from the file handle
        """
        if not self._read_pending:
            # There is no pending read operation, we should return here
            return

        # Represents the handle from where we should read.
        handle_to_read = self.namedpipe if from_namedpipe else self._npipe_file
        try:
            # Try to retrieve the result from the overlapped structure.
            # This will raise an ERROR_IO_INCOMPLETE exception if the
            # read operation has not completed yet.
            nBytesRead = ovs_winutils.get_overlapped_result(
                handle_to_read, self._read, False)
            # Mark the read operation as complete
            self._read_pending = False
            # Decode the result and return it
            return ovs_winutils.get_decoded_buffer(
                self._read_buffer[:nBytesRead])
        except ovs_winutils.pywintypes.error as e:
            if e.winerror == ovs_winutils.winerror.ERROR_IO_INCOMPLETE:
                # In this case we should call again this function to try to
                # retrieve the result.
                self._read_pending = True
                # Return False to mark that the read operation has not
                # completed yet.
                return False
            else:
                # If we reach here it means that an unexpected error was
                # received. We should raise an exception in this case.
                raise NamedPipeException(
                    "Could not get the overlapped result. "
                    "Error: '%s'" % e.strerror, e.winerror)
Exemplo n.º 4
0
    def nonblocking_read(self, bytes_to_read, from_namedpipe=True):
        """Read from the named pipe handle or the file handle.

        This function returns imediatly and does not wait for the read
        operation to complete. In case the read operation is not complete,
        the property '_read_pending' will be set to True and the method
        get_read_result should be called to retrieve the result. Otherwise,
        the output of the read operation is returned.

        :param bytes_to_read: int representing the maximum number of bytes
            to be read.
        :param from_namedpipe: boolean representing from where to read
            True = the function reads from the named pipe handle
            False = he function reads from the file handle
        """
        if self._read_pending:
            # If there is a pending read operation, the method
            # 'get_read_result' should be called to retrieve the result.
            return

        # Represents the handle from where we should read.
        handle_to_read = self.namedpipe if from_namedpipe else self._npipe_file

        # The read operation is non-blocking because the read overlapped
        # structure is passed. It will return immediately.
        (errCode,
         self._read_buffer) = ovs_winutils.read_file(handle_to_read,
                                                     bytes_to_read, self._read)

        if errCode:
            # The error code should be 0 if the operation executed with success
            if errCode == ovs_winutils.winerror.ERROR_IO_PENDING:
                # This is returned when the overlapped structure is passed
                # to the read operation (which is our case) and the operation
                # has not finished yet. We mark this as a pending read
                # operation and we will use the method 'get_read_result'
                # later on to retrieve the result.
                self._read_pending = True
            else:
                # In this case we received an unexpected error code, raise
                # an exception.
                raise NamedPipeException("Could not read from named pipe.",
                                         errCode)
            return None

        # If we can not retrieve the output from the overlapped result,
        # it means that the pipe was disconnected so we have no output.
        # The returned value should be an empty string.
        output = ""
        try:
            # Try to retrieve the result from the overlapped structure.
            # This call should succeed or otherwise will raise an exception,
            # but it will not block.
            nBytesRead = ovs_winutils.get_overlapped_result(
                handle_to_read, self._read, False)
            # Mark the read operation as complete
            self._read_pending = False
            # Retrieve the result and put the decoded result inside the
            # 'output' variable.
            output = ovs_winutils.get_decoded_buffer(
                self._read_buffer[:nBytesRead])
            # We need to manually signal the event to make sure the call to
            # wait for the event will not block.
            win32event.SetEvent(self._read.hEvent)
        except NamedPipeException as e:
            # If the pipe was disconnected, it means no output, we will return
            # an empty string in this case. Otherwise raise an exception.
            if e.code not in ovs_winutils.pipe_disconnected_errors:
                raise e
        return output