PostgreSQL Source Code git master
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 (char *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const char *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,...)
 

Function Documentation

◆ libpq_append_conn_error()

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

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

1382{
1383 int save_errno = errno;
1384 bool done;
1385 va_list args;
1386
1387 Assert(fmt[strlen(fmt) - 1] != '\n');
1388
1390 return; /* already failed */
1391
1392 /* Loop in case we have to retry after enlarging the buffer. */
1393 do
1394 {
1395 errno = save_errno;
1396 va_start(args, fmt);
1398 va_end(args);
1399 } while (!done);
1400
1402}
#define Assert(condition)
Definition: c.h:815
#define libpq_gettext(x)
Definition: libpq-int.h:923
static void const char * fmt
va_end(args)
va_start(args, fmt)
bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args)
Definition: pqexpbuffer.c:294
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
PGconn * conn
Definition: streamutil.c:53
PQExpBufferData errorMessage
Definition: libpq-int.h:660

References appendPQExpBufferChar(), appendPQExpBufferVA(), generate_unaccent_rules::args, Assert, conn, pg_conn::errorMessage, fmt, libpq_gettext, PQExpBufferBroken, va_end(), and va_start().

Referenced by build_client_final_message(), build_client_first_message(), check_expected_areq(), connectFailureMessage(), connectNoDelay(), fillPGconn(), handleSyncLoss(), init_allowed_encryption_methods(), initialize_SSL(), lo_create(), lo_export(), lo_import_internal(), lo_initialize(), lo_lseek64(), lo_read(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_write(), open_client_SSL(), openssl_verify_peer_name_matches_certificate_ip(), openssl_verify_peer_name_matches_certificate_name(), pg_fe_sendauth(), pg_GSS_load_servicename(), pg_GSS_read(), pg_GSS_write(), pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pgpassfileWarning(), pgtls_get_peer_certificate_hash(), pgtls_read(), pgtls_write(), pq_verify_peer_name_matches_certificate(), pq_verify_peer_name_matches_certificate_ip(), pq_verify_peer_name_matches_certificate_name(), pqAllocCmdQueueEntry(), PQcancelCreate(), PQcancelPoll(), PQcancelStart(), pqConnectOptions2(), PQconnectPoll(), pqCopyPGconn(), PQencryptPasswordConn(), pqEndcopy3(), PQenterPipelineMode(), PQescapeByteaInternal(), PQescapeInternal(), PQescapeStringInternal(), PQexecStart(), PQexitPipelineMode(), PQfn(), pqFunctionCall3(), PQgetCopyData(), pqGetCopyData3(), pqGetErrorNotice3(), pqGetline3(), pqGetNegotiateProtocolVersion3(), PQgetResult(), pqParseInput3(), pqParseIntParam(), pqPipelineProcessQueue(), pqPipelineSyncInternal(), pqPrepareAsyncResult(), PQputCopyData(), PQputCopyEnd(), pqReadData(), pqSaveWriteError(), pqsecure_open_gss(), pqsecure_raw_read(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendQueryParams(), PQsendQueryPrepared(), PQsendQueryStart(), PQsendTypedCommand(), PQsetdbLogin(), pqSocketCheck(), pqWaitTimed(), read_server_final_message(), read_server_first_message(), scram_exchange(), select_next_encryption_method(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), setTCPUserTimeout(), and store_conn_addrinfo().

◆ libpq_append_error()

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

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

1353{
1354 int save_errno = errno;
1355 bool done;
1356 va_list args;
1357
1358 Assert(fmt[strlen(fmt) - 1] != '\n');
1359
1360 if (PQExpBufferBroken(errorMessage))
1361 return; /* already failed */
1362
1363 /* Loop in case we have to retry after enlarging the buffer. */
1364 do
1365 {
1366 errno = save_errno;
1367 va_start(args, fmt);
1368 done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
1369 va_end(args);
1370 } while (!done);
1371
1372 appendPQExpBufferChar(errorMessage, '\n');
1373}

References appendPQExpBufferChar(), appendPQExpBufferVA(), generate_unaccent_rules::args, Assert, fmt, libpq_gettext, PQExpBufferBroken, va_end(), and va_start().

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().

◆ 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 */
367 bytes_needed -= conn->inStart;
368
369 if (conn->inStart < conn->inEnd)
370 {
371 if (conn->inStart > 0)
372 {
373 memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
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 {
404 newbuf = realloc(conn->inBuffer, newsize);
405 if (newbuf)
406 {
407 /* realloc succeeded */
408 conn->inBuffer = newbuf;
409 conn->inBufSize = newsize;
410 return 0;
411 }
412 }
413
414 newsize = conn->inBufSize;
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 {
422 newbuf = realloc(conn->inBuffer, newsize);
423 if (newbuf)
424 {
425 /* realloc succeeded */
426 conn->inBuffer = newbuf;
427 conn->inBufSize = newsize;
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}
#define realloc(a, b)
Definition: header.h:60
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
char * inBuffer
Definition: libpq-int.h:553
int inCursor
Definition: libpq-int.h:556
int inEnd
Definition: libpq-int.h:557
int inBufSize
Definition: libpq-int.h:554
int inStart
Definition: libpq-int.h:555

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, 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 {
310 newbuf = realloc(conn->outBuffer, newsize);
311 if (newbuf)
312 {
313 /* realloc succeeded */
314 conn->outBuffer = newbuf;
315 conn->outBufSize = newsize;
316 return 0;
317 }
318 }
319
320 newsize = conn->outBufSize;
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 {
328 newbuf = realloc(conn->outBuffer, newsize);
329 if (newbuf)
330 {
331 /* realloc succeeded */
332 conn->outBuffer = newbuf;
333 conn->outBufSize = newsize;
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:561
char * outBuffer
Definition: libpq-int.h:560

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, 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 1253 of file fe-misc.c.

1254{
1255 return pg_encoding_dsplen(encoding, s);
1256}
int32 encoding
Definition: pg_database.h:41
int pg_encoding_dsplen(int encoding, const char *mbstr)
Definition: wchar.c:2137

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 1262 of file fe-misc.c.

1263{
1264 char *str;
1265 int encoding = PG_SQL_ASCII;
1266
1267 str = getenv("PGCLIENTENCODING");
1268 if (str && *str != '\0')
1269 {
1271 if (encoding < 0)
1273 }
1274 return encoding;
1275}
const char * str
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define pg_char_to_encoding
Definition: pg_wchar.h:629

References encoding, pg_char_to_encoding, PG_SQL_ASCII, and str.

Referenced by main().

◆ pqFlush()

int pqFlush ( PGconn conn)

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

969{
970 if (conn->outCount > 0)
971 {
972 if (conn->Pfdebug)
974
975 return pqSendSome(conn, conn->outCount);
976 }
977
978 return 0;
979}
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:799
static void const char fflush(stdout)
FILE * Pfdebug
Definition: libpq-int.h:441
int outCount
Definition: libpq-int.h:562

References conn, fflush(), pg_conn::outCount, pg_conn::Pfdebug, and pqSendSome().

Referenced by pg_SASL_init(), PQconnectPoll(), PQconsumeInput(), pqEndcopy3(), PQexitPipelineMode(), PQflush(), pqFunctionCall3(), PQgetResult(), pqPacketSend(), pqPipelineFlush(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendQueryInternal(), PQsetnonblocking(), and sendTerminateConn().

◆ 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, 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 1209 of file fe-misc.c.

1210{
1211 struct timeval tval;
1212
1213 gettimeofday(&tval, NULL);
1214 return (pg_usec_time_t) tval.tv_sec * 1000000 + tval.tv_usec;
1215}
pg_int64 pg_usec_time_t
Definition: libpq-fe.h:228
int gettimeofday(struct timeval *tp, void *tzp)

References 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;
226 memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
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;
233 memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
234 conn->inCursor += 4;
235 *result = (int) pg_ntoh32(tmp4);
236 break;
237 default:
239 "integer of size %lu not supported by pqGetInt",
240 (unsigned long) bytes);
241 return EOF;
242 }
243
244 return 0;
245}
uint16_t uint16
Definition: c.h:487
uint32_t uint32
Definition: c.h:488
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:938
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
#define pg_ntoh16(x)
Definition: pg_bswap.h:124
PGNoticeHooks noticeHooks
Definition: libpq-int.h:445

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

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

◆ pqGetnchar()

int pqGetnchar ( char *  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
170 memcpy(s, conn->inBuffer + conn->inCursor, len);
171 /* no terminating null */
172
173 conn->inCursor += len;
174
175 return 0;
176}
const void size_t len

References conn, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, and len.

Referenced by 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
Definition: pg_test_fsync.c:72

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
128 appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
129
130 conn->inCursor = ++inCursor;
131
132 return 0;
133}
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
Definition: pqexpbuffer.c:397

References appendBinaryPQExpBuffer(), buf, conn, 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}

◆ PQmblen()

int PQmblen ( const char *  s,
int  encoding 
)

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

1234{
1235 return pg_encoding_mblen(encoding, s);
1236}
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition: wchar.c:2116

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()

int PQmblenBounded ( const char *  s,
int  encoding 
)

◆ 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 */
450 conn->inStart = newInStart;
451}
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:618

References conn, 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, 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:
261 tmp2 = pg_hton16((uint16) value);
262 if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
263 return EOF;
264 break;
265 case 4:
266 tmp4 = pg_hton32((uint32) value);
267 if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
268 return EOF;
269 break;
270 default:
272 "integer of size %lu not supported by pqPutInt",
273 (unsigned long) bytes);
274 return EOF;
275 }
276
277 return 0;
278}
static struct @162 value
#define pg_hton32(x)
Definition: pg_bswap.h:121
#define pg_hton16(x)
Definition: pg_bswap.h:120

