PostgreSQL Source Code git master
Loading...
Searching...
No Matches
fe-misc.c File Reference
#include "postgres_fe.h"
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/select.h>
#include <poll.h>
#include "libpq-fe.h"
#include "libpq-int.h"
#include "mb/pg_wchar.h"
#include "pg_config_paths.h"
#include "port/pg_bswap.h"
Include dependency graph for fe-misc.c:

Go to the source code of this file.

Functions

static int pqPutMsgBytes (const void *buf, size_t len, PGconn *conn)
 
static int pqSendSome (PGconn *conn, int len)
 
static int pqSocketCheck (PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
 
int PQlibVersion (void)
 
int pqGetc (char *result, PGconn *conn)
 
int pqPutc (char c, PGconn *conn)
 
static int pqGets_internal (PQExpBuffer buf, PGconn *conn, bool resetbuffer)
 
int pqGets (PQExpBuffer buf, PGconn *conn)
 
int pqGets_append (PQExpBuffer buf, PGconn *conn)
 
int pqPuts (const char *s, PGconn *conn)
 
int pqGetnchar (void *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const void *s, size_t len, PGconn *conn)
 
int pqGetInt (int *result, size_t bytes, PGconn *conn)
 
int pqPutInt (int value, size_t bytes, PGconn *conn)
 
int pqCheckOutBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqCheckInBufferSpace (size_t bytes_needed, PGconn *conn)
 
void pqParseDone (PGconn *conn, int newInStart)
 
int pqPutMsgStart (char msg_type, PGconn *conn)
 
int pqPutMsgEnd (PGconn *conn)
 
int pqReadData (PGconn *conn)
 
int pqFlush (PGconn *conn)
 
int pqWait (int forRead, int forWrite, PGconn *conn)
 
int pqWaitTimed (int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
 
int pqReadReady (PGconn *conn)
 
int pqWriteReady (PGconn *conn)
 
int PQsocketPoll (int sock, int forRead, int forWrite, pg_usec_time_t end_time)
 
pg_usec_time_t PQgetCurrentTimeUSec (void)
 
int PQmblen (const char *s, int encoding)
 
int PQmblenBounded (const char *s, int encoding)
 
int PQdsplen (const char *s, int encoding)
 
int PQenv2encoding (void)
 
void libpq_append_error (PQExpBuffer errorMessage, const char *fmt,...)
 
void libpq_append_conn_error (PGconn *conn, const char *fmt,...)
 
void libpq_append_grease_info (PGconn *conn)
 

Function Documentation

◆ libpq_append_conn_error()

void libpq_append_conn_error ( PGconn conn,
const char fmt,
  ... 
)

Definition at line 1404 of file fe-misc.c.

1405{
1406 int save_errno = errno;
1407 bool done;
1408 va_list args;
1409
1410 Assert(fmt[strlen(fmt) - 1] != '\n');
1411
1413 return; /* already failed */
1414
1415 /* Loop in case we have to retry after enlarging the buffer. */
1416 do
1417 {
1418 errno = save_errno;
1419 va_start(args, fmt);
1421 va_end(args);
1422 } while (!done);
1423
1425}
#define Assert(condition)
Definition c.h:906
#define libpq_gettext(x)
Definition oauth-utils.h:86
bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
#define PQExpBufferBroken(str)
Definition pqexpbuffer.h:59
static int fb(int x)
PGconn * conn
Definition streamutil.c:52
PQExpBufferData errorMessage
Definition libpq-int.h:683

References appendPQExpBufferChar(), appendPQExpBufferVA(), Assert, conn, pg_conn::errorMessage, fb(), libpq_gettext, and PQExpBufferBroken.

Referenced by libpq_append_grease_info(), pqReadData(), pqSocketCheck(), and pqWaitTimed().

◆ libpq_append_error()

void libpq_append_error ( PQExpBuffer  errorMessage,
const char fmt,
  ... 
)

Definition at line 1375 of file fe-misc.c.

1376{
1377 int save_errno = errno;
1378 bool done;
1379 va_list args;
1380
1381 Assert(fmt[strlen(fmt) - 1] != '\n');
1382
1383 if (PQExpBufferBroken(errorMessage))
1384 return; /* already failed */
1385
1386 /* Loop in case we have to retry after enlarging the buffer. */
1387 do
1388 {
1389 errno = save_errno;
1390 va_start(args, fmt);
1391 done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
1392 va_end(args);
1393 } while (!done);
1394
1395 appendPQExpBufferChar(errorMessage, '\n');
1396}

References appendPQExpBufferChar(), appendPQExpBufferVA(), Assert, fb(), libpq_gettext, and PQExpBufferBroken.

Referenced by conninfo_add_defaults(), conninfo_array_parse(), conninfo_init(), conninfo_parse(), conninfo_storeval(), conninfo_uri_decode(), conninfo_uri_parse_options(), conninfo_uri_parse_params(), parseServiceFile(), parseServiceInfo(), pg_fe_getusername(), and read_attr_value().

◆ libpq_append_grease_info()

void libpq_append_grease_info ( PGconn conn)

Definition at line 1432 of file fe-misc.c.

1433{
1434 /* translator: %s is a URL */
1436 "\tThis indicates a bug in either the server being contacted\n"
1437 "\tor a proxy handling the connection. Please consider\n"
1438 "\treporting this to the maintainers of that software.\n"
1439 "\tFor more information, including instructions on how to\n"
1440 "\twork around this issue for now, visit\n"
1441 "\t\t%s",
1442 "https://www.postgresql.org/docs/devel/libpq-connect.html#LIBPQ-CONNECT-MAX-PROTOCOL-VERSION");
1443}
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition fe-misc.c:1404

References conn, and libpq_append_conn_error().

Referenced by PQconnectPoll(), and pqGetNegotiateProtocolVersion3().

◆ pqCheckInBufferSpace()

int pqCheckInBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

Definition at line 351 of file fe-misc.c.

352{
353 int newsize = conn->inBufSize;
354 char *newbuf;
355
356 /* Quick exit if we have enough space */
357 if (bytes_needed <= (size_t) newsize)
358 return 0;
359
360 /*
361 * Before concluding that we need to enlarge the buffer, left-justify
362 * whatever is in it and recheck. The caller's value of bytes_needed
363 * includes any data to the left of inStart, but we can delete that in
364 * preference to enlarging the buffer. It's slightly ugly to have this
365 * function do this, but it's better than making callers worry about it.
366 */
368
369 if (conn->inStart < conn->inEnd)
370 {
371 if (conn->inStart > 0)
372 {
374 conn->inEnd - conn->inStart);
375 conn->inEnd -= conn->inStart;
377 conn->inStart = 0;
378 }
379 }
380 else
381 {
382 /* buffer is logically empty, reset it */
383 conn->inStart = conn->inCursor = conn->inEnd = 0;
384 }
385
386 /* Recheck whether we have enough space */
387 if (bytes_needed <= (size_t) newsize)
388 return 0;
389
390 /*
391 * If we need to enlarge the buffer, we first try to double it in size; if
392 * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
393 * the malloc pool by repeated small enlargements.
394 *
395 * Note: tests for newsize > 0 are to catch integer overflow.
396 */
397 do
398 {
399 newsize *= 2;
400 } while (newsize > 0 && bytes_needed > (size_t) newsize);
401
402 if (newsize > 0 && bytes_needed <= (size_t) newsize)
403 {
405 if (newbuf)
406 {
407 /* realloc succeeded */
410 return 0;
411 }
412 }
413
415 do
416 {
417 newsize += 8192;
418 } while (newsize > 0 && bytes_needed > (size_t) newsize);
419
420 if (newsize > 0 && bytes_needed <= (size_t) newsize)
421 {
423 if (newbuf)
424 {
425 /* realloc succeeded */
428 return 0;
429 }
430 }
431
432 /* realloc failed. Probably out of memory */
434 "cannot allocate memory for input buffer\n");
435 return EOF;
436}
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
#define realloc(a, b)
char * inBuffer
Definition libpq-int.h:576
int inCursor
Definition libpq-int.h:579
int inEnd
Definition libpq-int.h:580
int inBufSize
Definition libpq-int.h:577
int inStart
Definition libpq-int.h:578

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, fb(), pg_conn::inBuffer, pg_conn::inBufSize, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, and realloc.

Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), pqParseInput3(), and pqReadData().

