static int SOCK_get_next_n_bytes(SocketClass *self, int n, char *buf) { int retry_count = 0, gerrno, rest, rlen; BOOL maybeEOF = FALSE; if (!self || !n) return 0; for (rest = n; 0 < rest;) { if (self->buffer_read_in >= self->buffer_filled_in) { /* * there are no more bytes left in the buffer so reload the buffer */ self->buffer_read_in = 0; retry: #ifdef USE_SSL if (self->ssl) self->buffer_filled_in = SOCK_SSL_recv(self, (char *) self->buffer_in, self->buffer_size); else #endif /* USE_SSL */ self->buffer_filled_in = SOCK_SSPI_recv(self, (char *) self->buffer_in, self->buffer_size); gerrno = SOCK_ERRNO; mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size); if (self->buffer_filled_in < 0) { mylog("Lasterror=%d\n", gerrno); switch (gerrno) { case EINTR: goto retry; break; #ifdef EAGAIN case EAGAIN: #endif /* EAGAIN */ #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: #endif /* EWOULDBLOCK */ retry_count++; if (SOCK_wait_for_ready(self, FALSE, retry_count) >= 0) goto retry; break; case ECONNRESET: inolog("ECONNRESET\n"); maybeEOF = TRUE; SOCK_set_error(self, SOCKET_CLOSED, "Connection reset by peer."); break; } if (0 == self->errornumber) SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket."); self->buffer_filled_in = 0; return -1; } if (self->buffer_filled_in == 0) { if (!maybeEOF) { int nready = SOCK_wait_for_ready(self, FALSE, 0); if (nready > 0) { maybeEOF = TRUE; goto retry; } else if (0 == nready) maybeEOF = TRUE; } if (maybeEOF) { SOCK_set_error(self, SOCKET_CLOSED, "Socket has been closed."); break; } else { SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket."); return -1; } } } rlen = self->buffer_filled_in - self->buffer_read_in; if (rlen > rest) rlen = rest; if (buf) memcpy(buf + n - rest, self->buffer_in + self->buffer_read_in, rlen); rest -= rlen; if (PG_PROTOCOL_74 == self->pversion) self->reslen -= rlen; self->buffer_read_in += rlen; } return n - rest; }
UCHAR SOCK_get_next_byte(SocketClass *self, BOOL peek) { int retry_count = 0, gerrno; BOOL maybeEOF = FALSE; if (!self) return 0; if (self->buffer_read_in >= self->buffer_filled_in) { /* * there are no more bytes left in the buffer so reload the buffer */ self->buffer_read_in = 0; retry: #ifdef USE_SSL if (self->ssl) self->buffer_filled_in = SOCK_SSL_recv(self, (char *) self->buffer_in, self->buffer_size); else #endif /* USE_SSL */ self->buffer_filled_in = SOCK_SSPI_recv(self, (char *) self->buffer_in, self->buffer_size); gerrno = SOCK_ERRNO; mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size); if (self->buffer_filled_in < 0) { mylog("Lasterror=%d\n", gerrno); switch (gerrno) { case EINTR: goto retry; break; #ifdef EAGAIN case EAGAIN: #endif /* EAGAIN */ #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: #endif /* EWOULDBLOCK */ retry_count++; if (SOCK_wait_for_ready(self, FALSE, retry_count) >= 0) goto retry; break; case ECONNRESET: inolog("ECONNRESET\n"); maybeEOF = TRUE; SOCK_set_error(self, SOCKET_CLOSED, "Connection reset by peer."); break; } if (0 == self->errornumber) SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket."); self->buffer_filled_in = 0; return 0; } if (self->buffer_filled_in == 0) { if (!maybeEOF) { int nbytes = SOCK_wait_for_ready(self, FALSE, 0); if (nbytes > 0) { maybeEOF = TRUE; goto retry; } else if (0 == nbytes) maybeEOF = TRUE; } if (maybeEOF) SOCK_set_error(self, SOCKET_CLOSED, "Socket has been closed."); else SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket."); return 0; } } if (peek) return self->buffer_in[self->buffer_read_in]; if (PG_PROTOCOL_74 == self->pversion) self->reslen--; return self->buffer_in[self->buffer_read_in++]; }