⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pqcomm.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
							 (struct sockaddr *) & port->raddr,							 &addrlen)) < 0)	{		perror("postmaster: StreamConnection: accept");		return STATUS_ERROR;	}	/* fill in the server (local) address */	addrlen = sizeof(port->laddr);	if (getsockname(port->sock, (struct sockaddr *) & port->laddr,					&addrlen) < 0)	{		perror("postmaster: StreamConnection: getsockname");		return STATUS_ERROR;	}	/* select TCP_NODELAY option if it's a TCP connection */	if (port->laddr.sa.sa_family == AF_INET)	{		struct protoent *pe;		int			on = 1;		pe = getprotobyname("TCP");		if (pe == NULL)		{			perror("postmaster: StreamConnection: getprotobyname");			return STATUS_ERROR;		}		if (setsockopt(port->sock, pe->p_proto, TCP_NODELAY,					   &on, sizeof(on)) < 0)		{			perror("postmaster: StreamConnection: setsockopt");			return STATUS_ERROR;		}	}	/* reset to non-blocking */	fcntl(port->sock, F_SETFL, 1);	return STATUS_OK;}/* * StreamClose -- close a client/backend connection */voidStreamClose(int sock){	close(sock);}/* -------------------------------- * Low-level I/O routines begin here. * * These routines communicate with a frontend client across a connection * already established by the preceding routines. * -------------------------------- *//* -------------------------------- *		pq_recvbuf - load some bytes into the input buffer * *		returns 0 if OK, EOF if trouble * -------------------------------- */static intpq_recvbuf(void){	if (PqRecvPointer > 0)	{		if (PqRecvLength > PqRecvPointer)		{			/* still some unread data, left-justify it in the buffer */			memmove(PqRecvBuffer, PqRecvBuffer + PqRecvPointer,					PqRecvLength - PqRecvPointer);			PqRecvLength -= PqRecvPointer;			PqRecvPointer = 0;		}		else			PqRecvLength = PqRecvPointer = 0;	}	/* Can fill buffer from PqRecvLength and upwards */	for (;;)	{		int			r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength,							 PQ_BUFFER_SIZE - PqRecvLength, 0);		if (r < 0)		{			if (errno == EINTR)				continue;		/* Ok if interrupted */			/*			 * We would like to use elog() here, but dare not because elog			 * tries to write to the client, which will cause problems if			 * we have a hard communications failure ... So just write the			 * message to the postmaster log.			 */			fprintf(stderr, "pq_recvbuf: recv() failed: %s\n",					strerror(errno));			return EOF;		}		if (r == 0)		{			/* as above, elog not safe */			fprintf(stderr, "pq_recvbuf: unexpected EOF on client connection\n");			return EOF;		}		/* r contains number of bytes read, so just incr length */		PqRecvLength += r;		return 0;	}}/* -------------------------------- *		pq_getbyte	- get a single byte from connection, or return EOF * -------------------------------- */static intpq_getbyte(void){	while (PqRecvPointer >= PqRecvLength)	{		if (pq_recvbuf())		/* If nothing in buffer, then recv some */			return EOF;			/* Failed to recv data */	}	return PqRecvBuffer[PqRecvPointer++];}/* -------------------------------- *		pq_peekbyte		- peek at next byte from connection * *	 Same as pq_getbyte() except we don't advance the pointer. * -------------------------------- */intpq_peekbyte(void){	while (PqRecvPointer >= PqRecvLength)	{		if (pq_recvbuf())		/* If nothing in buffer, then recv some */			return EOF;			/* Failed to recv data */	}	return PqRecvBuffer[PqRecvPointer];}/* -------------------------------- *		pq_getbytes		- get a known number of bytes from connection * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_getbytes(char *s, size_t len){	size_t		amount;	while (len > 0)	{		while (PqRecvPointer >= PqRecvLength)		{			if (pq_recvbuf())	/* If nothing in buffer, then recv some */				return EOF;		/* Failed to recv data */		}		amount = PqRecvLength - PqRecvPointer;		if (amount > len)			amount = len;		memcpy(s, PqRecvBuffer + PqRecvPointer, amount);		PqRecvPointer += amount;		s += amount;		len -= amount;	}	return 0;}/* -------------------------------- *		pq_getstring	- get a null terminated string from connection * *		NOTE: this routine does not do any MULTIBYTE conversion, *		even though it is presumably useful only for text, because *		no code in this module should depend on MULTIBYTE mode. *		See pq_getstr in pqformat.c for that. * *		FIXME: we ought to use an expansible StringInfo buffer, *		rather than dropping data if the message is too long. * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_getstring(char *s, size_t len){	int			c;	/*	 * Keep on reading until we get the terminating '\0', discarding any	 * bytes we don't have room for.	 */	while ((c = pq_getbyte()) != EOF && c != '\0')	{		if (len > 1)		{			*s++ = c;			len--;		}	}	*s = '\0';	if (c == EOF)		return EOF;	return 0;}/* -------------------------------- *		pq_putbytes		- send bytes to connection (not flushed until pq_flush) * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_putbytes(const char *s, size_t len){	size_t		amount;	while (len > 0)	{		if (PqSendPointer >= PQ_BUFFER_SIZE)			if (pq_flush())		/* If buffer is full, then flush it out */				return EOF;		amount = PQ_BUFFER_SIZE - PqSendPointer;		if (amount > len)			amount = len;		memcpy(PqSendBuffer + PqSendPointer, s, amount);		PqSendPointer += amount;		s += amount;		len -= amount;	}	return 0;}/* -------------------------------- *		pq_flush		- flush pending output * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_flush(void){	unsigned char *bufptr = PqSendBuffer;	unsigned char *bufend = PqSendBuffer + PqSendPointer;	while (bufptr < bufend)	{		int			r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0);		if (r <= 0)		{			if (errno == EINTR)				continue;		/* Ok if we were interrupted */			/*			 * We would like to use elog() here, but cannot because elog			 * tries to write to the client, which would cause a recursive			 * flush attempt!  So just write it out to the postmaster log.			 */			fprintf(stderr, "pq_flush: send() failed: %s\n",					strerror(errno));			/*			 * We drop the buffered data anyway so that processing can			 * continue, even though we'll probably quit soon.			 */			PqSendPointer = 0;			return EOF;		}		bufptr += r;	}	PqSendPointer = 0;	return 0;}/* -------------------------------- * Message-level I/O routines begin here. * * These routines understand about COPY OUT protocol. * -------------------------------- *//* -------------------------------- *		pq_putmessage	- send a normal message (suppressed in COPY OUT mode) * *		If msgtype is not '\0', it is a message type code to place before *		the message body (len counts only the body size!). *		If msgtype is '\0', then the buffer already includes the type code. * *		All normal messages are suppressed while COPY OUT is in progress. *		(In practice only NOTICE messages might get emitted then; dropping *		them is annoying, but at least they will still appear in the *		postmaster log.) * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_putmessage(char msgtype, const char *s, size_t len){	if (DoingCopyOut)		return 0;	if (msgtype)		if (pq_putbytes(&msgtype, 1))			return EOF;	return pq_putbytes(s, len);}/* -------------------------------- *		pq_startcopyout - inform libpq that a COPY OUT transfer is beginning * -------------------------------- */voidpq_startcopyout(void){	DoingCopyOut = true;}/* -------------------------------- *		pq_endcopyout	- end a COPY OUT transfer * *		If errorAbort is indicated, we are aborting a COPY OUT due to an error, *		and must send a terminator line.  Since a partial data line might have *		been emitted, send a couple of newlines first (the first one could *		get absorbed by a backslash...) * -------------------------------- */voidpq_endcopyout(bool errorAbort){	if (!DoingCopyOut)		return;	if (errorAbort)		pq_putbytes("\n\n\\.\n", 5);	/* in non-error case, copy.c will have emitted the terminator line */	DoingCopyOut = false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -