Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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++];
}