◆ pqCheckOutBufferSpace()

int pqCheckOutBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

Definition at line 287 of file fe-misc.c.

288{
289 int newsize = conn->outBufSize;
290 char *newbuf;
291
292 /* Quick exit if we have enough space */
293 if (bytes_needed <= (size_t) newsize)
294 return 0;
295
296 /*
297 * If we need to enlarge the buffer, we first try to double it in size; if
298 * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
299 * the malloc pool by repeated small enlargements.
300 *
301 * Note: tests for newsize > 0 are to catch integer overflow.
302 */
303 do
304 {
305 newsize *= 2;
306 } while (newsize > 0 && bytes_needed > (size_t) newsize);
307
308 if (newsize > 0 && bytes_needed <= (size_t) newsize)
309 {
311 if (newbuf)
312 {
313 /* realloc succeeded */
316 return 0;
317 }
318 }
319
321 do
322 {
323 newsize += 8192;
324 } while (newsize > 0 && bytes_needed > (size_t) newsize);
325
326 if (newsize > 0 && bytes_needed <= (size_t) newsize)
327 {
329 if (newbuf)
330 {
331 /* realloc succeeded */
334 return 0;
335 }
336 }
337
338 /* realloc failed. Probably out of memory */
340 "cannot allocate memory for output buffer\n");
341 return EOF;
342}
int outBufSize
Definition libpq-int.h:584
char * outBuffer
Definition libpq-int.h:583

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, fb(), pg_conn::outBuffer, pg_conn::outBufSize, and realloc.

Referenced by PQputCopyData(), pqPutMsgBytes(), and pqPutMsgStart().

◆ PQdsplen()

int PQdsplen ( const char s,
int  encoding 
)

Definition at line 1276 of file fe-misc.c.

1277{
1278 return pg_encoding_dsplen(encoding, s);
1279}
static char * encoding
Definition initdb.c:139
int pg_encoding_dsplen(int encoding, const char *mbstr)
Definition wchar.c:2198

References encoding, and pg_encoding_dsplen().

Referenced by get_prompt(), pg_wcsformat(), pg_wcssize(), pg_wcswidth(), and strlen_max_width().

◆ PQenv2encoding()

int PQenv2encoding ( void  )

Definition at line 1285 of file fe-misc.c.

1286{
1287 char *str;
1288 int encoding = PG_SQL_ASCII;
1289
1290 str = getenv("PGCLIENTENCODING");
1291 if (str && *str != '\0')
1292 {
1294 if (encoding < 0)
1296 }
1297 return encoding;
1298}
const char * str
@ PG_SQL_ASCII
Definition pg_wchar.h:226
#define pg_char_to_encoding
Definition pg_wchar.h:629

References encoding, fb(), pg_char_to_encoding, PG_SQL_ASCII, and str.

Referenced by main().

◆ pqFlush()

int pqFlush ( PGconn conn)

◆ pqGetc()

int pqGetc ( char result,
PGconn conn 
)

Definition at line 77 of file fe-misc.c.

78{
79 if (conn->inCursor >= conn->inEnd)
80 return EOF;
81
82 *result = conn->inBuffer[conn->inCursor++];
83
84 return 0;
85}

References conn, fb(), pg_conn::inBuffer, pg_conn::inCursor, and pg_conn::inEnd.

Referenced by getCopyDataMessage(), getCopyStart(), getReadyForQuery(), PQconnectPoll(), pqFunctionCall3(), pqGetErrorNotice3(), and pqParseInput3().

◆ PQgetCurrentTimeUSec()

pg_usec_time_t PQgetCurrentTimeUSec ( void  )

Definition at line 1235 of file fe-misc.c.

1236{
1237 struct timeval tval;
1238
1240 return (pg_usec_time_t) tval.tv_sec * 1000000 + tval.tv_usec;
1241}
int64_t pg_usec_time_t
Definition libpq-fe.h:238
int gettimeofday(struct timeval *tp, void *tzp)

References fb(), and gettimeofday().

Referenced by pqConnectDBComplete(), PQsocketPoll(), and wait_until_connected().

◆ pqGetInt()

int pqGetInt ( int result,
size_t  bytes,
PGconn conn 
)

Definition at line 216 of file fe-misc.c.

217{
218 uint16 tmp2;
219 uint32 tmp4;
220
221 switch (bytes)
222 {
223 case 2:
224 if (conn->inCursor + 2 > conn->inEnd)
225 return EOF;
227 conn->inCursor += 2;
228 *result = (int) pg_ntoh16(tmp2);
229 break;
230 case 4:
231 if (conn->inCursor + 4 > conn->inEnd)
232 return EOF;
234 conn->inCursor += 4;
235 *result = (int) pg_ntoh32(tmp4);
236 break;
237 default:
239 "integer of size %zu not supported by pqGetInt",
240 bytes);
241 return EOF;
242 }
243
244 return 0;
245}
uint16_t uint16
Definition c.h:578
uint32_t uint32
Definition c.h:579
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition fe-exec.c:944
#define pg_ntoh32(x)
Definition pg_bswap.h:125
#define pg_ntoh16(x)
Definition pg_bswap.h:124
PGNoticeHooks noticeHooks
Definition libpq-int.h:454