References conn, 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 */
515 memcpy(conn->outBuffer + conn->outMsgEnd, buf, len);
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:567

References buf, conn, 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 {
537 uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
538
539 msgLen = pg_hton32(msgLen);
540 memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
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 (conn->outCount >= 8192)
557 {
558 int toSend = conn->outCount - (conn->outCount % 8192);
559
560 if (pqSendSome(conn, toSend) < 0)
561 return EOF;
562 /* in nonblock mode, don't complain if unable to send it all */
563 }
564
565 return 0;
566}
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition: fe-trace.c:835
int outMsgStart
Definition: libpq-int.h:565

References conn, pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, pg_conn::Pfdebug, pg_hton32, pqSendSome(), pqTraceOutputMessage(), and pqTraceOutputNoTypeByteMessage().

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), 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
482 endPos = conn->outCount;
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 */
490 if (pqCheckOutBufferSpace(endPos, conn))
491 return EOF;
492 /* okay, save the message type byte if any */
493 if (msg_type)
494 conn->outBuffer[conn->outCount] = msg_type;
495 /* set up the message pointers */
496 conn->outMsgStart = lenPos;
497 conn->outMsgEnd = endPos;
498 /* length word, if needed, will be filled in by pqPutMsgEnd */
499
500 return 0;
501}

