/* * Read data from a secure connection. */ ssize_t secure_read(Port *port, void *ptr, size_t len) { ssize_t n; int waitfor; retry: #ifdef USE_SSL waitfor = 0; if (port->ssl_in_use) { n = be_tls_read(port, ptr, len, &waitfor); } else #endif { n = secure_raw_read(port, ptr, len); waitfor = WL_SOCKET_READABLE; } /* In blocking mode, wait until the socket is ready */ if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { int w; Assert(waitfor); w = WaitLatchOrSocket(MyLatch, WL_LATCH_SET | waitfor, port->sock, 0); /* Handle interrupt. */ if (w & WL_LATCH_SET) { ResetLatch(MyLatch); ProcessClientReadInterrupt(true); /* * We'll retry the read. Most likely it will return immediately * because there's still no data available, and we'll wait * for the socket to become ready again. */ } goto retry; } /* * Process interrupts that happened while (or before) receiving. Note that * we signal that we're not blocking, which will prevent some types of * interrupts from being processed. */ ProcessClientReadInterrupt(false); return n; }
static int my_sock_read(BIO *h, char *buf, int size) { int res = 0; if (buf != NULL) { res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size); BIO_clear_retry_flags(h); if (res <= 0) { /* If we were interrupted, tell caller to retry */ if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { BIO_set_retry_read(h); } } } return res; }