References conn, fb(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::noticeHooks, pg_ntoh16, pg_ntoh32, and pqInternalNotice().

Referenced by getAnotherTuple(), getBackendKeyData(), getCopyDataMessage(), getCopyStart(), getNotify(), getParamDescriptions(), getRowDescriptions(), PQconnectPoll(), pqFunctionCall3(), pqGetNegotiateProtocolVersion3(), and pqParseInput3().

◆ pqGetnchar()

int pqGetnchar ( void s,
size_t  len,
PGconn conn 
)

Definition at line 165 of file fe-misc.c.

166{
167 if (len > (size_t) (conn->inEnd - conn->inCursor))
168 return EOF;
169
171 /* no terminating null */
172
173 conn->inCursor += len;
174
175 return 0;
176}
const void size_t len

References conn, fb(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, and len.

Referenced by getBackendKeyData(), pg_password_sendauth(), pg_SASL_continue(), and pqFunctionCall3().

◆ pqGets()

int pqGets ( PQExpBuffer  buf,
PGconn conn 
)

Definition at line 136 of file fe-misc.c.

137{
138 return pqGets_internal(buf, conn, true);
139}
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition fe-misc.c:109
static char buf[DEFAULT_XLOG_SEG_SIZE]

References buf, conn, and pqGets_internal().

Referenced by getNotify(), getParameterStatus(), getRowDescriptions(), pg_SASL_init(), pqGetErrorNotice3(), pqGetNegotiateProtocolVersion3(), and pqParseInput3().

◆ pqGets_append()

int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

Definition at line 142 of file fe-misc.c.

143{
144 return pqGets_internal(buf, conn, false);
145}

References buf, conn, and pqGets_internal().

Referenced by PQconnectPoll().

◆ pqGets_internal()

static int pqGets_internal ( PQExpBuffer  buf,
PGconn conn,
bool  resetbuffer 
)
static

Definition at line 109 of file fe-misc.c.

110{
111 /* Copy conn data to locals for faster search loop */
112 char *inBuffer = conn->inBuffer;
113 int inCursor = conn->inCursor;
114 int inEnd = conn->inEnd;
115 int slen;
116
117 while (inCursor < inEnd && inBuffer[inCursor])
118 inCursor++;
119
120 if (inCursor >= inEnd)
121 return EOF;
122
123 slen = inCursor - conn->inCursor;
124
125 if (resetbuffer)
127
129
130 conn->inCursor = ++inCursor;
131
132 return 0;
133}
void resetPQExpBuffer(PQExpBuffer str)
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)

References appendBinaryPQExpBuffer(), buf, conn, fb(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, and resetPQExpBuffer().

Referenced by pqGets(), and pqGets_append().

◆ PQlibVersion()

int PQlibVersion ( void  )

Definition at line 63 of file fe-misc.c.

64{
65 return PG_VERSION_NUM;
66}

References fb().

◆ PQmblen()

int PQmblen ( const char s,
int  encoding 
)

Definition at line 1255 of file fe-misc.c.

1256{
1257 return pg_encoding_mblen(encoding, s);
1258}
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition wchar.c:2157

References encoding, and pg_encoding_mblen().

Referenced by appendStringLiteral(), get_prompt(), pg_wcsformat(), pg_wcssize(), pg_wcswidth(), psqlscan_prepare_buffer(), and strlen_max_width().

◆ PQmblenBounded()

◆ pqParseDone()

void pqParseDone ( PGconn conn,
int  newInStart 
)

Definition at line 443 of file fe-misc.c.

444{
445 /* trace server-to-client message */
446 if (conn->Pfdebug)
448
449 /* Mark message as done */
451}
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition fe-trace.c:624

References conn, fb(), pg_conn::inBuffer, pg_conn::inStart, pg_conn::Pfdebug, and pqTraceOutputMessage().

Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), pqGetCopyData3(), and pqParseInput3().

◆ pqPutc()

int pqPutc ( char  c,
PGconn conn 
)

Definition at line 92 of file fe-misc.c.

93{
94 if (pqPutMsgBytes(&c, 1, conn))
95 return EOF;
96
97 return 0;
98}
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition fe-misc.c:509
char * c

References conn, fb(), and pqPutMsgBytes().

Referenced by PQsendQueryGuts(), and PQsendTypedCommand().

◆ pqPutInt()

int pqPutInt ( int  value,
size_t  bytes,
PGconn conn 
)

Definition at line 253 of file fe-misc.c.

254{
255 uint16 tmp2;
256 uint32 tmp4;
257
258 switch (bytes)
259 {
260 case 2:
262 if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
263 return EOF;
264 break;
265 case 4:
267 if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
268 return EOF;
269 break;
270 default:
272 "integer of size %zu not supported by pqPutInt",
273 bytes);
274 return EOF;
275 }
276
277 return 0;
278}
static struct @174 value
#define pg_hton32(x)
Definition pg_bswap.h:121
#define pg_hton16(x)
Definition pg_bswap.h:120

References conn, fb(), pg_conn::noticeHooks, pg_hton16, pg_hton32, pqInternalNotice(), pqPutMsgBytes(), and value.

Referenced by pg_SASL_init(), pqFunctionCall3(), PQsendPrepare(), and PQsendQueryGuts().

◆ pqPutMsgBytes()

static int pqPutMsgBytes ( const void buf,
size_t  len,
PGconn conn 
)
static

Definition at line 509 of file fe-misc.c.

510{
511 /* make sure there is room for it */
513 return EOF;
514 /* okay, save the data */
516 conn->outMsgEnd += len;
517 /* no Pfdebug call here, caller should do it */
518 return 0;
519}
int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
Definition fe-misc.c:287
int outMsgEnd
Definition libpq-int.h:590

References buf, conn, fb(), len, pg_conn::outBuffer, pg_conn::outMsgEnd, and pqCheckOutBufferSpace().

Referenced by pqPutc(), pqPutInt(), pqPutnchar(), and pqPuts().

◆ pqPutMsgEnd()

int pqPutMsgEnd ( PGconn conn)

Definition at line 532 of file fe-misc.c.

533{
534 /* Fill in length word if needed */
535 if (conn->outMsgStart >= 0)
536 {
538
541 }
542
543 /* trace client-to-server message */
544 if (conn->Pfdebug)
545 {
548 else
551 }
552
553 /* Make message eligible to send */
555
556 /* If appropriate, try to push out some data */
557 if (conn->outCount >= 8192)
558 {
559 int toSend = conn->outCount;
560
561 /*
562 * On Unix-pipe connections, it seems profitable to prefer sending
563 * pipe-buffer-sized packets not randomly-sized ones, so retain the
564 * last partial-8K chunk in our buffer for now. On TCP connections,
565 * the advantage of that is far less clear. Moreover, it flat out
566 * isn't safe when using SSL or GSSAPI, because those code paths have
567 * API stipulations that if they fail to send all the data that was
568 * offered in the previous write attempt, we mustn't offer less data
569 * in this write attempt. The previous write attempt might've been
570 * pqFlush attempting to send everything in the buffer, so we mustn't
571 * offer less now. (Presently, we won't try to use SSL or GSSAPI on
572 * Unix connections, so those checks are just Asserts. They'll have
573 * to become part of the regular if-test if we ever change that.)
574 */
575 if (conn->raddr.addr.ss_family == AF_UNIX)
576 {
577#ifdef USE_SSL
579#endif
580#ifdef ENABLE_GSS
581 Assert(!conn->gssenc);
582#endif
583 toSend -= toSend % 8192;
584 }
585
586 if (pqSendSome(conn, toSend) < 0)
587 return EOF;
588 /* in nonblock mode, don't complain if unable to send it all */
589 }
590
591 return 0;
592}
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition fe-trace.c:841
struct sockaddr_storage addr
Definition pqcomm.h:32
int outMsgStart
Definition libpq-int.h:588
SockAddr raddr
Definition libpq-int.h:502
bool ssl_in_use
Definition libpq-int.h:620

