postgresql-syntax-0.1: foreign/libpg_query/src/postgres/src_backend_libpq_pqcomm.c
/*--------------------------------------------------------------------
* Symbols referenced in this file:
* - PqCommMethods
*--------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
*
* pqcomm.c
* Communication functions between the Frontend and the Backend
*
* These routines handle the low-level details of communication between
* frontend and backend. They just shove data across the communication
* channel, and are ignorant of the semantics of the data --- or would be,
* except for major brain damage in the design of the old COPY OUT protocol.
* Unfortunately, COPY OUT was designed to commandeer the communication
* channel (it just transfers data without wrapping it into messages).
* No other messages can be sent while COPY OUT is in progress; and if the
* copy is aborted by an ereport(ERROR), we need to close out the copy so that
* the frontend gets back into sync. Therefore, these routines have to be
* aware of COPY OUT state. (New COPY-OUT is message-based and does *not*
* set the DoingCopyOut flag.)
*
* NOTE: generally, it's a bad idea to emit outgoing messages directly with
* pq_putbytes(), especially if the message would require multiple calls
* to send. Instead, use the routines in pqformat.c to construct the message
* in a buffer and then emit it in one call to pq_putmessage. This ensures
* that the channel will not be clogged by an incomplete message if execution
* is aborted by ereport(ERROR) partway through the message. The only
* non-libpq code that should call pq_putbytes directly is old-style COPY OUT.
*
* At one time, libpq was shared between frontend and backend, but now
* the backend's "backend/libpq" is quite separate from "interfaces/libpq".
* All that remains is similarities of names to trap the unwary...
*
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/backend/libpq/pqcomm.c
*
*-------------------------------------------------------------------------
*/
/*------------------------
* INTERFACE ROUTINES
*
* setup/teardown:
* StreamServerPort - Open postmaster's server port
* StreamConnection - Create new connection with client
* StreamClose - Close a client/backend connection
* TouchSocketFiles - Protect socket files against /tmp cleaners
* pq_init - initialize libpq at backend startup
* pq_comm_reset - reset libpq during error recovery
* pq_close - shutdown libpq at backend exit
*
* low-level I/O:
* pq_getbytes - get a known number of bytes from connection
* pq_getstring - get a null terminated string from connection
* pq_getmessage - get a message with length word from connection
* pq_getbyte - get next byte from connection
* pq_peekbyte - peek at next byte from connection
* pq_putbytes - send bytes to connection (not flushed until pq_flush)
* pq_flush - flush pending output
* pq_flush_if_writable - flush pending output if writable without blocking
* pq_getbyte_if_available - get a byte if available without blocking
*
* message-level I/O (and old-style-COPY-OUT cruft):
* pq_putmessage - send a normal message (suppressed in COPY OUT mode)
* pq_putmessage_noblock - buffer a normal message (suppressed in COPY OUT)
* pq_startcopyout - inform libpq that a COPY OUT transfer is beginning
* pq_endcopyout - end a COPY OUT transfer
*
*------------------------
*/
#include "postgres.h"
#include <signal.h>
#include <fcntl.h>
#include <grp.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef WIN32_ONLY_COMPILER /* mstcpip.h is missing on mingw */
#include <mstcpip.h>
#endif
#include "libpq/ip.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/memutils.h"
/*
* Configuration options
*/
/* Where the Unix socket files are (list of palloc'd strings) */
/*
* Buffers for low-level I/O.
*
* The receive buffer is fixed size. Send buffer is usually 8k, but can be
* enlarged by pq_putmessage_noblock() if the message doesn't fit otherwise.
*/
#define PQ_SEND_BUFFER_SIZE 8192
#define PQ_RECV_BUFFER_SIZE 8192
/* Size send buffer */
/* Next index to store a byte in PqSendBuffer */
/* Next index to send a byte in PqSendBuffer */
/* Next index to read a byte from PqRecvBuffer */
/* End of data available in PqRecvBuffer */
/*
* Message status
*/
/* busy sending data to the client */
/* in the middle of reading a message */
/* in old-protocol COPY OUT processing */
/* Internal functions */
static void socket_comm_reset(void);
static void socket_close(int code, Datum arg);
static void socket_set_nonblocking(bool nonblocking);
static int socket_flush(void);
static int socket_flush_if_writable(void);
static bool socket_is_send_pending(void);
static int socket_putmessage(char msgtype, const char *s, size_t len);
static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
static void socket_startcopyout(void);
static void socket_endcopyout(bool errorAbort);
static int internal_putbytes(const char *s, size_t len);
static int internal_flush(void);
static void socket_set_nonblocking(bool nonblocking);
#ifdef HAVE_UNIX_SOCKETS
static int Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath);
static int Setup_AF_UNIX(char *sock_path);
#endif /* HAVE_UNIX_SOCKETS */
PQcommMethods *PqCommMethods = NULL;
/* --------------------------------
* pq_init - initialize libpq at backend startup
* --------------------------------
*/
#ifndef WIN32
#endif
/* --------------------------------
* socket_comm_reset - reset libpq during error recovery
*
* This is called from error recovery at the outer idle loop. It's
* just to get us out of trouble if we somehow manage to elog() from
* inside a pqcomm.c routine (which ideally will never happen, but...)
* --------------------------------
*/
/* --------------------------------
* socket_close - shutdown libpq at backend exit
*
* This is the one pg_on_exit_callback in place during BackendInitialize().
* That function's unusual signal handling constrains that this callback be
* safe to run at any instant.
* --------------------------------
*/
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
#ifdef ENABLE_GSS
#endif /* ENABLE_GSS */
#endif /* ENABLE_GSS || ENABLE_SSPI */
/*
* Streams -- wrapper around Unix socket system calls
*
*
* Stream functions are used for vanilla TCP connection protocol.
*/
/*
* StreamServerPort -- open a "listening" port to accept connections.
*
* family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
* For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
* specified. For TCP ports, hostName is either NULL for all interfaces or
* the interface to listen on, and unixSocketDir is ignored (can be NULL).
*
* Successfully opened sockets are added to the ListenSocket[] array (of
* length MaxListen), at the first position that isn't PGINVALID_SOCKET.
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
#ifdef HAVE_UNIX_SOCKETS
#endif
#if !defined(WIN32) || defined(IPV6_V6ONLY)
#endif
#ifdef HAVE_UNIX_SOCKETS
#endif /* HAVE_UNIX_SOCKETS */
#ifdef HAVE_IPV6
#endif
#ifdef HAVE_UNIX_SOCKETS
#endif
#ifndef WIN32
#endif
#ifdef IPV6_V6ONLY
#endif
#ifdef HAVE_UNIX_SOCKETS
#endif
#ifdef HAVE_UNIX_SOCKETS
/*
* Lock_AF_UNIX -- configure unix socket file path
*/
/*
* Setup_AF_UNIX -- configure unix socket permissions
*/
#ifdef WIN32
#else
#endif
#endif /* HAVE_UNIX_SOCKETS */
/*
* StreamConnection -- create a new connection with client using
* server port. Set port->sock to the FD of the new connection.
*
* ASSUME: that this doesn't need to be non-blocking because
* the Postmaster uses select() to tell when the server master
* socket is ready for accept().
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
#ifdef SCO_ACCEPT_BUG
#endif
#ifdef TCP_NODELAY
#endif
#ifdef WIN32
#endif
/*
* StreamClose -- close a client/backend connection
*
* NOTE: this is NOT used to terminate a session; it is just used to release
* the file descriptor in a process that should no longer have the socket
* open. (For example, the postmaster calls this after passing ownership
* of the connection to a child process.) It is expected that someone else
* still has the socket open. So, we only want to close the descriptor,
* we do NOT want to send anything to the far end.
*/
/*
* TouchSocketFiles -- mark socket files as recently accessed
*
* This routine should be called every so often to ensure that the socket
* files have a recent mod date (ordinary operations on sockets usually won't
* change the mod date). That saves them from being removed by
* overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should
* never have put the socket file in /tmp...)
*/
#ifdef HAVE_UTIME
#else /* !HAVE_UTIME */
#ifdef HAVE_UTIMES
#endif /* HAVE_UTIMES */
#endif /* HAVE_UTIME */
/*
* RemoveSocketFiles -- unlink socket files at postmaster shutdown
*/
/* --------------------------------
* Low-level I/O routines begin here.
*
* These routines communicate with a frontend client across a connection
* already established by the preceding routines.
* --------------------------------
*/
/* --------------------------------
* socket_set_nonblocking - set socket blocking/non-blocking
*
* Sets the socket non-blocking if nonblocking is TRUE, or sets it
* blocking otherwise.
* --------------------------------
*/
/* --------------------------------
* pq_recvbuf - load some bytes into the input buffer
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_getbyte - get a single byte from connection, or return EOF
* --------------------------------
*/
/* --------------------------------
* pq_peekbyte - peek at next byte from connection
*
* Same as pq_getbyte() except we don't advance the pointer.
* --------------------------------
*/
/* --------------------------------
* pq_getbyte_if_available - get a single byte from connection,
* if available
*
* The received byte is stored in *c. Returns 1 if a byte was read,
* 0 if no data was available, or EOF if trouble.
* --------------------------------
*/
/* --------------------------------
* pq_getbytes - get a known number of bytes from connection
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_discardbytes - throw away a known number of bytes
*
* same as pq_getbytes except we do not copy the data to anyplace.
* this is used for resynchronizing after read errors.
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_getstring - get a null terminated string from connection
*
* The return value is placed in an expansible StringInfo, which has
* already been initialized by the caller.
*
* This is used only for dealing with old-protocol clients. The idea
* is to produce a StringInfo that looks the same as we would get from
* pq_getmessage() with a newer client; we will then process it with
* pq_getmsgstring. Therefore, no character set conversion is done here,
* even though this is presumably useful only for text.
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_startmsgread - begin reading a message from the client.
*
* This must be called before any of the pq_get* functions.
* --------------------------------
*/
/* --------------------------------
* pq_endmsgread - finish reading message.
*
* This must be called after reading a V2 protocol message with
* pq_getstring() and friends, to indicate that we have read the whole
* message. In V3 protocol, pq_getmessage() does this implicitly.
* --------------------------------
*/
/* --------------------------------
* pq_is_reading_msg - are we currently reading a message?
*
* This is used in error recovery at the outer idle loop to detect if we have
* lost protocol sync, and need to terminate the connection. pq_startmsgread()
* will check for that too, but it's nicer to detect it earlier.
* --------------------------------
*/
/* --------------------------------
* pq_getmessage - get a message with length word from connection
*
* The return value is placed in an expansible StringInfo, which has
* already been initialized by the caller.
* Only the message body is placed in the StringInfo; the length word
* is removed. Also, s->cursor is initialized to zero for convenience
* in scanning the message contents.
*
* If maxlen is not zero, it is an upper limit on the length of the
* message we are willing to accept. We abort the connection (by
* returning EOF) if client tries to send more than that.
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_putbytes - send bytes to connection (not flushed until pq_flush)
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* socket_flush - flush pending output
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* internal_flush - flush pending output
*
* Returns 0 if OK (meaning everything was sent, or operation would block
* and the socket is in non-blocking mode), or EOF if trouble.
* --------------------------------
*/
/* --------------------------------
* pq_flush_if_writable - flush pending output if writable without blocking
*
* Returns 0 if OK, or EOF if trouble.
* --------------------------------
*/
/* --------------------------------
* socket_is_send_pending - is there any pending data in the output buffer?
* --------------------------------
*/
/* --------------------------------
* Message-level I/O routines begin here.
*
* These routines understand about the old-style COPY OUT protocol.
* --------------------------------
*/
/* --------------------------------
* socket_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. If msgtype is '\0', then the message has no type
* code (this is only valid in pre-3.0 protocols).
*
* len is the length of the message body data at *s. In protocol 3.0
* and later, a message length word (equal to len+4 because it counts
* itself too) is inserted by this routine.
*
* All normal messages are suppressed while old-style COPY OUT is in
* progress. (In practice only a few notice messages might get emitted
* then; dropping them is annoying, but at least they will still appear
* in the postmaster log.)
*
* We also suppress messages generated while pqcomm.c is busy. This
* avoids any possibility of messages being inserted within other
* messages. The only known trouble case arises if SIGQUIT occurs
* during a pqcomm.c routine --- quickdie() will try to send a warning
* message, and the most reasonable approach seems to be to drop it.
*
* returns 0 if OK, EOF if trouble
* --------------------------------
*/
/* --------------------------------
* pq_putmessage_noblock - like pq_putmessage, but never blocks
*
* If the output buffer is too small to hold the message, the buffer
* is enlarged.
*/
/* --------------------------------
* socket_startcopyout - inform libpq that an old-style COPY OUT transfer
* is beginning
* --------------------------------
*/
/* --------------------------------
* socket_endcopyout - end an old-style 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...) Note that old-style COPY OUT does
* not allow binary transfers, so a textual terminator is always correct.
* --------------------------------
*/
/*
* Support for TCP Keepalive parameters
*/
/*
* On Windows, we need to set both idle and interval at the same time.
* We also cannot reset them to the default (setting to zero will
* actually set them to zero, not default), therefore we fallback to
* the out-of-the-box default instead.
*/
#if defined(WIN32) && defined(SIO_KEEPALIVE_VALS)
static int
pq_setkeepaliveswin32(Port *port, int idle, int interval)
{
struct tcp_keepalive ka;
DWORD retsize;
if (idle <= 0)
idle = 2 * 60 * 60; /* default = 2 hours */
if (interval <= 0)
interval = 1; /* default = 1 second */
ka.onoff = 1;
ka.keepalivetime = idle * 1000;
ka.keepaliveinterval = interval * 1000;
if (WSAIoctl(port->sock,
SIO_KEEPALIVE_VALS,
(LPVOID) &ka,
sizeof(ka),
NULL,
0,
&retsize,
NULL,
NULL)
!= 0)
{
elog(LOG, "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui",
WSAGetLastError());
return STATUS_ERROR;
}
if (port->keepalives_idle != idle)
port->keepalives_idle = idle;
if (port->keepalives_interval != interval)
port->keepalives_interval = interval;
return STATUS_OK;
}
#endif
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(WIN32)
#ifndef WIN32
#ifdef TCP_KEEPIDLE
#else
#endif /* TCP_KEEPIDLE */
#else /* WIN32 */
#endif /* WIN32 */
#else
#endif
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
#ifndef WIN32
#ifdef TCP_KEEPIDLE
#else
#endif
#else /* WIN32 */
#endif
#else /* TCP_KEEPIDLE || SIO_KEEPALIVE_VALS */
#endif
#if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
#ifndef WIN32
#else
#endif /* WIN32 */
#else
#endif
#if defined(TCP_KEEPINTVL) || defined (SIO_KEEPALIVE_VALS)
#ifndef WIN32
#else /* WIN32 */
#endif
#else
#endif
#ifdef TCP_KEEPCNT
#else
#endif
#ifdef TCP_KEEPCNT
#else
#endif