Example #1
0
 def read(self, size=-1):
     # XXX CPython uses a more delicate logic here
     ll_file = self.ll_file
     if not ll_file:
         raise ValueError("I/O operation on closed file")
     if size < 0:
         # read the entire contents
         buf = lltype.malloc(rffi.CCHARP.TO, BASE_BUF_SIZE, flavor='raw')
         try:
             s = StringBuilder()
             while True:
                 returned_size = c_fread(buf, 1, BASE_BUF_SIZE, ll_file)
                 returned_size = intmask(returned_size)  # is between 0 and BASE_BUF_SIZE
                 if returned_size == 0:
                     if c_feof(ll_file):
                         # ok, finished
                         return s.build()
                     raise _error(ll_file)
                 s.append_charpsize(buf, returned_size)
         finally:
             lltype.free(buf, flavor='raw')
     else:
         raw_buf, gc_buf = rffi.alloc_buffer(size)
         try:
             returned_size = c_fread(raw_buf, 1, size, ll_file)
             returned_size = intmask(returned_size)  # is between 0 and size
             if returned_size == 0:
                 if not c_feof(ll_file):
                     raise _error(ll_file)
             s = rffi.str_from_buffer(raw_buf, gc_buf, size, returned_size)
         finally:
             rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
         return s
Example #2
0
 def recvfrom(self, buffersize, flags=0):
     """Like recv(buffersize, flags) but also return the sender's
     address."""
     read_bytes = -1
     timeout = self._select(False)
     if timeout == 1:
         raise SocketTimeout
     elif timeout == 0:
         raw_buf, gc_buf = rffi.alloc_buffer(buffersize)
         try:
             address, addr_p, addrlen_p = self._addrbuf()
             try:
                 read_bytes = _c.recvfrom(self.fd, raw_buf, buffersize, flags,
                                          addr_p, addrlen_p)
                 addrlen = rffi.cast(lltype.Signed, addrlen_p[0])
             finally:
                 lltype.free(addrlen_p, flavor='raw')
                 address.unlock()
             if read_bytes >= 0:
                 if addrlen:
                     address.addrlen = addrlen
                 else:
                     address = None
                 data = rffi.str_from_buffer(raw_buf, gc_buf, buffersize, read_bytes)
                 return (data, address)
         finally:
             rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
     raise self.error_handler()
Example #3
0
 def _get_chunk(self, chunksize):
     assert 0 <= chunksize <= self.current_size
     raw_buf = self.raw_buf
     gc_buf = self.gc_buf
     s = rffi.str_from_buffer(raw_buf, gc_buf, self.current_size, chunksize)
     rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
     self.current_size = 0
     return s
Example #4
0
 def test_str_from_buffer(self):
     """gc-managed memory does not need to be freed"""
     size = 50
     raw_buf, gc_buf, case_num = rffi.alloc_buffer(size)
     for i in range(size): raw_buf[i] = 'a'
     rstr = rffi.str_from_buffer(raw_buf, gc_buf, case_num, size, size)
     rffi.keep_buffer_alive_until_here(raw_buf, gc_buf, case_num)
     assert not leakfinder.ALLOCATED
Example #5
0
 def test_str_from_buffer(self):
     """gc-managed memory does not need to be freed"""
     size = 50
     raw_buf, gc_buf, case_num = rffi.alloc_buffer(size)
     for i in range(size): raw_buf[i] = 'a'
     rstr = rffi.str_from_buffer(raw_buf, gc_buf, case_num, size, size)
     rffi.keep_buffer_alive_until_here(raw_buf, gc_buf, case_num)
     assert not leakfinder.ALLOCATED
Example #6
0
 def _get_chunk(self, chunksize):
     assert 0 <= chunksize <= self.current_size
     raw_buf = self.raw_buf
     gc_buf = self.gc_buf
     case_num = self.case_num
     s = rffi.str_from_buffer(raw_buf, gc_buf, case_num, self.current_size,
                              chunksize)
     rffi.keep_buffer_alive_until_here(raw_buf, gc_buf, case_num)
     self.current_size = 0
     return s