References SockAddr::addr, Assert, conn, fb(), pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, pg_conn::Pfdebug, pg_hton32, pqSendSome(), pqTraceOutputMessage(), pqTraceOutputNoTypeByteMessage(), pg_conn::raddr, and pg_conn::ssl_in_use.

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendCancelRequest(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutMsgStart()

int pqPutMsgStart ( char  msg_type,
PGconn conn 
)

Definition at line 473 of file fe-misc.c.

474{
475 int lenPos;
476 int endPos;
477
478 /* allow room for message type byte */
479 if (msg_type)
480 endPos = conn->outCount + 1;
481 else
483
484 /* do we want a length word? */
485 lenPos = endPos;
486 /* allow room for message length */
487 endPos += 4;
488
489 /* make sure there is room for message header */
491 return EOF;
492 /* okay, save the message type byte if any */
493 if (msg_type)
495 /* set up the message pointers */
498 /* length word, if needed, will be filled in by pqPutMsgEnd */
499
500 return 0;
501}

References conn, fb(), pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, and pqCheckOutBufferSpace().

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendCancelRequest(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutnchar()

int pqPutnchar ( const void s,
size_t  len,
PGconn conn 
)

Definition at line 202 of file fe-misc.c.

203{
204 if (pqPutMsgBytes(s, len, conn))
205 return EOF;
206
207 return 0;
208}

References conn, fb(), len, and pqPutMsgBytes().

Referenced by pg_SASL_init(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQsendCancelRequest(), and PQsendQueryGuts().

◆ pqPuts()

int pqPuts ( const char s,
PGconn conn 
)

Definition at line 152 of file fe-misc.c.

153{
154 if (pqPutMsgBytes(s, strlen(s) + 1, conn))
155 return EOF;
156
157 return 0;
158}

References conn, fb(), and pqPutMsgBytes().

Referenced by pg_SASL_init(), PQputCopyEnd(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), and PQsendTypedCommand().

◆ pqReadData()

int pqReadData ( PGconn conn)

Definition at line 606 of file fe-misc.c.

607{
608 int someread = 0;
609 int nread;
610
611 if (conn->sock == PGINVALID_SOCKET)
612 {
613 libpq_append_conn_error(conn, "connection not open");
614 return -1;
615 }
616
617 /* Left-justify any data in the buffer to make room */
618 if (conn->inStart < conn->inEnd)
619 {
620 if (conn->inStart > 0)
621 {
623 conn->inEnd - conn->inStart);
624 conn->inEnd -= conn->inStart;
626 conn->inStart = 0;
627 }
628 }
629 else
630 {
631 /* buffer is logically empty, reset it */
632 conn->inStart = conn->inCursor = conn->inEnd = 0;
633 }
634
635 /*
636 * If the buffer is fairly full, enlarge it. We need to be able to enlarge
637 * the buffer in case a single message exceeds the initial buffer size. We
638 * enlarge before filling the buffer entirely so as to avoid asking the
639 * kernel for a partial packet. The magic constant here should be large
640 * enough for a TCP packet or Unix pipe bufferload. 8K is the usual pipe
641 * buffer size, so...
642 */
643 if (conn->inBufSize - conn->inEnd < 8192)
644 {
645 if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
646 {
647 /*
648 * We don't insist that the enlarge worked, but we need some room
649 */
650 if (conn->inBufSize - conn->inEnd < 100)
651 return -1; /* errorMessage already set */
652 }
653 }
654
655 /* OK, try to read some data */
656retry3:
659 if (nread < 0)
660 {
661 switch (SOCK_ERRNO)
662 {
663 case EINTR:
664 goto retry3;
665
666 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
667#ifdef EAGAIN
668 case EAGAIN:
669 return someread;
670#endif
671#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
672 case EWOULDBLOCK:
673 return someread;
674#endif
675
676 /* We might get ECONNRESET etc here if connection failed */
678 goto definitelyFailed;
679
680 default:
681 /* pqsecure_read set the error message for us */
682 return -1;
683 }
684 }
685 if (nread > 0)
686 {
687 conn->inEnd += nread;
688
689 /*
690 * Hack to deal with the fact that some kernels will only give us back
691 * 1 packet per recv() call, even if we asked for more and there is
692 * more available. If it looks like we are reading a long message,
693 * loop back to recv() again immediately, until we run out of data or
694 * buffer space. Without this, the block-and-restart behavior of
695 * libpq's higher levels leads to O(N^2) performance on long messages.
696 *
697 * Since we left-justified the data above, conn->inEnd gives the
698 * amount of data already read in the current message. We consider
699 * the message "long" once we have acquired 32k ...
700 */
701 if (conn->inEnd > 32768 &&
702 (conn->inBufSize - conn->inEnd) >= 8192)
703 {
704 someread = 1;
705 goto retry3;
706 }
707 return 1;
708 }
709
710 if (someread)
711 return 1; /* got a zero read after successful tries */
712
713 /*
714 * A return value of 0 could mean just that no data is now available, or
715 * it could mean EOF --- that is, the server has closed the connection.
716 * Since we have the socket in nonblock mode, the only way to tell the
717 * difference is to see if select() is saying that the file is ready.
718 * Grumble. Fortunately, we don't expect this path to be taken much,
719 * since in normal practice we should not be trying to read data unless
720 * the file selected for reading already.
721 *
722 * In SSL mode it's even worse: SSL_read() could say WANT_READ and then
723 * data could arrive before we make the pqReadReady() test, but the second
724 * SSL_read() could still say WANT_READ because the data received was not
725 * a complete SSL record. So we must play dumb and assume there is more
726 * data, relying on the SSL layer to detect true EOF.
727 */
728
729#ifdef USE_SSL
730 if (conn->ssl_in_use)
731 return 0;
732#endif
733
734 switch (pqReadReady(conn))
735 {
736 case 0:
737 /* definitely no data available */
738 return 0;
739 case 1:
740 /* ready for read */
741 break;
742 default:
743 /* we override pqReadReady's message with something more useful */
744 goto definitelyEOF;
745 }
746
747 /*
748 * Still not sure that it's EOF, because some data could have just
749 * arrived.
750 */
751retry4:
754 if (nread < 0)
755 {
756 switch (SOCK_ERRNO)
757 {
758 case EINTR:
759 goto retry4;
760
761 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
762#ifdef EAGAIN
763 case EAGAIN:
764 return 0;
765#endif
766#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
767 case EWOULDBLOCK:
768 return 0;
769#endif
770
771 /* We might get ECONNRESET etc here if connection failed */
773 goto definitelyFailed;
774
775 default:
776 /* pqsecure_read set the error message for us */
777 return -1;
778 }
779 }
780 if (nread > 0)
781 {
782 conn->inEnd += nread;
783 return 1;
784 }
785
786 /*
787 * OK, we are getting a zero read even though select() says ready. This
788 * means the connection has been closed. Cope.
789 */
791 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
792 "\tThis probably means the server terminated abnormally\n"
793 "\tbefore or while processing the request.");
794
795 /* Come here if lower-level code already set a suitable errorMessage */
797 /* Do *not* drop any already-read data; caller still wants it */
798 pqDropConnection(conn, false);
799 conn->status = CONNECTION_BAD; /* No more connection to backend */
800 return -1;
801}
void pqDropConnection(PGconn *conn, bool flushInput)
Definition fe-connect.c:533
int pqReadReady(PGconn *conn)
Definition fe-misc.c:1058
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition fe-misc.c:351
ssize_t pqsecure_read(PGconn *conn, void *ptr, size_t len)
Definition fe-secure.c:167
@ CONNECTION_BAD
Definition libpq-fe.h:85
#define SOCK_ERRNO
#define ALL_CONNECTION_FAILURE_ERRNOS
Definition port.h:122
#define PGINVALID_SOCKET
Definition port.h:31
pgsocket sock
Definition libpq-int.h:499
ConnStatusType status
Definition libpq-int.h:462
#define EINTR
Definition win32_port.h:361
#define EWOULDBLOCK
Definition win32_port.h:367
#define EAGAIN
Definition win32_port.h:359

References ALL_CONNECTION_FAILURE_ERRNOS, conn, CONNECTION_BAD, EAGAIN, EINTR, EWOULDBLOCK, fb(), pg_conn::inBuffer, pg_conn::inBufSize, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), PGINVALID_SOCKET, pqCheckInBufferSpace(), pqDropConnection(), pqReadReady(), pqsecure_read(), pg_conn::sock, SOCK_ERRNO, pg_conn::ssl_in_use, and pg_conn::status.

