1
/*-------------------------------------------------------------------------
4
* Communication functions between the Frontend and the Backend
6
* These routines handle the low-level details of communication between
7
* frontend and backend. They just shove data across the communication
8
* channel, and are ignorant of the semantics of the data --- or would be,
9
* except for major brain damage in the design of the old COPY OUT protocol.
10
* Unfortunately, COPY OUT was designed to commandeer the communication
11
* channel (it just transfers data without wrapping it into messages).
12
* No other messages can be sent while COPY OUT is in progress; and if the
13
* copy is aborted by an ereport(ERROR), we need to close out the copy so that
14
* the frontend gets back into sync. Therefore, these routines have to be
15
* aware of COPY OUT state. (New COPY-OUT is message-based and does *not*
16
* set the DoingCopyOut flag.)
18
* NOTE: generally, it's a bad idea to emit outgoing messages directly with
19
* pq_putbytes(), especially if the message would require multiple calls
20
* to send. Instead, use the routines in pqformat.c to construct the message
21
* in a buffer and then emit it in one call to pq_putmessage. This ensures
22
* that the channel will not be clogged by an incomplete message if execution
23
* is aborted by ereport(ERROR) partway through the message. The only
24
* non-libpq code that should call pq_putbytes directly is old-style COPY OUT.
26
* At one time, libpq was shared between frontend and backend, but now
27
* the backend's "backend/libpq" is quite separate from "interfaces/libpq".
28
* All that remains is similarities of names to trap the unwary...
30
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
31
* Portions Copyright (c) 1994, Regents of the University of California
33
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.175 2005-01-12 16:38:17 tgl Exp $
35
*-------------------------------------------------------------------------
38
/*------------------------
42
* StreamServerPort - Open postmaster's server port
43
* StreamConnection - Create new connection with client
44
* StreamClose - Close a client/backend connection
45
* TouchSocketFile - Protect socket file against /tmp cleaners
46
* pq_init - initialize libpq at backend startup
47
* pq_comm_reset - reset libpq during error recovery
48
* pq_close - shutdown libpq at backend exit
51
* pq_getbytes - get a known number of bytes from connection
52
* pq_getstring - get a null terminated string from connection
53
* pq_getmessage - get a message with length word from connection
54
* pq_getbyte - get next byte from connection
55
* pq_peekbyte - peek at next byte from connection
56
* pq_putbytes - send bytes to connection (not flushed until pq_flush)
57
* pq_flush - flush pending output
59
* message-level I/O (and old-style-COPY-OUT cruft):
60
* pq_putmessage - send a normal message (suppressed in COPY OUT mode)
61
* pq_startcopyout - inform libpq that a COPY OUT transfer is beginning
62
* pq_endcopyout - end a COPY OUT transfer
64
*------------------------
74
#include <sys/socket.h>
78
#include <netinet/in.h>
79
#ifdef HAVE_NETINET_TCP_H
80
#include <netinet/tcp.h>
82
#include <arpa/inet.h>
87
#include "libpq/libpq.h"
88
#include "miscadmin.h"
89
#include "storage/ipc.h"
93
* Configuration options
95
int Unix_socket_permissions;
96
char *Unix_socket_group;
99
/* Where the Unix socket file is */
100
static char sock_path[MAXPGPATH];
104
* Buffers for low-level I/O
107
#define PQ_BUFFER_SIZE 8192
109
static unsigned char PqSendBuffer[PQ_BUFFER_SIZE];
110
static int PqSendPointer; /* Next index to store a byte in
113
static unsigned char PqRecvBuffer[PQ_BUFFER_SIZE];
114
static int PqRecvPointer; /* Next index to read a byte from
116
static int PqRecvLength; /* End of data available in PqRecvBuffer */
121
static bool PqCommBusy;
122
static bool DoingCopyOut;
125
/* Internal functions */
126
static void pq_close(int code, Datum arg);
127
static int internal_putbytes(const char *s, size_t len);
128
static int internal_flush(void);
129
#ifdef HAVE_UNIX_SOCKETS
130
static int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName);
131
static int Setup_AF_UNIX(void);
132
#endif /* HAVE_UNIX_SOCKETS */
135
/* --------------------------------
136
* pq_init - initialize libpq at backend startup
137
* --------------------------------
142
PqSendPointer = PqRecvPointer = PqRecvLength = 0;
144
DoingCopyOut = false;
145
on_proc_exit(pq_close, 0);
148
/* --------------------------------
149
* pq_comm_reset - reset libpq during error recovery
151
* This is called from error recovery at the outer idle loop. It's
152
* just to get us out of trouble if we somehow manage to elog() from
153
* inside a pqcomm.c routine (which ideally will never happen, but...)
154
* --------------------------------
159
/* Do not throw away pending data, but do reset the busy flag */
161
/* We can abort any old-style COPY OUT, too */
165
/* --------------------------------
166
* pq_close - shutdown libpq at backend exit
168
* Note: in a standalone backend MyProcPort will be null,
169
* don't crash during exit...
170
* --------------------------------
173
pq_close(int code, Datum arg)
175
if (MyProcPort != NULL)
177
/* Cleanly shut down SSL layer */
178
secure_close(MyProcPort);
181
* Formerly we did an explicit close() here, but it seems better
182
* to leave the socket open until the process dies. This allows
183
* clients to perform a "synchronous close" if they care --- wait
184
* till the transport layer reports connection closure, and you
185
* can be sure the backend has exited.
187
* We do set sock to -1 to prevent any further I/O, though.
189
MyProcPort->sock = -1;
196
* Streams -- wrapper around Unix socket system calls
199
* Stream functions are used for vanilla TCP connection protocol.
204
* Shutdown routine for backend connection
205
* If a Unix socket is used for communication, explicitly close it.
207
#ifdef HAVE_UNIX_SOCKETS
209
StreamDoUnlink(int code, Datum arg)
211
Assert(sock_path[0]);
214
#endif /* HAVE_UNIX_SOCKETS */
217
* StreamServerPort -- open a "listening" port to accept connections.
219
* Successfully opened sockets are added to the ListenSocket[] array,
220
* at the first position that isn't -1.
222
* RETURNS: STATUS_OK or STATUS_ERROR
226
StreamServerPort(int family, char *hostName, unsigned short portNumber,
227
char *unixSocketName,
228
int ListenSocket[], int MaxListen)
235
char portNumberStr[32];
236
const char *familyDesc;
237
char familyDescBuf[64];
239
struct addrinfo *addrs = NULL,
241
struct addrinfo hint;
242
int listen_index = 0;
245
/* Initialize hint structure */
246
MemSet(&hint, 0, sizeof(hint));
247
hint.ai_family = family;
248
hint.ai_flags = AI_PASSIVE;
249
hint.ai_socktype = SOCK_STREAM;
251
#ifdef HAVE_UNIX_SOCKETS
252
if (family == AF_UNIX)
254
/* Lock_AF_UNIX will also fill in sock_path. */
255
if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
260
#endif /* HAVE_UNIX_SOCKETS */
262
snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
263
service = portNumberStr;
266
ret = getaddrinfo_all(hostName, service, &hint, &addrs);
271
(errmsg("could not translate host name \"%s\", service \"%s\" to address: %s",
272
hostName, service, gai_strerror(ret))));
275
(errmsg("could not translate service \"%s\" to address: %s",
276
service, gai_strerror(ret))));
278
freeaddrinfo_all(hint.ai_family, addrs);
282
for (addr = addrs; addr; addr = addr->ai_next)
284
if (!IS_AF_UNIX(family) && IS_AF_UNIX(addr->ai_family))
287
* Only set up a unix domain socket when they really asked for
288
* it. The service/port is different in that case.
293
/* See if there is still room to add 1 more socket. */
294
for (; listen_index < MaxListen; listen_index++)
296
if (ListenSocket[listen_index] == -1)
299
if (listen_index >= MaxListen)
302
(errmsg("could not bind to all requested addresses: MAXLISTEN (%d) exceeded",
307
/* set up family name for possible error messages */
308
switch (addr->ai_family)
311
familyDesc = gettext("IPv4");
315
familyDesc = gettext("IPv6");
318
#ifdef HAVE_UNIX_SOCKETS
320
familyDesc = gettext("Unix");
324
snprintf(familyDescBuf, sizeof(familyDescBuf),
325
gettext("unrecognized address family %d"),
327
familyDesc = familyDescBuf;
331
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
334
(errcode_for_socket_access(),
335
/* translator: %s is IPv4, IPv6, or Unix */
336
errmsg("could not create %s socket: %m",
341
if (!IS_AF_UNIX(addr->ai_family))
343
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
344
(char *) &one, sizeof(one))) == -1)
347
(errcode_for_socket_access(),
348
errmsg("setsockopt(SO_REUSEADDR) failed: %m")));
355
if (addr->ai_family == AF_INET6)
357
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
358
(char *) &one, sizeof(one)) == -1)
361
(errcode_for_socket_access(),
362
errmsg("setsockopt(IPV6_V6ONLY) failed: %m")));
370
* Note: This might fail on some OS's, like Linux older than
371
* 2.4.21-pre3, that don't have the IPV6_V6ONLY socket option, and
372
* map ipv4 addresses to ipv6. It will show ::ffff:ipv4 for all
375
err = bind(fd, addr->ai_addr, addr->ai_addrlen);
379
(errcode_for_socket_access(),
380
/* translator: %s is IPv4, IPv6, or Unix */
381
errmsg("could not bind %s socket: %m",
383
(IS_AF_UNIX(addr->ai_family)) ?
384
errhint("Is another postmaster already running on port %d?"
385
" If not, remove socket file \"%s\" and retry.",
386
(int) portNumber, sock_path) :
387
errhint("Is another postmaster already running on port %d?"
388
" If not, wait a few seconds and retry.",
394
#ifdef HAVE_UNIX_SOCKETS
395
if (addr->ai_family == AF_UNIX)
397
if (Setup_AF_UNIX() != STATUS_OK)
406
* Select appropriate accept-queue length limit. PG_SOMAXCONN is
407
* only intended to provide a clamp on the request on platforms
408
* where an overly large request provokes a kernel error (are
411
maxconn = MaxBackends * 2;
412
if (maxconn > PG_SOMAXCONN)
413
maxconn = PG_SOMAXCONN;
415
err = listen(fd, maxconn);
419
(errcode_for_socket_access(),
420
/* translator: %s is IPv4, IPv6, or Unix */
421
errmsg("could not listen on %s socket: %m",
426
ListenSocket[listen_index] = fd;
430
freeaddrinfo_all(hint.ai_family, addrs);
439
#ifdef HAVE_UNIX_SOCKETS
442
* Lock_AF_UNIX -- configure unix socket file path
445
Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
447
UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
450
* Grab an interlock file associated with the socket file.
452
CreateSocketLockFile(sock_path, true);
455
* Once we have the interlock, we can safely delete any pre-existing
456
* socket file to avoid failure at bind() time.
465
* Setup_AF_UNIX -- configure unix socket permissions
470
/* Arrange to unlink the socket file at exit */
471
on_proc_exit(StreamDoUnlink, 0);
474
* Fix socket ownership/permission if requested. Note we must do this
475
* before we listen() to avoid a window where unwanted connections
476
* could get accepted.
478
Assert(Unix_socket_group);
479
if (Unix_socket_group[0] != '\0')
482
elog(WARNING, "configuration item unix_socket_group is not supported on this platform");
485
unsigned long int val;
488
val = strtoul(Unix_socket_group, &endptr, 10);
490
{ /* numeric group id */
494
{ /* convert group name to id */
497
gr = getgrnam(Unix_socket_group);
501
(errmsg("group \"%s\" does not exist",
502
Unix_socket_group)));
507
if (chown(sock_path, -1, gid) == -1)
510
(errcode_for_file_access(),
511
errmsg("could not set group of file \"%s\": %m",
518
if (chmod(sock_path, Unix_socket_permissions) == -1)
521
(errcode_for_file_access(),
522
errmsg("could not set permissions of file \"%s\": %m",
528
#endif /* HAVE_UNIX_SOCKETS */
532
* StreamConnection -- create a new connection with client using
535
* ASSUME: that this doesn't need to be non-blocking because
536
* the Postmaster uses select() to tell when the server master
537
* socket is ready for accept().
539
* RETURNS: STATUS_OK or STATUS_ERROR
542
StreamConnection(int server_fd, Port *port)
544
/* accept connection and fill in the client (remote) address */
545
port->raddr.salen = sizeof(port->raddr.addr);
546
if ((port->sock = accept(server_fd,
547
(struct sockaddr *) & port->raddr.addr,
548
&port->raddr.salen)) < 0)
551
(errcode_for_socket_access(),
552
errmsg("could not accept new connection: %m")));
556
#ifdef SCO_ACCEPT_BUG
559
* UnixWare 7+ and OpenServer 5.0.4 are known to have this bug, but it
560
* shouldn't hurt to catch it for all versions of those platforms.
562
if (port->raddr.addr.ss_family == 0)
563
port->raddr.addr.ss_family = AF_UNIX;
566
/* fill in the server (local) address */
567
port->laddr.salen = sizeof(port->laddr.addr);
568
if (getsockname(port->sock,
569
(struct sockaddr *) & port->laddr.addr,
570
&port->laddr.salen) < 0)
572
elog(LOG, "getsockname() failed: %m");
576
/* select NODELAY and KEEPALIVE options if it's a TCP connection */
577
if (!IS_AF_UNIX(port->laddr.addr.ss_family))
583
if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY,
584
(char *) &on, sizeof(on)) < 0)
586
elog(LOG, "setsockopt(TCP_NODELAY) failed: %m");
591
if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE,
592
(char *) &on, sizeof(on)) < 0)
594
elog(LOG, "setsockopt(SO_KEEPALIVE) failed: %m");
603
* StreamClose -- close a client/backend connection
605
* NOTE: this is NOT used to terminate a session; it is just used to release
606
* the file descriptor in a process that should no longer have the socket
607
* open. (For example, the postmaster calls this after passing ownership
608
* of the connection to a child process.) It is expected that someone else
609
* still has the socket open. So, we only want to close the descriptor,
610
* we do NOT want to send anything to the far end.
613
StreamClose(int sock)
619
* TouchSocketFile -- mark socket file as recently accessed
621
* This routine should be called every so often to ensure that the socket
622
* file has a recent mod date (ordinary operations on sockets usually won't
623
* change the mod date). That saves it from being removed by
624
* overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should
625
* never have put the socket file in /tmp...)
628
TouchSocketFile(void)
630
/* Do nothing if we did not create a socket... */
631
if (sock_path[0] != '\0')
634
* utime() is POSIX standard, utimes() is a common alternative. If
635
* we have neither, there's no way to affect the mod or access
636
* time of the socket :-(
638
* In either path, we ignore errors; there's no point in complaining.
641
utime(sock_path, NULL);
642
#else /* !HAVE_UTIME */
644
utimes(sock_path, NULL);
645
#endif /* HAVE_UTIMES */
646
#endif /* HAVE_UTIME */
651
/* --------------------------------
652
* Low-level I/O routines begin here.
654
* These routines communicate with a frontend client across a connection
655
* already established by the preceding routines.
656
* --------------------------------
660
/* --------------------------------
661
* pq_recvbuf - load some bytes into the input buffer
663
* returns 0 if OK, EOF if trouble
664
* --------------------------------
669
if (PqRecvPointer > 0)
671
if (PqRecvLength > PqRecvPointer)
673
/* still some unread data, left-justify it in the buffer */
674
memmove(PqRecvBuffer, PqRecvBuffer + PqRecvPointer,
675
PqRecvLength - PqRecvPointer);
676
PqRecvLength -= PqRecvPointer;
680
PqRecvLength = PqRecvPointer = 0;
683
/* Can fill buffer from PqRecvLength and upwards */
688
r = secure_read(MyProcPort, PqRecvBuffer + PqRecvLength,
689
PQ_BUFFER_SIZE - PqRecvLength);
694
continue; /* Ok if interrupted */
697
* Careful: an ereport() that tries to write to the client
698
* would cause recursion to here, leading to stack overflow
699
* and core dump! This message must go *only* to the
703
(errcode_for_socket_access(),
704
errmsg("could not receive data from client: %m")));
710
* EOF detected. We used to write a log message here, but
711
* it's better to expect the ultimate caller to do that.
715
/* r contains number of bytes read, so just incr length */
721
/* --------------------------------
722
* pq_getbyte - get a single byte from connection, or return EOF
723
* --------------------------------
728
while (PqRecvPointer >= PqRecvLength)
730
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
731
return EOF; /* Failed to recv data */
733
return PqRecvBuffer[PqRecvPointer++];
736
/* --------------------------------
737
* pq_peekbyte - peek at next byte from connection
739
* Same as pq_getbyte() except we don't advance the pointer.
740
* --------------------------------
745
while (PqRecvPointer >= PqRecvLength)
747
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
748
return EOF; /* Failed to recv data */
750
return PqRecvBuffer[PqRecvPointer];
753
/* --------------------------------
754
* pq_getbytes - get a known number of bytes from connection
756
* returns 0 if OK, EOF if trouble
757
* --------------------------------
760
pq_getbytes(char *s, size_t len)
766
while (PqRecvPointer >= PqRecvLength)
768
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
769
return EOF; /* Failed to recv data */
771
amount = PqRecvLength - PqRecvPointer;
774
memcpy(s, PqRecvBuffer + PqRecvPointer, amount);
775
PqRecvPointer += amount;
782
/* --------------------------------
783
* pq_discardbytes - throw away a known number of bytes
785
* same as pq_getbytes except we do not copy the data to anyplace.
786
* this is used for resynchronizing after read errors.
788
* returns 0 if OK, EOF if trouble
789
* --------------------------------
792
pq_discardbytes(size_t len)
798
while (PqRecvPointer >= PqRecvLength)
800
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
801
return EOF; /* Failed to recv data */
803
amount = PqRecvLength - PqRecvPointer;
806
PqRecvPointer += amount;
812
/* --------------------------------
813
* pq_getstring - get a null terminated string from connection
815
* The return value is placed in an expansible StringInfo, which has
816
* already been initialized by the caller.
818
* This is used only for dealing with old-protocol clients. The idea
819
* is to produce a StringInfo that looks the same as we would get from
820
* pq_getmessage() with a newer client; we will then process it with
821
* pq_getmsgstring. Therefore, no character set conversion is done here,
822
* even though this is presumably useful only for text.
824
* returns 0 if OK, EOF if trouble
825
* --------------------------------
828
pq_getstring(StringInfo s)
832
/* Reset string to empty */
837
/* Read until we get the terminating '\0' */
840
while (PqRecvPointer >= PqRecvLength)
842
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
843
return EOF; /* Failed to recv data */
846
for (i = PqRecvPointer; i < PqRecvLength; i++)
848
if (PqRecvBuffer[i] == '\0')
850
/* include the '\0' in the copy */
851
appendBinaryStringInfo(s, PqRecvBuffer + PqRecvPointer,
852
i - PqRecvPointer + 1);
853
PqRecvPointer = i + 1; /* advance past \0 */
858
/* If we're here we haven't got the \0 in the buffer yet. */
859
appendBinaryStringInfo(s, PqRecvBuffer + PqRecvPointer,
860
PqRecvLength - PqRecvPointer);
861
PqRecvPointer = PqRecvLength;
866
/* --------------------------------
867
* pq_getmessage - get a message with length word from connection
869
* The return value is placed in an expansible StringInfo, which has
870
* already been initialized by the caller.
871
* Only the message body is placed in the StringInfo; the length word
872
* is removed. Also, s->cursor is initialized to zero for convenience
873
* in scanning the message contents.
875
* If maxlen is not zero, it is an upper limit on the length of the
876
* message we are willing to accept. We abort the connection (by
877
* returning EOF) if client tries to send more than that.
879
* returns 0 if OK, EOF if trouble
880
* --------------------------------
883
pq_getmessage(StringInfo s, int maxlen)
887
/* Reset message buffer to empty */
892
/* Read message length word */
893
if (pq_getbytes((char *) &len, 4) == EOF)
896
(errcode(ERRCODE_PROTOCOL_VIOLATION),
897
errmsg("unexpected EOF within message length word")));
904
(maxlen > 0 && len > maxlen))
907
(errcode(ERRCODE_PROTOCOL_VIOLATION),
908
errmsg("invalid message length")));
912
len -= 4; /* discount length itself */
917
* Allocate space for message. If we run out of room (ridiculously
918
* large message), we will elog(ERROR), but we want to discard the
919
* message body so as not to lose communication sync.
923
enlargeStringInfo(s, len);
927
if (pq_discardbytes(len) == EOF)
929
(errcode(ERRCODE_PROTOCOL_VIOLATION),
930
errmsg("incomplete message from client")));
935
/* And grab the message */
936
if (pq_getbytes(s->data, len) == EOF)
939
(errcode(ERRCODE_PROTOCOL_VIOLATION),
940
errmsg("incomplete message from client")));
944
/* Place a trailing null per StringInfo convention */
952
/* --------------------------------
953
* pq_putbytes - send bytes to connection (not flushed until pq_flush)
955
* returns 0 if OK, EOF if trouble
956
* --------------------------------
959
pq_putbytes(const char *s, size_t len)
963
/* Should only be called by old-style COPY OUT */
964
Assert(DoingCopyOut);
965
/* No-op if reentrant call */
969
res = internal_putbytes(s, len);
975
internal_putbytes(const char *s, size_t len)
981
/* If buffer is full, then flush it out */
982
if (PqSendPointer >= PQ_BUFFER_SIZE)
983
if (internal_flush())
985
amount = PQ_BUFFER_SIZE - PqSendPointer;
988
memcpy(PqSendBuffer + PqSendPointer, s, amount);
989
PqSendPointer += amount;
996
/* --------------------------------
997
* pq_flush - flush pending output
999
* returns 0 if OK, EOF if trouble
1000
* --------------------------------
1007
/* No-op if reentrant call */
1011
res = internal_flush();
1017
internal_flush(void)
1019
static int last_reported_send_errno = 0;
1021
unsigned char *bufptr = PqSendBuffer;
1022
unsigned char *bufend = PqSendBuffer + PqSendPointer;
1024
while (bufptr < bufend)
1028
r = secure_write(MyProcPort, bufptr, bufend - bufptr);
1033
continue; /* Ok if we were interrupted */
1036
* Careful: an ereport() that tries to write to the client
1037
* would cause recursion to here, leading to stack overflow
1038
* and core dump! This message must go *only* to the
1041
* If a client disconnects while we're in the midst of output, we
1042
* might write quite a bit of data before we get to a safe
1043
* query abort point. So, suppress duplicate log messages.
1045
if (errno != last_reported_send_errno)
1047
last_reported_send_errno = errno;
1049
(errcode_for_socket_access(),
1050
errmsg("could not send data to client: %m")));
1054
* We drop the buffered data anyway so that processing can
1055
* continue, even though we'll probably quit soon.
1061
last_reported_send_errno = 0; /* reset after any successful send */
1070
/* --------------------------------
1071
* Message-level I/O routines begin here.
1073
* These routines understand about the old-style COPY OUT protocol.
1074
* --------------------------------
1078
/* --------------------------------
1079
* pq_putmessage - send a normal message (suppressed in COPY OUT mode)
1081
* If msgtype is not '\0', it is a message type code to place before
1082
* the message body. If msgtype is '\0', then the message has no type
1083
* code (this is only valid in pre-3.0 protocols).
1085
* len is the length of the message body data at *s. In protocol 3.0
1086
* and later, a message length word (equal to len+4 because it counts
1087
* itself too) is inserted by this routine.
1089
* All normal messages are suppressed while old-style COPY OUT is in
1090
* progress. (In practice only a few notice messages might get emitted
1091
* then; dropping them is annoying, but at least they will still appear
1092
* in the postmaster log.)
1094
* We also suppress messages generated while pqcomm.c is busy. This
1095
* avoids any possibility of messages being inserted within other
1096
* messages. The only known trouble case arises if SIGQUIT occurs
1097
* during a pqcomm.c routine --- quickdie() will try to send a warning
1098
* message, and the most reasonable approach seems to be to drop it.
1100
* returns 0 if OK, EOF if trouble
1101
* --------------------------------
1104
pq_putmessage(char msgtype, const char *s, size_t len)
1106
if (DoingCopyOut || PqCommBusy)
1110
if (internal_putbytes(&msgtype, 1))
1112
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
1116
n32 = htonl((uint32) (len + 4));
1117
if (internal_putbytes((char *) &n32, 4))
1120
if (internal_putbytes(s, len))
1130
/* --------------------------------
1131
* pq_startcopyout - inform libpq that an old-style COPY OUT transfer
1133
* --------------------------------
1136
pq_startcopyout(void)
1138
DoingCopyOut = true;
1141
/* --------------------------------
1142
* pq_endcopyout - end an old-style COPY OUT transfer
1144
* If errorAbort is indicated, we are aborting a COPY OUT due to an error,
1145
* and must send a terminator line. Since a partial data line might have
1146
* been emitted, send a couple of newlines first (the first one could
1147
* get absorbed by a backslash...) Note that old-style COPY OUT does
1148
* not allow binary transfers, so a textual terminator is always correct.
1149
* --------------------------------
1152
pq_endcopyout(bool errorAbort)
1157
pq_putbytes("\n\n\\.\n", 5);
1158
/* in non-error case, copy.c will have emitted the terminator line */
1159
DoingCopyOut = false;