Example #7
0
    def read(self, num_bytes=1024):
        """read([len]) -> string

        Read up to len bytes from the SSL socket."""

        count = libssl_SSL_pending(self.ssl)
        if not count:
            sockstate = check_socket_and_wait_for_timeout(self.space,
                self.w_socket, False)
            if sockstate == SOCKET_HAS_TIMED_OUT:
                raise ssl_error(self.space, "The read operation timed out")
            elif sockstate == SOCKET_TOO_LARGE_FOR_SELECT:
                raise ssl_error(self.space, "Underlying socket too large for select().")
            elif sockstate == SOCKET_HAS_BEEN_CLOSED:
                if libssl_SSL_get_shutdown(self.ssl) == SSL_RECEIVED_SHUTDOWN:
                    return self.space.wrap('')
                raise ssl_error(self.space, "Socket closed without SSL shutdown handshake")

        raw_buf, gc_buf = rffi.alloc_buffer(num_bytes)
        while True:
            err = 0

            count = libssl_SSL_read(self.ssl, raw_buf, num_bytes)
            err = libssl_SSL_get_error(self.ssl, count)

            if err == SSL_ERROR_WANT_READ:
                sockstate = check_socket_and_wait_for_timeout(self.space,
                    self.w_socket, False)
            elif err == SSL_ERROR_WANT_WRITE:
                sockstate = check_socket_and_wait_for_timeout(self.space,
                    self.w_socket, True)
            elif (err == SSL_ERROR_ZERO_RETURN and
                  libssl_SSL_get_shutdown(self.ssl) == SSL_RECEIVED_SHUTDOWN):
                return self.space.wrap("")
            else:
                sockstate = SOCKET_OPERATION_OK

            if sockstate == SOCKET_HAS_TIMED_OUT:
                raise ssl_error(self.space, "The read operation timed out")
            elif sockstate == SOCKET_IS_NONBLOCKING:
                break

            if err == SSL_ERROR_WANT_READ or err == SSL_ERROR_WANT_WRITE:
                continue
            else:
                break

        if count <= 0:
            raise _ssl_seterror(self.space, self, count)

        result = rffi.str_from_buffer(raw_buf, gc_buf, num_bytes, count)
        rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
        return self.space.wrap(result)
Example #8
0
 def recv(self, buffersize, flags=0):
     """Receive up to buffersize bytes from the socket.  For the optional
     flags argument, see the Unix manual.  When no data is available, block
     until at least one byte is available or until the remote end is closed.
     When the remote end is closed and all data is read, return the empty
     string."""
     timeout = self._select(False)
     if timeout == 1:
         raise SocketTimeout
     elif timeout == 0:
         raw_buf, gc_buf = rffi.alloc_buffer(buffersize)
         try:
             read_bytes = _c.socketrecv(self.fd, raw_buf, buffersize, flags)
             if read_bytes >= 0:
                 return rffi.str_from_buffer(raw_buf, gc_buf, buffersize, read_bytes)
         finally:
             rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
     raise self.error_handler()
Example #9
0
 def readline(self):
     if self.ll_file:
         raw_buf, gc_buf = rffi.alloc_buffer(BASE_LINE_SIZE)
         try:
             c = self._readline1(raw_buf)
             if c >= 0:
                 return rffi.str_from_buffer(raw_buf, gc_buf,
                                             BASE_LINE_SIZE, c)
             #
             # this is the rare case: the line is longer than BASE_LINE_SIZE
             s = StringBuilder()
             while True:
                 s.append_charpsize(raw_buf, BASE_LINE_SIZE - 1)
                 c = self._readline1(raw_buf)
                 if c >= 0:
                     break
             #
             s.append_charpsize(raw_buf, c)
             return s.build()
         finally:
             rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
     raise ValueError("I/O operation on closed file")
Example #10
0
 def test_leak(self):
     size = 50
     raw_buf, gc_buf = rffi.alloc_buffer(size)
     for i in range(size): raw_buf[i] = 'a'
     str = rffi.str_from_buffer(raw_buf, gc_buf, size, size)
     rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)