Referenced by PQcancelPoll(), PQconnectPoll(), PQconsumeInput(), pqFunctionCall3(), pqGetCopyData3(), pqGetline3(), PQgetResult(), and pqSendSome().

◆ pqReadReady()

int pqReadReady ( PGconn conn)

Definition at line 1058 of file fe-misc.c.

1059{
1060 return pqSocketCheck(conn, 1, 0, 0);
1061}
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
Definition fe-misc.c:1083

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqSendSome()

static int pqSendSome ( PGconn conn,
int  len 
)
static

Definition at line 825 of file fe-misc.c.

826{
827 char *ptr = conn->outBuffer;
828 int remaining = conn->outCount;
829 int result = 0;
830
831 /*
832 * If we already had a write failure, we will never again try to send data
833 * on that connection. Even if the kernel would let us, we've probably
834 * lost message boundary sync with the server. conn->write_failed
835 * therefore persists until the connection is reset, and we just discard
836 * all data presented to be written. However, as long as we still have a
837 * valid socket, we should continue to absorb data from the backend, so
838 * that we can collect any final error messages.
839 */
840 if (conn->write_failed)
841 {
842 /* conn->write_err_msg should be set up already */
843 conn->outCount = 0;
844 /* Absorb input data if any, and detect socket closure */
845 if (conn->sock != PGINVALID_SOCKET)
846 {
847 if (pqReadData(conn) < 0)
848 return -1;
849 }
850 return 0;
851 }
852
853 if (conn->sock == PGINVALID_SOCKET)
854 {
855 conn->write_failed = true;
856 /* Store error message in conn->write_err_msg, if possible */
857 /* (strdup failure is OK, we'll cope later) */
858 conn->write_err_msg = strdup(libpq_gettext("connection not open\n"));
859 /* Discard queued data; no chance it'll ever be sent */
860 conn->outCount = 0;
861 return 0;
862 }
863
864 /* while there's still data to send */
865 while (len > 0)
866 {
867 int sent;
868
869#ifndef WIN32
870 sent = pqsecure_write(conn, ptr, len);
871#else
872
873 /*
874 * Windows can fail on large sends, per KB article Q201213. The
875 * failure-point appears to be different in different versions of
876 * Windows, but 64k should always be safe.
877 */
878 sent = pqsecure_write(conn, ptr, Min(len, 65536));
879#endif
880
881 if (sent < 0)
882 {
883 /* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble */
884 switch (SOCK_ERRNO)
885 {
886#ifdef EAGAIN
887 case EAGAIN:
888 break;
889#endif
890#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
891 case EWOULDBLOCK:
892 break;
893#endif
894 case EINTR:
895 continue;
896
897 default:
898 /* Discard queued data; no chance it'll ever be sent */
899 conn->outCount = 0;
900
901 /* Absorb input data if any, and detect socket closure */
902 if (conn->sock != PGINVALID_SOCKET)
903 {
904 if (pqReadData(conn) < 0)
905 return -1;
906 }
907
908 /*
909 * Lower-level code should already have filled
910 * conn->write_err_msg (and set conn->write_failed) or
911 * conn->errorMessage. In the former case, we pretend
912 * there's no problem; the write_failed condition will be
913 * dealt with later. Otherwise, report the error now.
914 */
915 if (conn->write_failed)
916 return 0;
917 else
918 return -1;
919 }
920 }
921 else
922 {
923 ptr += sent;
924 len -= sent;
925 remaining -= sent;
926 }
927
928 if (len > 0)
929 {
930 /*
931 * We didn't send it all, wait till we can send more.
932 *
933 * There are scenarios in which we can't send data because the
934 * communications channel is full, but we cannot expect the server
935 * to clear the channel eventually because it's blocked trying to
936 * send data to us. (This can happen when we are sending a large
937 * amount of COPY data, and the server has generated lots of
938 * NOTICE responses.) To avoid a deadlock situation, we must be
939 * prepared to accept and buffer incoming data before we try
940 * again. Furthermore, it is possible that such incoming data
941 * might not arrive until after we've gone to sleep. Therefore,
942 * we wait for either read ready or write ready.
943 *
944 * In non-blocking mode, we don't wait here directly, but return 1
945 * to indicate that data is still pending. The caller should wait
946 * for both read and write ready conditions, and call
947 * PQconsumeInput() on read ready, but just in case it doesn't, we
948 * call pqReadData() ourselves before returning. That's not
949 * enough if the data has not arrived yet, but it's the best we
950 * can do, and works pretty well in practice. (The documentation
951 * used to say that you only need to wait for write-ready, so
952 * there are still plenty of applications like that out there.)
953 *
954 * Note that errors here don't result in write_failed becoming
955 * set.
956 */
957 if (pqReadData(conn) < 0)
958 {
959 result = -1; /* error message already set up */
960 break;
961 }
962
964 {
965 result = 1;
966 break;
967 }
968
969 if (pqWait(true, true, conn))
970 {
971 result = -1;
972 break;
973 }
974 }
975 }
976
977 /* shift the remaining contents of the buffer */
978 if (remaining > 0)
981
982 return result;
983}
#define Min(x, y)
Definition c.h:1040
int pqReadData(PGconn *conn)
Definition fe-misc.c:606
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition fe-misc.c:1019
ssize_t pqsecure_write(PGconn *conn, const void *ptr, size_t len)
Definition fe-secure.c:267
int remaining
Definition informix.c:692
#define pqIsnonblocking(conn)
Definition libpq-int.h:939
char * write_err_msg
Definition libpq-int.h:513
bool write_failed
Definition libpq-int.h:512