References conn, 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(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutnchar()

int pqPutnchar ( const char *  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, len, and pqPutMsgBytes().

Referenced by pg_SASL_init(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), 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, and pqPutMsgBytes().

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

◆ pqReadData()

int pqReadData ( PGconn conn)

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

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

References ALL_CONNECTION_FAILURE_ERRNOS, conn, CONNECTION_BAD, EAGAIN, EINTR, EWOULDBLOCK, 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 1032 of file fe-misc.c.

1033{
1034 return pqSocketCheck(conn, 1, 0, 0);
1035}
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
Definition: fe-misc.c:1057

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqSendSome()

static int pqSendSome ( PGconn conn,
int  len 
)
static

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

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

References conn, EAGAIN, EINTR, EWOULDBLOCK, 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, 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 1057 of file fe-misc.c.

1058{
1059 int result;
1060 pgsocket sock;
1061
1062 if (!conn)
1063 return -1;
1064
1066 sock = conn->altsock;
1067 else
1068 {
1069 sock = conn->sock;
1070 if (sock == PGINVALID_SOCKET)
1071 {
1072 libpq_append_conn_error(conn, "invalid socket");
1073 return -1;
1074 }
1075
1076#ifdef USE_SSL
1077 /* Check for SSL library buffering read bytes */
1078 if (forRead && conn->ssl_in_use && pgtls_read_pending(conn))
1079 {
1080 /* short-circuit the select */
1081 return 1;
1082 }
1083#endif
1084 }
1085
1086 /* We will retry as long as we get EINTR */
1087 do
1088 result = PQsocketPoll(sock, forRead, forWrite, end_time);
1089 while (result < 0 && SOCK_ERRNO == EINTR);
1090
1091 if (result < 0)
1092 {
1093 char sebuf[PG_STRERROR_R_BUFLEN];
1094
1095 libpq_append_conn_error(conn, "%s() failed: %s", "select",
1096 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1097 }
1098
1099 return result;
1100}
int PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time)
Definition: fe-misc.c:1115
bool pgtls_read_pending(PGconn *conn)
#define SOCK_STRERROR
Definition: libpq-int.h:945
static int64 end_time
Definition: pgbench.c:176
#define PG_STRERROR_R_BUFLEN
Definition: port.h:257
int pgsocket
Definition: port.h:29
pgsocket altsock
Definition: libpq-int.h:519

References pg_conn::altsock, conn, EINTR, end_time, 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 1115 of file fe-misc.c.

1116{
1117 /* We use poll(2) if available, otherwise select(2) */
1118#ifdef HAVE_POLL
1119 struct pollfd input_fd;
1120 int timeout_ms;
1121
1122 if (!forRead && !forWrite)
1123 return 0;
1124
1125 input_fd.fd = sock;
1126 input_fd.events = POLLERR;
1127 input_fd.revents = 0;
1128
1129 if (forRead)
1130 input_fd.events |= POLLIN;
1131 if (forWrite)
1132 input_fd.events |= POLLOUT;
1133
1134 /* Compute appropriate timeout interval */
1135 if (end_time == -1)
1136 timeout_ms = -1;
1137 else if (end_time == 0)
1138 timeout_ms = 0;
1139 else
1140 {
1142
1143 if (end_time > now)
1144 timeout_ms = (end_time - now) / 1000;
1145 else
1146 timeout_ms = 0;
1147 }
1148
1149 return poll(&input_fd, 1, timeout_ms);
1150#else /* !HAVE_POLL */
1151
1152 fd_set input_mask;
1153 fd_set output_mask;
1154 fd_set except_mask;
1155 struct timeval timeout;
1156 struct timeval *ptr_timeout;
1157
1158 if (!forRead && !forWrite)
1159 return 0;
1160
1161 FD_ZERO(&input_mask);
1162 FD_ZERO(&output_mask);
1163 FD_ZERO(&except_mask);
1164 if (forRead)
1165 FD_SET(sock, &input_mask);
1166
1167 if (forWrite)
1168 FD_SET(sock, &output_mask);
1169 FD_SET(sock, &except_mask);
1170
1171 /* Compute appropriate timeout interval */
1172 if (end_time == -1)
1173 ptr_timeout = NULL;
1174 else if (end_time == 0)
1175 {
1176 timeout.tv_sec = 0;
1177 timeout.tv_usec = 0;
1178 ptr_timeout = &timeout;
1179 }
1180 else
1181 {
1183
1184 if (end_time > now)
1185 {
1186 timeout.tv_sec = (end_time - now) / 1000000;
1187 timeout.tv_usec = (end_time - now) % 1000000;
1188 }
1189 else
1190 {
1191 timeout.tv_sec = 0;
1192 timeout.tv_usec = 0;
1193 }
1194 ptr_timeout = &timeout;
1195 }
1196
1197 return select(sock + 1, &input_mask, &output_mask,
1198 &except_mask, ptr_timeout);
1199#endif /* HAVE_POLL */
1200}
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1608
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition: fe-misc.c:1209
#define select(n, r, w, e, timeout)
Definition: win32_port.h:503

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

Referenced by pqSocketCheck(), and wait_until_connected().

◆ pqWait()

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

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

994{
995 return pqWaitTimed(forRead, forWrite, conn, -1);
996}
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
Definition: fe-misc.c:1009

References conn, 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 1009 of file fe-misc.c.

1010{
1011 int result;
1012
1013 result = pqSocketCheck(conn, forRead, forWrite, end_time);
1014
1015 if (result < 0)
1016 return -1; /* errorMessage is already set */
1017
1018 if (result == 0)
1019 {
1020 libpq_append_conn_error(conn, "timeout expired");
1021 return 1;
1022 }
1023
1024 return 0;
1025}

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

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

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

1043{
1044 return pqSocketCheck(conn, 0, 1, 0);
1045}

References conn, and pqSocketCheck().