References conn, EAGAIN, EINTR, EWOULDBLOCK, fb(), len, libpq_gettext, Min, pg_conn::outBuffer, pg_conn::outCount, PGINVALID_SOCKET, pqIsnonblocking, pqReadData(), pqsecure_write(), pqWait(), remaining, pg_conn::sock, SOCK_ERRNO, pg_conn::write_err_msg, and pg_conn::write_failed.

Referenced by pqFlush(), and pqPutMsgEnd().

◆ pqSkipnchar()

int pqSkipnchar ( size_t  len,
PGconn conn 
)

Definition at line 187 of file fe-misc.c.

188{
189 if (len > (size_t) (conn->inEnd - conn->inCursor))
190 return EOF;
191
192 conn->inCursor += len;
193
194 return 0;
195}

References conn, fb(), pg_conn::inCursor, pg_conn::inEnd, and len.

Referenced by getAnotherTuple().

◆ pqSocketCheck()

static int pqSocketCheck ( PGconn conn,
int  forRead,
int  forWrite,
pg_usec_time_t  end_time 
)
static

Definition at line 1083 of file fe-misc.c.

1084{
1085 int result;
1086 pgsocket sock;
1087
1088 if (!conn)
1089 return -1;
1090
1092 sock = conn->altsock;
1093 else
1094 {
1095 sock = conn->sock;
1096 if (sock == PGINVALID_SOCKET)
1097 {
1098 libpq_append_conn_error(conn, "invalid socket");
1099 return -1;
1100 }
1101
1102#ifdef USE_SSL
1103 /* Check for SSL library buffering read bytes */
1105 {
1106 /* short-circuit the select */
1107 return 1;
1108 }
1109#endif
1110 }
1111
1112 /* We will retry as long as we get EINTR */
1113 do
1114 result = PQsocketPoll(sock, forRead, forWrite, end_time);
1115 while (result < 0 && SOCK_ERRNO == EINTR);
1116
1117 if (result < 0)
1118 {
1120
1121 libpq_append_conn_error(conn, "%s() failed: %s", "select",
1122 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1123 }
1124
1125 return result;
1126}
int PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time)
Definition fe-misc.c:1141
bool pgtls_read_pending(PGconn *conn)
#define SOCK_STRERROR
Definition libpq-int.h:973
static int64 end_time
Definition pgbench.c:176
#define PG_STRERROR_R_BUFLEN
Definition port.h:278
int pgsocket
Definition port.h:29
pgsocket altsock
Definition libpq-int.h:530

References pg_conn::altsock, conn, EINTR, end_time, fb(), libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, PGINVALID_SOCKET, pgtls_read_pending(), PQsocketPoll(), pg_conn::sock, SOCK_ERRNO, SOCK_STRERROR, and pg_conn::ssl_in_use.

Referenced by pqReadReady(), pqWaitTimed(), and pqWriteReady().

◆ PQsocketPoll()

int PQsocketPoll ( int  sock,
int  forRead,
int  forWrite,
pg_usec_time_t  end_time 
)

Definition at line 1141 of file fe-misc.c.

1142{
1143 /* We use poll(2) if available, otherwise select(2) */
1144#ifdef HAVE_POLL
1145 struct pollfd input_fd;
1146 int timeout_ms;
1147
1148 if (!forRead && !forWrite)
1149 return 0;
1150
1151 input_fd.fd = sock;
1152 input_fd.events = POLLERR;
1153 input_fd.revents = 0;
1154
1155 if (forRead)
1156 input_fd.events |= POLLIN;
1157 if (forWrite)
1158 input_fd.events |= POLLOUT;
1159
1160 /* Compute appropriate timeout interval */
1161 if (end_time == -1)
1162 timeout_ms = -1;
1163 else if (end_time == 0)
1164 timeout_ms = 0;
1165 else
1166 {
1168
1169 if (end_time > now)
1170 timeout_ms = (end_time - now) / 1000;
1171 else
1172 timeout_ms = 0;
1173 }
1174
1175 return poll(&input_fd, 1, timeout_ms);
1176#else /* !HAVE_POLL */
1177
1181 struct timeval timeout;
1182 struct timeval *ptr_timeout;
1183
1184 if (!forRead && !forWrite)
1185 return 0;
1186
1190 if (forRead)
1191 FD_SET(sock, &input_mask);
1192
1193 if (forWrite)
1194 FD_SET(sock, &output_mask);
1195 FD_SET(sock, &except_mask);
1196
1197 /* Compute appropriate timeout interval */
1198 if (end_time == -1)
1199 ptr_timeout = NULL;
1200 else if (end_time == 0)
1201 {
1202 timeout.tv_sec = 0;
1203 timeout.tv_usec = 0;
1205 }
1206 else
1207 {
1209
1210 if (end_time > now)
1211 {
1212 timeout.tv_sec = (end_time - now) / 1000000;
1213 timeout.tv_usec = (end_time - now) % 1000000;
1214 }
1215 else
1216 {
1217 timeout.tv_sec = 0;
1218 timeout.tv_usec = 0;
1219 }
1221 }
1222
1223 return select(sock + 1, &input_mask, &output_mask,
1225#endif /* HAVE_POLL */
1226}
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1609
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition fe-misc.c:1235
#define select(n, r, w, e, timeout)
Definition win32_port.h:500

References end_time, fb(), now(), PQgetCurrentTimeUSec(), and select.

Referenced by pqSocketCheck(), timer_expired(), and wait_until_connected().

◆ pqWait()

int pqWait ( int  forRead,
int  forWrite,
PGconn conn 
)

Definition at line 1019 of file fe-misc.c.

1020{
1021 return pqWaitTimed(forRead, forWrite, conn, -1);
1022}
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
Definition fe-misc.c:1035

References conn, fb(), and pqWaitTimed().

Referenced by pqFunctionCall3(), pqGetCopyData3(), pqGetline3(), PQgetResult(), and pqSendSome().

◆ pqWaitTimed()

int pqWaitTimed ( int  forRead,
int  forWrite,
PGconn conn,
pg_usec_time_t  end_time 
)

Definition at line 1035 of file fe-misc.c.

1036{
1037 int result;
1038
1040
1041 if (result < 0)
1042 return -1; /* errorMessage is already set */
1043
1044 if (result == 0)
1045 {
1046 libpq_append_conn_error(conn, "timeout expired");
1047 return 1;
1048 }
1049
1050 return 0;
1051}

References conn, end_time, fb(), libpq_append_conn_error(), and pqSocketCheck().

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

Definition at line 1068 of file fe-misc.c.

1069{
1070 return pqSocketCheck(conn, 0, 1, 0);
1071}

References conn, and pqSocketCheck().