PostgreSQL Source Code  git master
libpq-int.h File Reference
#include "libpq-events.h"
#include <time.h>
#include "getaddrinfo.h"
#include "libpq/pqcomm.h"
#include "fe-auth-sasl.h"
#include "pqexpbuffer.h"
Include dependency graph for libpq-int.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

union  pgresult_data
 
struct  pgresParamDesc
 
struct  pgresAttValue
 
struct  pgMessageField
 
struct  PGNoticeHooks
 
struct  PGEvent
 
struct  pg_result
 
struct  PQEnvironmentOption
 
struct  pgParameterStatus
 
struct  pgLobjfuncs
 
struct  pgDataValue
 
struct  PGcmdQueueEntry
 
struct  pg_conn_host
 
struct  pg_conn
 
struct  pg_cancel
 

Macros

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */
 
#define NULL_LEN   (-1) /* pg_result len for NULL value */
 
#define pglock_thread()   ((void) 0)
 
#define pgunlock_thread()   ((void) 0)
 
#define pqIsnonblocking(conn)   ((conn)->nonblocking)
 
#define OUTBUFFER_THRESHOLD   65536
 
#define libpq_gettext(x)   (x)
 
#define libpq_ngettext(s, p, n)   ((n) == 1 ? (s) : (p))
 
#define SOCK_ERRNO   errno
 
#define SOCK_STRERROR   strerror_r
 
#define SOCK_ERRNO_SET(e)   (errno = (e))
 

Typedefs

typedef union pgresult_data PGresult_data
 
typedef struct pgresParamDesc PGresParamDesc
 
typedef struct pgresAttValue PGresAttValue
 
typedef struct pgMessageField PGMessageField
 
typedef struct PGEvent PGEvent
 
typedef struct PQEnvironmentOption PQEnvironmentOption
 
typedef struct pgParameterStatus pgParameterStatus
 
typedef struct pgLobjfuncs PGlobjfuncs
 
typedef struct pgDataValue PGdataValue
 
typedef enum pg_conn_host_type pg_conn_host_type
 
typedef struct PGcmdQueueEntry PGcmdQueueEntry
 
typedef struct pg_conn_host pg_conn_host
 

Enumerations

enum  PGAsyncStatusType {
  PGASYNC_IDLE, PGASYNC_BUSY, PGASYNC_READY, PGASYNC_READY_MORE,
  PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_COPY_BOTH
}
 
enum  PGTargetServerType {
  SERVER_TYPE_ANY = 0, SERVER_TYPE_READ_WRITE, SERVER_TYPE_READ_ONLY, SERVER_TYPE_PRIMARY,
  SERVER_TYPE_STANDBY, SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PREFER_STANDBY_PASS2
}
 
enum  PGTernaryBool { PG_BOOL_UNKNOWN = 0, PG_BOOL_YES, PG_BOOL_NO }
 
enum  pg_conn_host_type { CHT_HOST_NAME, CHT_HOST_ADDRESS, CHT_UNIX_SOCKET }
 
enum  PGQueryClass {
  PGQUERY_SIMPLE, PGQUERY_EXTENDED, PGQUERY_PREPARE, PGQUERY_DESCRIBE,
  PGQUERY_SYNC
}
 

Functions

void pqDropConnection (PGconn *conn, bool flushInput)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
void pqSetResultError (PGresult *res, PQExpBuffer errorMessage)
 
void * pqResultAlloc (PGresult *res, size_t nBytes, bool isBinary)
 
char * pqResultStrdup (PGresult *res, const char *str)
 
void pqClearAsyncResult (PGconn *conn)
 
void pqSaveErrorResult (PGconn *conn)
 
PGresultpqPrepareAsyncResult (PGconn *conn)
 
void pqInternalNotice (const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2
 
void void pqSaveMessageField (PGresult *res, char code, const char *value)
 
void pqSaveParameterStatus (PGconn *conn, const char *name, const char *value)
 
int pqRowProcessor (PGconn *conn, const char **errmsgp)
 
void pqCommandQueueAdvance (PGconn *conn)
 
int PQsendQueryContinue (PGconn *conn, const char *query)
 
char * pqBuildStartupPacket3 (PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
 
void pqParseInput3 (PGconn *conn)
 
int pqGetErrorNotice3 (PGconn *conn, bool isError)
 
void pqBuildErrorMessage3 (PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
 
int pqGetCopyData3 (PGconn *conn, char **buffer, int async)
 
int pqGetline3 (PGconn *conn, char *s, int maxlen)
 
int pqGetlineAsync3 (PGconn *conn, char *buffer, int bufsize)
 
int pqEndcopy3 (PGconn *conn)
 
PGresultpqFunctionCall3 (PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
int pqCheckOutBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqCheckInBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqGetc (char *result, PGconn *conn)
 
int pqPutc (char c, PGconn *conn)
 
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 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, time_t finish_time)
 
int pqReadReady (PGconn *conn)
 
int pqWriteReady (PGconn *conn)
 
int pqsecure_initialize (PGconn *, bool, bool)
 
PostgresPollingStatusType pqsecure_open_client (PGconn *)
 
void pqsecure_close (PGconn *)
 
ssize_t pqsecure_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_write (PGconn *, const void *ptr, size_t len)
 
ssize_t pqsecure_raw_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_raw_write (PGconn *, const void *ptr, size_t len)
 
void pgtls_init_library (bool do_ssl, int do_crypto)
 
int pgtls_init (PGconn *conn, bool do_ssl, bool do_crypto)
 
PostgresPollingStatusType pgtls_open_client (PGconn *conn)
 
void pgtls_close (PGconn *conn)
 
ssize_t pgtls_read (PGconn *conn, void *ptr, size_t len)
 
bool pgtls_read_pending (PGconn *conn)
 
ssize_t pgtls_write (PGconn *conn, const void *ptr, size_t len)
 
int pgtls_verify_peer_name_matches_certificate_guts (PGconn *conn, int *names_examined, char **first_name)
 
void pqTraceOutputMessage (PGconn *conn, const char *message, bool toServer)
 
void pqTraceOutputNoTypeByteMessage (PGconn *conn, const char *message)
 

Variables

char *const pgresStatus []
 

Macro Definition Documentation

◆ CMDSTATUS_LEN

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */

Definition at line 87 of file libpq-int.h.

Referenced by pqParseInput3().

◆ libpq_gettext

#define libpq_gettext (   x)    (x)

Definition at line 841 of file libpq-int.h.

Referenced by build_client_final_message(), build_client_first_message(), check_expected_areq(), connectFailureMessage(), connectNoDelay(), connectOptions2(), conninfo_add_defaults(), conninfo_array_parse(), conninfo_init(), conninfo_parse(), conninfo_storeval(), conninfo_uri_decode(), conninfo_uri_parse_options(), conninfo_uri_parse_params(), do_field(), do_header(), emitHostIdentityInfo(), fillPGconn(), getAnotherTuple(), getParamDescriptions(), getRowDescriptions(), handleSyncLoss(), 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_name(), parse_int_param(), parseServiceFile(), parseServiceInfo(), passwordFromFile(), pg_fe_getauthname(), pg_fe_sendauth(), pg_GSS_load_servicename(), pg_GSS_read(), pg_GSS_write(), pg_local_sendauth(), pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pgpassfileWarning(), pgtls_read(), pgtls_write(), pq_verify_peer_name_matches_certificate(), pq_verify_peer_name_matches_certificate_name(), pqAddTuple(), pqAllocCmdQueueEntry(), pqBuildErrorMessage3(), PQconnectPoll(), PQdefaultSSLKeyPassHook_OpenSSL(), PQdisplayTuples(), PQencryptPasswordConn(), pqEndcopy3(), PQenterPipelineMode(), PQenv2encoding(), PQerrorMessage(), PQescapeByteaInternal(), PQescapeInternal(), PQescapeStringInternal(), PQexecStart(), PQexitPipelineMode(), PQfn(), pqFunctionCall3(), PQgetCopyData(), pqGetCopyData3(), pqGetErrorNotice3(), pqGetline3(), PQgetResult(), pqInternalNotice(), pqPacketSend(), pqParseInput3(), pqPipelineProcessQueue(), PQpipelineSync(), PQprint(), PQprintTuples(), PQputCopyData(), PQputCopyEnd(), pqReadData(), PQreset(), PQresetPoll(), PQresStatus(), PQresultVerboseErrorMessage(), pqSaveWriteError(), pqsecure_open_gss(), pqsecure_raw_read(), pqsecure_raw_write(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendQueryParams(), PQsendQueryPrepared(), PQsendQueryStart(), pqSendSome(), PQsetdbLogin(), pqSetResultError(), PQsetvalue(), pqSocketCheck(), pqWaitTimed(), read_attr_value(), read_server_final_message(), read_server_first_message(), reportErrorPosition(), scram_exchange(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), setTCPUserTimeout(), and SSLerrmessage().

◆ libpq_ngettext

#define libpq_ngettext (   s,
  p,
 
)    ((n) == 1 ? (s) : (p))

Definition at line 842 of file libpq-int.h.

Referenced by pq_verify_peer_name_matches_certificate(), and PQenv2encoding().

◆ NULL_LEN

#define NULL_LEN   (-1) /* pg_result len for NULL value */

Definition at line 134 of file libpq-int.h.

Referenced by PQgetisnull(), PQgetlength(), pqRowProcessor(), and PQsetvalue().

◆ OUTBUFFER_THRESHOLD

#define OUTBUFFER_THRESHOLD   65536

Definition at line 835 of file libpq-int.h.

Referenced by pqPipelineFlush().

◆ pglock_thread

#define pglock_thread ( )    ((void) 0)

Definition at line 634 of file libpq-int.h.

Referenced by pg_fe_getauthname(), and pg_fe_sendauth().

◆ pgunlock_thread

#define pgunlock_thread ( )    ((void) 0)

Definition at line 635 of file libpq-int.h.

Referenced by pg_fe_getauthname(), and pg_fe_sendauth().

◆ pqIsnonblocking

#define pqIsnonblocking (   conn)    ((conn)->nonblocking)

Definition at line 830 of file libpq-int.h.

Referenced by PQconsumeInput(), pqEndcopy3(), PQisnonblocking(), PQputCopyData(), and pqSendSome().

◆ SOCK_ERRNO

◆ SOCK_ERRNO_SET

#define SOCK_ERRNO_SET (   e)    (errno = (e))

◆ SOCK_STRERROR

Typedef Documentation

◆ pg_conn_host

typedef struct pg_conn_host pg_conn_host

◆ pg_conn_host_type

◆ PGcmdQueueEntry

◆ PGdataValue

typedef struct pgDataValue PGdataValue

◆ PGEvent

typedef struct PGEvent PGEvent

◆ PGlobjfuncs

typedef struct pgLobjfuncs PGlobjfuncs

◆ PGMessageField

◆ pgParameterStatus

◆ PGresAttValue

typedef struct pgresAttValue PGresAttValue

◆ PGresParamDesc

◆ PGresult_data

Definition at line 102 of file libpq-int.h.

◆ PQEnvironmentOption

Enumeration Type Documentation

◆ pg_conn_host_type

Enumerator
CHT_HOST_NAME 
CHT_HOST_ADDRESS 
CHT_UNIX_SOCKET 

Definition at line 297 of file libpq-int.h.

◆ PGAsyncStatusType

Enumerator
PGASYNC_IDLE 
PGASYNC_BUSY 
PGASYNC_READY 
PGASYNC_READY_MORE 
PGASYNC_COPY_IN 
PGASYNC_COPY_OUT 
PGASYNC_COPY_BOTH 

Definition at line 217 of file libpq-int.h.

218 {
219  PGASYNC_IDLE, /* nothing's happening, dude */
220  PGASYNC_BUSY, /* query in progress */
221  PGASYNC_READY, /* query done, waiting for client to fetch
222  * result */
223  PGASYNC_READY_MORE, /* query done, waiting for client to fetch
224  * result, more results expected from this
225  * query */
226  PGASYNC_COPY_IN, /* Copy In data transfer in progress */
227  PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */
228  PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */
PGAsyncStatusType
Definition: libpq-int.h:217

◆ PGQueryClass

Enumerator
PGQUERY_SIMPLE 
PGQUERY_EXTENDED 
PGQUERY_PREPARE 
PGQUERY_DESCRIBE 
PGQUERY_SYNC 

Definition at line 308 of file libpq-int.h.

309 {
310  PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
311  PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
312  PGQUERY_PREPARE, /* Parse only (PQprepare) */
313  PGQUERY_DESCRIBE, /* Describe Statement or Portal */
314  PGQUERY_SYNC /* Sync (at end of a pipeline) */
315 } PGQueryClass;
PGQueryClass
Definition: libpq-int.h:308

◆ PGTargetServerType

Enumerator
SERVER_TYPE_ANY 
SERVER_TYPE_READ_WRITE 
SERVER_TYPE_READ_ONLY 
SERVER_TYPE_PRIMARY 
SERVER_TYPE_STANDBY 
SERVER_TYPE_PREFER_STANDBY 
SERVER_TYPE_PREFER_STANDBY_PASS2 

Definition at line 232 of file libpq-int.h.

233 {
234  SERVER_TYPE_ANY = 0, /* Any server (default) */
235  SERVER_TYPE_READ_WRITE, /* Read-write server */
236  SERVER_TYPE_READ_ONLY, /* Read-only server */
237  SERVER_TYPE_PRIMARY, /* Primary server */
238  SERVER_TYPE_STANDBY, /* Standby server */
239  SERVER_TYPE_PREFER_STANDBY, /* Prefer standby server */
240  SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */
PGTargetServerType
Definition: libpq-int.h:232

◆ PGTernaryBool

Enumerator
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 

Definition at line 244 of file libpq-int.h.

245 {
246  PG_BOOL_UNKNOWN = 0, /* Currently unknown */
247  PG_BOOL_YES, /* Yes (true) */
248  PG_BOOL_NO /* No (false) */
249 } PGTernaryBool;
PGTernaryBool
Definition: libpq-int.h:244

Function Documentation

◆ pgtls_close()

void pgtls_close ( PGconn conn)

Definition at line 1438 of file fe-secure-openssl.c.

References destroy_ssl_system(), and pg_conn::ssl_in_use.

Referenced by open_client_SSL(), pgtls_open_client(), and pqsecure_close().

1439 {
1440  bool destroy_needed = false;
1441 
1442  if (conn->ssl_in_use)
1443  {
1444  if (conn->ssl)
1445  {
1446  /*
1447  * We can't destroy everything SSL-related here due to the
1448  * possible later calls to OpenSSL routines which may need our
1449  * thread callbacks, so set a flag here and check at the end.
1450  */
1451 
1452  SSL_shutdown(conn->ssl);
1453  SSL_free(conn->ssl);
1454  conn->ssl = NULL;
1455  conn->ssl_in_use = false;
1456 
1457  destroy_needed = true;
1458  }
1459 
1460  if (conn->peer)
1461  {
1462  X509_free(conn->peer);
1463  conn->peer = NULL;
1464  }
1465 
1466 #ifdef USE_SSL_ENGINE
1467  if (conn->engine)
1468  {
1469  ENGINE_finish(conn->engine);
1470  ENGINE_free(conn->engine);
1471  conn->engine = NULL;
1472  }
1473 #endif
1474  }
1475  else
1476  {
1477  /*
1478  * In the non-SSL case, just remove the crypto callbacks if the
1479  * connection has then loaded. This code path has no dependency on
1480  * any pending SSL calls.
1481  */
1482  if (conn->crypto_loaded)
1483  destroy_needed = true;
1484  }
1485 
1486  /*
1487  * This will remove our crypto locking hooks if this is the last
1488  * connection using libcrypto which means we must wait to call it until
1489  * after all the potential SSL calls have been made, otherwise we can end
1490  * up with a race condition and possible deadlocks.
1491  *
1492  * See comments above destroy_ssl_system().
1493  */
1494  if (destroy_needed)
1495  {
1497  conn->crypto_loaded = false;
1498  }
1499 }
bool ssl_in_use
Definition: libpq-int.h:508
static void destroy_ssl_system(void)

◆ pgtls_init()

int pgtls_init ( PGconn conn,
bool  do_ssl,
bool  do_crypto 
)

Definition at line 643 of file fe-secure-openssl.c.

References free, i, malloc, pq_init_crypto_lib, pq_init_ssl_lib, pthread_mutex_init(), pthread_mutex_lock(), pthread_mutex_unlock(), and ssl_lib_initialized.

Referenced by pqsecure_initialize().

644 {
645 #ifdef ENABLE_THREAD_SAFETY
646 #ifdef WIN32
647  /* Also see similar code in fe-connect.c, default_threadlock() */
648  if (ssl_config_mutex == NULL)
649  {
650  while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
651  /* loop, another thread own the lock */ ;
652  if (ssl_config_mutex == NULL)
653  {
654  if (pthread_mutex_init(&ssl_config_mutex, NULL))
655  return -1;
656  }
657  InterlockedExchange(&win32_ssl_create_mutex, 0);
658  }
659 #endif
660  if (pthread_mutex_lock(&ssl_config_mutex))
661  return -1;
662 
663 #ifdef HAVE_CRYPTO_LOCK
664  if (pq_init_crypto_lib)
665  {
666  /*
667  * If necessary, set up an array to hold locks for libcrypto.
668  * libcrypto will tell us how big to make this array.
669  */
670  if (pq_lockarray == NULL)
671  {
672  int i;
673 
674  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
675  if (!pq_lockarray)
676  {
677  pthread_mutex_unlock(&ssl_config_mutex);
678  return -1;
679  }
680  for (i = 0; i < CRYPTO_num_locks(); i++)
681  {
682  if (pthread_mutex_init(&pq_lockarray[i], NULL))
683  {
684  free(pq_lockarray);
685  pq_lockarray = NULL;
686  pthread_mutex_unlock(&ssl_config_mutex);
687  return -1;
688  }
689  }
690  }
691 
692  if (do_crypto && !conn->crypto_loaded)
693  {
694  if (crypto_open_connections++ == 0)
695  {
696  /*
697  * These are only required for threaded libcrypto
698  * applications, but make sure we don't stomp on them if
699  * they're already set.
700  */
701  if (CRYPTO_get_id_callback() == NULL)
702  CRYPTO_set_id_callback(pq_threadidcallback);
703  if (CRYPTO_get_locking_callback() == NULL)
704  CRYPTO_set_locking_callback(pq_lockingcallback);
705  }
706 
707  conn->crypto_loaded = true;
708  }
709  }
710 #endif /* HAVE_CRYPTO_LOCK */
711 #endif /* ENABLE_THREAD_SAFETY */
712 
713  if (!ssl_lib_initialized && do_ssl)
714  {
715  if (pq_init_ssl_lib)
716  {
717 #ifdef HAVE_OPENSSL_INIT_SSL
718  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
719 #else
720  OPENSSL_config(NULL);
721  SSL_library_init();
722  SSL_load_error_strings();
723 #endif
724  }
725  ssl_lib_initialized = true;
726  }
727 
728 #ifdef ENABLE_THREAD_SAFETY
729  pthread_mutex_unlock(&ssl_config_mutex);
730 #endif
731  return 0;
732 }
static bool pq_init_ssl_lib
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
#define malloc(a)
Definition: header.h:50
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
static bool pq_init_crypto_lib
#define free(a)
Definition: header.h:65
int i
static bool ssl_lib_initialized

◆ pgtls_init_library()

void pgtls_init_library ( bool  do_ssl,
int  do_crypto 
)

Definition at line 106 of file fe-secure-openssl.c.

References pq_init_crypto_lib, and pq_init_ssl_lib.

Referenced by PQinitOpenSSL(), and PQinitSSL().

107 {
108 #ifdef ENABLE_THREAD_SAFETY
109 
110  /*
111  * Disallow changing the flags while we have open connections, else we'd
112  * get completely confused.
113  */
114  if (crypto_open_connections != 0)
115  return;
116 #endif
117 
118  pq_init_ssl_lib = do_ssl;
119  pq_init_crypto_lib = do_crypto;
120 }
static bool pq_init_ssl_lib
static bool pq_init_crypto_lib

◆ pgtls_open_client()

PostgresPollingStatusType pgtls_open_client ( PGconn conn)

Definition at line 123 of file fe-secure-openssl.c.

References initialize_SSL(), open_client_SSL(), PGRES_POLLING_FAILED, and pgtls_close().

Referenced by pqsecure_open_client().

124 {
125  /* First time through? */
126  if (conn->ssl == NULL)
127  {
128  /*
129  * Create a connection-specific SSL object, and load client
130  * certificate, private key, and trusted CA certs.
131  */
132  if (initialize_SSL(conn) != 0)
133  {
134  /* initialize_SSL already put a message in conn->errorMessage */
135  pgtls_close(conn);
136  return PGRES_POLLING_FAILED;
137  }
138  }
139 
140  /* Begin or continue the actual handshake */
141  return open_client_SSL(conn);
142 }
static PostgresPollingStatusType open_client_SSL(PGconn *)
static int initialize_SSL(PGconn *conn)
void pgtls_close(PGconn *conn)

◆ pgtls_read()

ssize_t pgtls_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 145 of file fe-secure-openssl.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), ECONNRESET, pg_conn::errorMessage, libpq_gettext, PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_read().

146 {
147  ssize_t n;
148  int result_errno = 0;
149  char sebuf[PG_STRERROR_R_BUFLEN];
150  int err;
151  unsigned long ecode;
152 
153 rloop:
154 
155  /*
156  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
157  * queue. In general, the current thread's error queue must be empty
158  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
159  * not work reliably. Since the possibility exists that other OpenSSL
160  * clients running in the same thread but not under our control will fail
161  * to call ERR_get_error() themselves (after their own I/O operations),
162  * pro-actively clear the per-thread error queue now.
163  */
164  SOCK_ERRNO_SET(0);
165  ERR_clear_error();
166  n = SSL_read(conn->ssl, ptr, len);
167  err = SSL_get_error(conn->ssl, n);
168 
169  /*
170  * Other clients of OpenSSL may fail to call ERR_get_error(), but we
171  * always do, so as to not cause problems for OpenSSL clients that don't
172  * call ERR_clear_error() defensively. Be sure that this happens by
173  * calling now. SSL_get_error() relies on the OpenSSL per-thread error
174  * queue being intact, so this is the earliest possible point
175  * ERR_get_error() may be called.
176  */
177  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
178  switch (err)
179  {
180  case SSL_ERROR_NONE:
181  if (n < 0)
182  {
183  /* Not supposed to happen, so we don't translate the msg */
185  "SSL_read failed but did not provide error information\n");
186  /* assume the connection is broken */
187  result_errno = ECONNRESET;
188  }
189  break;
190  case SSL_ERROR_WANT_READ:
191  n = 0;
192  break;
193  case SSL_ERROR_WANT_WRITE:
194 
195  /*
196  * Returning 0 here would cause caller to wait for read-ready,
197  * which is not correct since what SSL wants is wait for
198  * write-ready. The former could get us stuck in an infinite
199  * wait, so don't risk it; busy-loop instead.
200  */
201  goto rloop;
202  case SSL_ERROR_SYSCALL:
203  if (n < 0)
204  {
205  result_errno = SOCK_ERRNO;
206  if (result_errno == EPIPE ||
207  result_errno == ECONNRESET)
209  libpq_gettext("server closed the connection unexpectedly\n"
210  "\tThis probably means the server terminated abnormally\n"
211  "\tbefore or while processing the request.\n"));
212  else
214  libpq_gettext("SSL SYSCALL error: %s\n"),
215  SOCK_STRERROR(result_errno,
216  sebuf, sizeof(sebuf)));
217  }
218  else
219  {
221  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
222  /* assume the connection is broken */
223  result_errno = ECONNRESET;
224  n = -1;
225  }
226  break;
227  case SSL_ERROR_SSL:
228  {
229  char *errm = SSLerrmessage(ecode);
230 
232  libpq_gettext("SSL error: %s\n"), errm);
233  SSLerrfree(errm);
234  /* assume the connection is broken */
235  result_errno = ECONNRESET;
236  n = -1;
237  break;
238  }
239  case SSL_ERROR_ZERO_RETURN:
240 
241  /*
242  * Per OpenSSL documentation, this error code is only returned for
243  * a clean connection closure, so we should not report it as a
244  * server crash.
245  */
247  libpq_gettext("SSL connection has been closed unexpectedly\n"));
248  result_errno = ECONNRESET;
249  n = -1;
250  break;
251  default:
253  libpq_gettext("unrecognized SSL error code: %d\n"),
254  err);
255  /* assume the connection is broken */
256  result_errno = ECONNRESET;
257  n = -1;
258  break;
259  }
260 
261  /* ensure we return the intended errno to caller */
262  SOCK_ERRNO_SET(result_errno);
263 
264  return n;
265 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define PG_STRERROR_R_BUFLEN
Definition: port.h:235
#define SOCK_STRERROR
Definition: libpq-int.h:855
#define SOCK_ERRNO
Definition: libpq-int.h:854
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:856
static void SSLerrfree(char *buf)
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define ECONNRESET
Definition: win32_port.h:361
static char * SSLerrmessage(unsigned long ecode)
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pgtls_read_pending()

bool pgtls_read_pending ( PGconn conn)

Definition at line 268 of file fe-secure-openssl.c.

Referenced by pqSocketCheck().

269 {
270  return SSL_pending(conn->ssl) > 0;
271 }

◆ pgtls_verify_peer_name_matches_certificate_guts()

int pgtls_verify_peer_name_matches_certificate_guts ( PGconn conn,
int *  names_examined,
char **  first_name 
)

Definition at line 512 of file fe-secure-openssl.c.

References Assert, free, i, mode, name, openssl_verify_peer_name_matches_certificate_name(), pthread_mutex_lock(), pthread_mutex_unlock(), and pthread_self().

Referenced by pq_verify_peer_name_matches_certificate().

515 {
516  STACK_OF(GENERAL_NAME) * peer_san;
517  int i;
518  int rc = 0;
519 
520  /*
521  * First, get the Subject Alternative Names (SANs) from the certificate,
522  * and compare them against the originally given hostname.
523  */
524  peer_san = (STACK_OF(GENERAL_NAME) *)
525  X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
526 
527  if (peer_san)
528  {
529  int san_len = sk_GENERAL_NAME_num(peer_san);
530 
531  for (i = 0; i < san_len; i++)
532  {
533  const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
534 
535  if (name->type == GEN_DNS)
536  {
537  char *alt_name;
538 
539  (*names_examined)++;
541  name->d.dNSName,
542  &alt_name);
543 
544  if (alt_name)
545  {
546  if (!*first_name)
547  *first_name = alt_name;
548  else
549  free(alt_name);
550  }
551  }
552  if (rc != 0)
553  break;
554  }
555  sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
556  }
557 
558  /*
559  * If there is no subjectAltName extension of type dNSName, check the
560  * Common Name.
561  *
562  * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
563  * dNSName is present, the CN must be ignored.)
564  */
565  if (*names_examined == 0)
566  {
567  X509_NAME *subject_name;
568 
569  subject_name = X509_get_subject_name(conn->peer);
570  if (subject_name != NULL)
571  {
572  int cn_index;
573 
574  cn_index = X509_NAME_get_index_by_NID(subject_name,
575  NID_commonName, -1);
576  if (cn_index >= 0)
577  {
578  (*names_examined)++;
580  X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
581  first_name);
582  }
583  }
584  }
585 
586  return rc;
587 }
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name, char **store_name)
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:561
int i

◆ pgtls_write()

ssize_t pgtls_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 274 of file fe-secure-openssl.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), conn, ECONNRESET, pg_conn::errorMessage, hash(), libpq_gettext, malloc, PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_write().

275 {
276  ssize_t n;
277  int result_errno = 0;
278  char sebuf[PG_STRERROR_R_BUFLEN];
279  int err;
280  unsigned long ecode;
281 
282  SOCK_ERRNO_SET(0);
283  ERR_clear_error();
284  n = SSL_write(conn->ssl, ptr, len);
285  err = SSL_get_error(conn->ssl, n);
286  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
287  switch (err)
288  {
289  case SSL_ERROR_NONE:
290  if (n < 0)
291  {
292  /* Not supposed to happen, so we don't translate the msg */
294  "SSL_write failed but did not provide error information\n");
295  /* assume the connection is broken */
296  result_errno = ECONNRESET;
297  }
298  break;
299  case SSL_ERROR_WANT_READ:
300 
301  /*
302  * Returning 0 here causes caller to wait for write-ready, which
303  * is not really the right thing, but it's the best we can do.
304  */
305  n = 0;
306  break;
307  case SSL_ERROR_WANT_WRITE:
308  n = 0;
309  break;
310  case SSL_ERROR_SYSCALL:
311  if (n < 0)
312  {
313  result_errno = SOCK_ERRNO;
314  if (result_errno == EPIPE || result_errno == ECONNRESET)
316  libpq_gettext("server closed the connection unexpectedly\n"
317  "\tThis probably means the server terminated abnormally\n"
318  "\tbefore or while processing the request.\n"));
319  else
321  libpq_gettext("SSL SYSCALL error: %s\n"),
322  SOCK_STRERROR(result_errno,
323  sebuf, sizeof(sebuf)));
324  }
325  else
326  {
328  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
329  /* assume the connection is broken */
330  result_errno = ECONNRESET;
331  n = -1;
332  }
333  break;
334  case SSL_ERROR_SSL:
335  {
336  char *errm = SSLerrmessage(ecode);
337 
339  libpq_gettext("SSL error: %s\n"), errm);
340  SSLerrfree(errm);
341  /* assume the connection is broken */
342  result_errno = ECONNRESET;
343  n = -1;
344  break;
345  }
346  case SSL_ERROR_ZERO_RETURN:
347 
348  /*
349  * Per OpenSSL documentation, this error code is only returned for
350  * a clean connection closure, so we should not report it as a
351  * server crash.
352  */
354  libpq_gettext("SSL connection has been closed unexpectedly\n"));
355  result_errno = ECONNRESET;
356  n = -1;
357  break;
358  default:
360  libpq_gettext("unrecognized SSL error code: %d\n"),
361  err);
362  /* assume the connection is broken */
363  result_errno = ECONNRESET;
364  n = -1;
365  break;
366  }
367 
368  /* ensure we return the intended errno to caller */
369  SOCK_ERRNO_SET(result_errno);
370 
371  return n;
372 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define PG_STRERROR_R_BUFLEN
Definition: port.h:235
#define SOCK_STRERROR
Definition: libpq-int.h:855
#define SOCK_ERRNO
Definition: libpq-int.h:854
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:856
static void SSLerrfree(char *buf)
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define ECONNRESET
Definition: win32_port.h:361
static char * SSLerrmessage(unsigned long ecode)
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqBuildErrorMessage3()

void pqBuildErrorMessage3 ( PQExpBuffer  msg,
const PGresult res,
PGVerbosity  verbosity,
PGContextVisibility  show_context 
)

Definition at line 1013 of file fe-protocol3.c.

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), pg_result::client_encoding, pg_result::errFields, pg_result::errMsg, pg_result::errQuery, libpq_gettext, PG_DIAG_COLUMN_NAME, PG_DIAG_CONSTRAINT_NAME, PG_DIAG_CONTEXT, PG_DIAG_DATATYPE_NAME, PG_DIAG_INTERNAL_POSITION, PG_DIAG_INTERNAL_QUERY, PG_DIAG_MESSAGE_DETAIL, PG_DIAG_MESSAGE_HINT, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SCHEMA_NAME, PG_DIAG_SEVERITY, PG_DIAG_SOURCE_FILE, PG_DIAG_SOURCE_FUNCTION, PG_DIAG_SOURCE_LINE, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PG_DIAG_TABLE_NAME, PGRES_FATAL_ERROR, PQERRORS_SQLSTATE, PQERRORS_TERSE, PQERRORS_VERBOSE, PQresultErrorField(), PQSHOW_CONTEXT_ALWAYS, PQSHOW_CONTEXT_ERRORS, reportErrorPosition(), pg_result::resultStatus, and val.

Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().

1015 {
1016  const char *val;
1017  const char *querytext = NULL;
1018  int querypos = 0;
1019 
1020  /* If we couldn't allocate a PGresult, just say "out of memory" */
1021  if (res == NULL)
1022  {
1023  appendPQExpBufferStr(msg, libpq_gettext("out of memory\n"));
1024  return;
1025  }
1026 
1027  /*
1028  * If we don't have any broken-down fields, just return the base message.
1029  * This mainly applies if we're given a libpq-generated error result.
1030  */
1031  if (res->errFields == NULL)
1032  {
1033  if (res->errMsg && res->errMsg[0])
1034  appendPQExpBufferStr(msg, res->errMsg);
1035  else
1036  appendPQExpBufferStr(msg, libpq_gettext("no error message available\n"));
1037  return;
1038  }
1039 
1040  /* Else build error message from relevant fields */
1042  if (val)
1043  appendPQExpBuffer(msg, "%s: ", val);
1044 
1045  if (verbosity == PQERRORS_SQLSTATE)
1046  {
1047  /*
1048  * If we have a SQLSTATE, print that and nothing else. If not (which
1049  * shouldn't happen for server-generated errors, but might possibly
1050  * happen for libpq-generated ones), fall back to TERSE format, as
1051  * that seems better than printing nothing at all.
1052  */
1054  if (val)
1055  {
1056  appendPQExpBuffer(msg, "%s\n", val);
1057  return;
1058  }
1059  verbosity = PQERRORS_TERSE;
1060  }
1061 
1062  if (verbosity == PQERRORS_VERBOSE)
1063  {
1065  if (val)
1066  appendPQExpBuffer(msg, "%s: ", val);
1067  }
1069  if (val)
1070  appendPQExpBufferStr(msg, val);
1072  if (val)
1073  {
1074  if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1075  {
1076  /* emit position as a syntax cursor display */
1077  querytext = res->errQuery;
1078  querypos = atoi(val);
1079  }
1080  else
1081  {
1082  /* emit position as text addition to primary message */
1083  /* translator: %s represents a digit string */
1084  appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1085  val);
1086  }
1087  }
1088  else
1089  {
1091  if (val)
1092  {
1093  querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1094  if (verbosity != PQERRORS_TERSE && querytext != NULL)
1095  {
1096  /* emit position as a syntax cursor display */
1097  querypos = atoi(val);
1098  }
1099  else
1100  {
1101  /* emit position as text addition to primary message */
1102  /* translator: %s represents a digit string */
1103  appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1104  val);
1105  }
1106  }
1107  }
1108  appendPQExpBufferChar(msg, '\n');
1109  if (verbosity != PQERRORS_TERSE)
1110  {
1111  if (querytext && querypos > 0)
1112  reportErrorPosition(msg, querytext, querypos,
1113  res->client_encoding);
1115  if (val)
1116  appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1118  if (val)
1119  appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1121  if (val)
1122  appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1123  if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1124  (show_context == PQSHOW_CONTEXT_ERRORS &&
1126  {
1127  val = PQresultErrorField(res, PG_DIAG_CONTEXT);
1128  if (val)
1129  appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1130  val);
1131  }
1132  }
1133  if (verbosity == PQERRORS_VERBOSE)
1134  {
1136  if (val)
1137  appendPQExpBuffer(msg,
1138  libpq_gettext("SCHEMA NAME: %s\n"), val);
1140  if (val)
1141  appendPQExpBuffer(msg,
1142  libpq_gettext("TABLE NAME: %s\n"), val);
1144  if (val)
1145  appendPQExpBuffer(msg,
1146  libpq_gettext("COLUMN NAME: %s\n"), val);
1148  if (val)
1149  appendPQExpBuffer(msg,
1150  libpq_gettext("DATATYPE NAME: %s\n"), val);
1152  if (val)
1153  appendPQExpBuffer(msg,
1154  libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1155  }
1156  if (verbosity == PQERRORS_VERBOSE)
1157  {
1158  const char *valf;
1159  const char *vall;
1160 
1164  if (val || valf || vall)
1165  {
1166  appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1167  if (val)
1168  appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1169  if (valf && vall) /* unlikely we'd have just one */
1170  appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1171  valf, vall);
1172  appendPQExpBufferChar(msg, '\n');
1173  }
1174  }
1175 }
PGMessageField * errFields
Definition: libpq-int.h:198
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:67
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:66
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:71
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:62
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * errMsg
Definition: libpq-int.h:197
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:70
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
char * errQuery
Definition: libpq-int.h:199
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:68
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:69
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:63
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3233
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:72
ExecStatusType resultStatus
Definition: libpq-int.h:178
long val
Definition: informix.c:664
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64
#define libpq_gettext(x)
Definition: libpq-int.h:841
int client_encoding
Definition: libpq-int.h:190

◆ pqBuildStartupPacket3()

char* pqBuildStartupPacket3 ( PGconn conn,
int *  packetlen,
const PQEnvironmentOption options 
)

Definition at line 2164 of file fe-protocol3.c.

References build_startup_packet(), and malloc.

Referenced by PQconnectPoll().

2166 {
2167  char *startpacket;
2168 
2169  *packetlen = build_startup_packet(conn, NULL, options);
2170  startpacket = (char *) malloc(*packetlen);
2171  if (!startpacket)
2172  return NULL;
2173  *packetlen = build_startup_packet(conn, startpacket, options);
2174  return startpacket;
2175 }
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)
#define malloc(a)
Definition: header.h:50

◆ pqCheckInBufferSpace()

int pqCheckInBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

References appendPQExpBufferStr(), 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().

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

◆ pqCheckOutBufferSpace()

int pqCheckOutBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

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

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

291 {
292  int newsize = conn->outBufSize;
293  char *newbuf;
294 
295  /* Quick exit if we have enough space */
296  if (bytes_needed <= (size_t) newsize)
297  return 0;
298 
299  /*
300  * If we need to enlarge the buffer, we first try to double it in size; if
301  * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
302  * the malloc pool by repeated small enlargements.
303  *
304  * Note: tests for newsize > 0 are to catch integer overflow.
305  */
306  do
307  {
308  newsize *= 2;
309  } while (newsize > 0 && bytes_needed > (size_t) newsize);
310 
311  if (newsize > 0 && bytes_needed <= (size_t) newsize)
312  {
313  newbuf = realloc(conn->outBuffer, newsize);
314  if (newbuf)
315  {
316  /* realloc succeeded */
317  conn->outBuffer = newbuf;
318  conn->outBufSize = newsize;
319  return 0;
320  }
321  }
322 
323  newsize = conn->outBufSize;
324  do
325  {
326  newsize += 8192;
327  } while (newsize > 0 && bytes_needed > (size_t) newsize);
328 
329  if (newsize > 0 && bytes_needed <= (size_t) newsize)
330  {
331  newbuf = realloc(conn->outBuffer, newsize);
332  if (newbuf)
333  {
334  /* realloc succeeded */
335  conn->outBuffer = newbuf;
336  conn->outBufSize = newsize;
337  return 0;
338  }
339  }
340 
341  /* realloc failed. Probably out of memory */
343  "cannot allocate memory for output buffer\n");
344  return EOF;
345 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
PQExpBufferData errorMessage
Definition: libpq-int.h:571
int outBufSize
Definition: libpq-int.h:487
#define realloc(a, b)
Definition: header.h:60
char * outBuffer
Definition: libpq-int.h:486

◆ pqClearAsyncResult()

void pqClearAsyncResult ( PGconn conn)

Definition at line 749 of file fe-exec.c.

References pg_conn::next_result, PQclear(), and pg_conn::result.

Referenced by closePGconn(), getAnotherTuple(), getParamDescriptions(), getRowDescriptions(), PQconnectPoll(), pqGetErrorNotice3(), pqPipelineProcessQueue(), pqSaveErrorResult(), and PQsendQueryStart().

750 {
751  if (conn->result)
752  PQclear(conn->result);
753  conn->result = NULL;
754  if (conn->next_result)
755  PQclear(conn->next_result);
756  conn->next_result = NULL;
757 }
PGresult * result
Definition: libpq-int.h:500
PGresult * next_result
Definition: libpq-int.h:501
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ pqCommandQueueAdvance()

void pqCommandQueueAdvance ( PGconn conn)

Definition at line 2976 of file fe-exec.c.

References pg_conn::cmd_queue_head, PGcmdQueueEntry::next, and pqRecycleCmdQueueEntry().

Referenced by PQgetResult(), and pqParseInput3().

2977 {
2978  PGcmdQueueEntry *prevquery;
2979 
2980  if (conn->cmd_queue_head == NULL)
2981  return;
2982 
2983  /* delink from queue */
2984  prevquery = conn->cmd_queue_head;
2985  conn->cmd_queue_head = conn->cmd_queue_head->next;
2986 
2987  /* and make it recyclable */
2988  prevquery->next = NULL;
2989  pqRecycleCmdQueueEntry(conn, prevquery);
2990 }
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:434
struct PGcmdQueueEntry * next
Definition: libpq-int.h:324
static void pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
Definition: fe-exec.c:1296

◆ pqDropConnection()

void pqDropConnection ( PGconn conn,
bool  flushInput 
)

Definition at line 448 of file fe-connect.c.

References closesocket, free, pg_fe_sasl_mech::free, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, pg_conn::outCount, PGINVALID_SOCKET, pqsecure_close(), pg_conn::sasl, pg_conn::sasl_state, and pg_conn::sock.

Referenced by closePGconn(), connectDBStart(), handleSyncLoss(), PQconnectPoll(), and pqReadData().

449 {
450  /* Drop any SSL state */
451  pqsecure_close(conn);
452 
453  /* Close the socket itself */
454  if (conn->sock != PGINVALID_SOCKET)
455  closesocket(conn->sock);
456  conn->sock = PGINVALID_SOCKET;
457 
458  /* Optionally discard any unread data */
459  if (flushInput)
460  conn->inStart = conn->inCursor = conn->inEnd = 0;
461 
462  /* Always discard any unsent data */
463  conn->outCount = 0;
464 
465  /* Free authentication/encryption state */
466 #ifdef ENABLE_GSS
467  {
468  OM_uint32 min_s;
469 
470  if (conn->gcred != GSS_C_NO_CREDENTIAL)
471  {
472  gss_release_cred(&min_s, &conn->gcred);
473  conn->gcred = GSS_C_NO_CREDENTIAL;
474  }
475  if (conn->gctx)
476  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
477  if (conn->gtarg_nam)
478  gss_release_name(&min_s, &conn->gtarg_nam);
479  if (conn->gss_SendBuffer)
480  {
481  free(conn->gss_SendBuffer);
482  conn->gss_SendBuffer = NULL;
483  }
484  if (conn->gss_RecvBuffer)
485  {
486  free(conn->gss_RecvBuffer);
487  conn->gss_RecvBuffer = NULL;
488  }
489  if (conn->gss_ResultBuffer)
490  {
491  free(conn->gss_ResultBuffer);
492  conn->gss_ResultBuffer = NULL;
493  }
494  conn->gssenc = false;
495  }
496 #endif
497 #ifdef ENABLE_SSPI
498  if (conn->sspitarget)
499  {
500  free(conn->sspitarget);
501  conn->sspitarget = NULL;
502  }
503  if (conn->sspicred)
504  {
505  FreeCredentialsHandle(conn->sspicred);
506  free(conn->sspicred);
507  conn->sspicred = NULL;
508  }
509  if (conn->sspictx)
510  {
511  DeleteSecurityContext(conn->sspictx);
512  free(conn->sspictx);
513  conn->sspictx = NULL;
514  }
515  conn->usesspi = 0;
516 #endif
517  if (conn->sasl_state)
518  {
519  conn->sasl->free(conn->sasl_state);
520  conn->sasl_state = NULL;
521  }
522 }
int inEnd
Definition: libpq-int.h:483
int inStart
Definition: libpq-int.h:481
#define closesocket
Definition: port.h:333
int outCount
Definition: libpq-int.h:488
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:191
void(* free)(void *state)
Definition: fe-auth-sasl.h:127
const pg_fe_sasl_mech * sasl
Definition: libpq-int.h:504
void * sasl_state
Definition: libpq-int.h:505
pgsocket sock
Definition: libpq-int.h:444
#define PGINVALID_SOCKET
Definition: port.h:33
#define free(a)
Definition: header.h:65
int inCursor
Definition: libpq-int.h:482

◆ pqEndcopy3()

int pqEndcopy3 ( PGconn conn)

Definition at line 1861 of file fe-protocol3.c.

References appendPQExpBufferStr(), pg_conn::asyncStatus, pg_conn::cmd_queue_head, PQExpBufferData::data, pg_conn::errorMessage, PQExpBufferData::len, libpq_gettext, pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGQUERY_SIMPLE, PGRES_COMMAND_OK, PQclear(), pqFlush(), PQgetResult(), pqInternalNotice(), PQisBusy(), pqIsnonblocking, pqPutMsgEnd(), pqPutMsgStart(), PGcmdQueueEntry::queryclass, and pg_result::resultStatus.

Referenced by PQendcopy().

1862 {
1863  PGresult *result;
1864 
1865  if (conn->asyncStatus != PGASYNC_COPY_IN &&
1866  conn->asyncStatus != PGASYNC_COPY_OUT &&
1867  conn->asyncStatus != PGASYNC_COPY_BOTH)
1868  {
1870  libpq_gettext("no COPY in progress\n"));
1871  return 1;
1872  }
1873 
1874  /* Send the CopyDone message if needed */
1875  if (conn->asyncStatus == PGASYNC_COPY_IN ||
1876  conn->asyncStatus == PGASYNC_COPY_BOTH)
1877  {
1878  if (pqPutMsgStart('c', conn) < 0 ||
1879  pqPutMsgEnd(conn) < 0)
1880  return 1;
1881 
1882  /*
1883  * If we sent the COPY command in extended-query mode, we must issue a
1884  * Sync as well.
1885  */
1886  if (conn->cmd_queue_head &&
1888  {
1889  if (pqPutMsgStart('S', conn) < 0 ||
1890  pqPutMsgEnd(conn) < 0)
1891  return 1;
1892  }
1893  }
1894 
1895  /*
1896  * make sure no data is waiting to be sent, abort if we are non-blocking
1897  * and the flush fails
1898  */
1899  if (pqFlush(conn) && pqIsnonblocking(conn))
1900  return 1;
1901 
1902  /* Return to active duty */
1903  conn->asyncStatus = PGASYNC_BUSY;
1904 
1905  /*
1906  * Non blocking connections may have to abort at this point. If everyone
1907  * played the game there should be no problem, but in error scenarios the
1908  * expected messages may not have arrived yet. (We are assuming that the
1909  * backend's packetizing will ensure that CommandComplete arrives along
1910  * with the CopyDone; are there corner cases where that doesn't happen?)
1911  */
1912  if (pqIsnonblocking(conn) && PQisBusy(conn))
1913  return 1;
1914 
1915  /* Wait for the completion response */
1916  result = PQgetResult(conn);
1917 
1918  /* Expecting a successful result */
1919  if (result && result->resultStatus == PGRES_COMMAND_OK)
1920  {
1921  PQclear(result);
1922  return 0;
1923  }
1924 
1925  /*
1926  * Trouble. For backwards-compatibility reasons, we issue the error
1927  * message as if it were a notice (would be nice to get rid of this
1928  * silliness, but too many apps probably don't handle errors from
1929  * PQendcopy reasonably). Note that the app can still obtain the error
1930  * status from the PGconn object.
1931  */
1932  if (conn->errorMessage.len > 0)
1933  {
1934  /* We have to strip the trailing newline ... pain in neck... */
1935  char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1936 
1937  if (svLast == '\n')
1938  conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1939  pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1940  conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1941  }
1942 
1943  PQclear(result);
1944 
1945  return 1;
1946 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:965
#define pqIsnonblocking(conn)
Definition: libpq-int.h:830
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:434
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
PGQueryClass queryclass
Definition: libpq-int.h:322
PGNoticeHooks noticeHooks
Definition: libpq-int.h:402
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:839
PQExpBufferData errorMessage
Definition: libpq-int.h:571
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1951
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:461
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:520
ExecStatusType resultStatus
Definition: libpq-int.h:178
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1978
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqFlush()

int pqFlush ( PGconn conn)

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

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

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

966 {
967  if (conn->outCount > 0)
968  {
969  if (conn->Pfdebug)
970  fflush(conn->Pfdebug);
971 
972  return pqSendSome(conn, conn->outCount);
973  }
974 
975  return 0;
976 }
int outCount
Definition: libpq-int.h:488
FILE * Pfdebug
Definition: libpq-int.h:398
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:788

◆ pqFunctionCall3()

PGresult* pqFunctionCall3 ( PGconn conn,
Oid  fnid,
int *  result_buf,
int *  actual_result_len,
int  result_is_int,
const PQArgBlock args,
int  nargs 
)

Definition at line 1955 of file fe-protocol3.c.

References appendPQExpBuffer(), Assert, pg_conn::errorMessage, getNotify(), getParameterStatus(), getReadyForQuery(), handleSyncLoss(), i, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, PQArgBlock::integer, PQArgBlock::len, libpq_gettext, pg_conn::Pfdebug, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), PQmakeEmptyPGresult(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), pqTraceOutputMessage(), pqWait(), PQArgBlock::ptr, pg_conn::result, status(), and VALID_LONG_MESSAGE_TYPE.

Referenced by PQfn().

1959 {
1960  bool needInput = false;
1962  char id;
1963  int msgLength;
1964  int avail;
1965  int i;
1966 
1967  /* already validated by PQfn */
1969 
1970  /* PQfn already validated connection state */
1971 
1972  if (pqPutMsgStart('F', conn) < 0 || /* function call msg */
1973  pqPutInt(fnid, 4, conn) < 0 || /* function id */
1974  pqPutInt(1, 2, conn) < 0 || /* # of format codes */
1975  pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
1976  pqPutInt(nargs, 2, conn) < 0) /* # of args */
1977  {
1978  /* error message should be set up already */
1979  return NULL;
1980  }
1981 
1982  for (i = 0; i < nargs; ++i)
1983  { /* len.int4 + contents */
1984  if (pqPutInt(args[i].len, 4, conn))
1985  return NULL;
1986  if (args[i].len == -1)
1987  continue; /* it's NULL */
1988 
1989  if (args[i].isint)
1990  {
1991  if (pqPutInt(args[i].u.integer, args[i].len, conn))
1992  return NULL;
1993  }
1994  else
1995  {
1996  if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1997  return NULL;
1998  }
1999  }
2000 
2001  if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
2002  return NULL;
2003 
2004  if (pqPutMsgEnd(conn) < 0 ||
2005  pqFlush(conn))
2006  return NULL;
2007 
2008  for (;;)
2009  {
2010  if (needInput)
2011  {
2012  /* Wait for some data to arrive (or for the channel to close) */
2013  if (pqWait(true, false, conn) ||
2014  pqReadData(conn) < 0)
2015  break;
2016  }
2017 
2018  /*
2019  * Scan the message. If we run out of data, loop around to try again.
2020  */
2021  needInput = true;
2022 
2023  conn->inCursor = conn->inStart;
2024  if (pqGetc(&id, conn))
2025  continue;
2026  if (pqGetInt(&msgLength, 4, conn))
2027  continue;
2028 
2029  /*
2030  * Try to validate message type/length here. A length less than 4 is
2031  * definitely broken. Large lengths should only be believed for a few
2032  * message types.
2033  */
2034  if (msgLength < 4)
2035  {
2036  handleSyncLoss(conn, id, msgLength);
2037  break;
2038  }
2039  if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
2040  {
2041  handleSyncLoss(conn, id, msgLength);
2042  break;
2043  }
2044 
2045  /*
2046  * Can't process if message body isn't all here yet.
2047  */
2048  msgLength -= 4;
2049  avail = conn->inEnd - conn->inCursor;
2050  if (avail < msgLength)
2051  {
2052  /*
2053  * Before looping, enlarge the input buffer if needed to hold the
2054  * whole message. See notes in parseInput.
2055  */
2056  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2057  conn))
2058  {
2059  /*
2060  * XXX add some better recovery code... plan is to skip over
2061  * the message using its length, then report an error. For the
2062  * moment, just treat this like loss of sync (which indeed it
2063  * might be!)
2064  */
2065  handleSyncLoss(conn, id, msgLength);
2066  break;
2067  }
2068  continue;
2069  }
2070 
2071  /*
2072  * We should see V or E response to the command, but might get N
2073  * and/or A notices first. We also need to swallow the final Z before
2074  * returning.
2075  */
2076  switch (id)
2077  {
2078  case 'V': /* function result */
2079  if (pqGetInt(actual_result_len, 4, conn))
2080  continue;
2081  if (*actual_result_len != -1)
2082  {
2083  if (result_is_int)
2084  {
2085  if (pqGetInt(result_buf, *actual_result_len, conn))
2086  continue;
2087  }
2088  else
2089  {
2090  if (pqGetnchar((char *) result_buf,
2091  *actual_result_len,
2092  conn))
2093  continue;
2094  }
2095  }
2096  /* correctly finished function result message */
2097  status = PGRES_COMMAND_OK;
2098  break;
2099  case 'E': /* error return */
2100  if (pqGetErrorNotice3(conn, true))
2101  continue;
2102  status = PGRES_FATAL_ERROR;
2103  break;
2104  case 'A': /* notify message */
2105  /* handle notify and go back to processing return values */
2106  if (getNotify(conn))
2107  continue;
2108  break;
2109  case 'N': /* notice */
2110  /* handle notice and go back to processing return values */
2111  if (pqGetErrorNotice3(conn, false))
2112  continue;
2113  break;
2114  case 'Z': /* backend is ready for new query */
2115  if (getReadyForQuery(conn))
2116  continue;
2117  /* consume the message and exit */
2118  conn->inStart += 5 + msgLength;
2119  /* if we saved a result object (probably an error), use it */
2120  if (conn->result)
2121  return pqPrepareAsyncResult(conn);
2122  return PQmakeEmptyPGresult(conn, status);
2123  case 'S': /* parameter status */
2124  if (getParameterStatus(conn))
2125  continue;
2126  break;
2127  default:
2128  /* The backend violates the protocol. */
2130  libpq_gettext("protocol error: id=0x%x\n"),
2131  id);
2132  pqSaveErrorResult(conn);
2133  /* trust the specified message length as what to skip */
2134  conn->inStart += 5 + msgLength;
2135  return pqPrepareAsyncResult(conn);
2136  }
2137 
2138  /* trace server-to-client message */
2139  if (conn->Pfdebug)
2140  pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
2141 
2142  /* Completed this message, keep going */
2143  /* trust the specified message length as what to skip */
2144  conn->inStart += 5 + msgLength;
2145  needInput = false;
2146  }
2147 
2148  /*
2149  * We fall out of the loop only upon failing to read data.
2150  * conn->errorMessage has been set by pqWait or pqReadData. We want to
2151  * append it to any already-received error message.
2152  */
2153  pqSaveErrorResult(conn);
2154  return pqPrepareAsyncResult(conn);
2155 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:965
int inEnd
Definition: libpq-int.h:483
int inStart
Definition: libpq-int.h:481
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:354
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:417
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:219
ExecStatusType
Definition: libpq-fe.h:92
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:168
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:804
FILE * Pfdebug
Definition: libpq-int.h:398
PGresult * result
Definition: libpq-int.h:500
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:256
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:888
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
int pqReadData(PGconn *conn)
Definition: fe-misc.c:568
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:990
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:146
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:80
char * inBuffer
Definition: libpq-int.h:479
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:529
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:38
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define Assert(condition)
Definition: c.h:804
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:205
static int getReadyForQuery(PGconn *conn)
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:461
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:520
static int getParameterStatus(PGconn *conn)
static int getNotify(PGconn *conn)
int i
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:488
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:765
int inCursor
Definition: libpq-int.h:482
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
int * ptr
Definition: libpq-fe.h:250
#define libpq_gettext(x)
Definition: libpq-int.h:841
int integer
Definition: libpq-fe.h:251

◆ pqGetc()

int pqGetc ( char *  result,
PGconn conn 
)

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

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

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

81 {
82  if (conn->inCursor >= conn->inEnd)
83  return EOF;
84 
85  *result = conn->inBuffer[conn->inCursor++];
86 
87  return 0;
88 }
int inEnd
Definition: libpq-int.h:483
char * inBuffer
Definition: libpq-int.h:479
int inCursor
Definition: libpq-int.h:482

◆ pqGetCopyData3()

int pqGetCopyData3 ( PGconn conn,
char **  buffer,
int  async 
)

Definition at line 1694 of file fe-protocol3.c.

References appendPQExpBufferStr(), pg_conn::errorMessage, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, libpq_gettext, malloc, pqReadData(), and pqWait().

Referenced by PQgetCopyData().

1695 {
1696  int msgLength;
1697 
1698  for (;;)
1699  {
1700  /*
1701  * Collect the next input message. To make life simpler for async
1702  * callers, we keep returning 0 until the next message is fully
1703  * available, even if it is not Copy Data.
1704  */
1705  msgLength = getCopyDataMessage(conn);
1706  if (msgLength < 0)
1707  return msgLength; /* end-of-copy or error */
1708  if (msgLength == 0)
1709  {
1710  /* Don't block if async read requested */
1711  if (async)
1712  return 0;
1713  /* Need to load more data */
1714  if (pqWait(true, false, conn) ||
1715  pqReadData(conn) < 0)
1716  return -2;
1717  continue;
1718  }
1719 
1720  /*
1721  * Drop zero-length messages (shouldn't happen anyway). Otherwise
1722  * pass the data back to the caller.
1723  */
1724  msgLength -= 4;
1725  if (msgLength > 0)
1726  {
1727  *buffer = (char *) malloc(msgLength + 1);
1728  if (*buffer == NULL)
1729  {
1731  libpq_gettext("out of memory\n"));
1732  return -2;
1733  }
1734  memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1735  (*buffer)[msgLength] = '\0'; /* Add terminating null */
1736 
1737  /* Mark message consumed */
1738  conn->inStart = conn->inCursor + msgLength;
1739 
1740  return msgLength;
1741  }
1742 
1743  /* Empty, so drop it and loop around for another */
1744  conn->inStart = conn->inCursor;
1745  }
1746 }
int inStart
Definition: libpq-int.h:481
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define malloc(a)
Definition: header.h:50
int pqReadData(PGconn *conn)
Definition: fe-misc.c:568
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:990
char * inBuffer
Definition: libpq-int.h:479
static int getCopyDataMessage(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:571
int inCursor
Definition: libpq-int.h:482
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqGetErrorNotice3()

int pqGetErrorNotice3 ( PGconn conn,
bool  isError 
)

Definition at line 888 of file fe-protocol3.c.

References appendPQExpBufferStr(), pg_conn::cmd_queue_head, PQExpBufferData::data, pg_result::errMsg, pg_conn::errorMessage, pg_result::errQuery, initPQExpBuffer(), pg_conn::last_sqlstate, libpq_gettext, pg_result::noticeHooks, PGNoticeHooks::noticeRec, PGNoticeHooks::noticeRecArg, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_ABORTED, PQ_PIPELINE_OFF, pqBuildErrorMessage3(), PQclear(), pqClearAsyncResult(), PQExpBufferDataBroken, pqGetc(), pqGets(), PQmakeEmptyPGresult(), pqResultStrdup(), pqSaveMessageField(), pqSetResultError(), PGcmdQueueEntry::query, resetPQExpBuffer(), pg_conn::result, pg_result::resultStatus, pg_conn::show_context, strlcpy(), termPQExpBuffer(), and pg_conn::verbosity.

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

889 {
890  PGresult *res = NULL;
891  bool have_position = false;
892  PQExpBufferData workBuf;
893  char id;
894 
895  /* If in pipeline mode, set error indicator for it */
896  if (isError && conn->pipelineStatus != PQ_PIPELINE_OFF)
898 
899  /*
900  * If this is an error message, pre-emptively clear any incomplete query
901  * result we may have. We'd just throw it away below anyway, and
902  * releasing it before collecting the error might avoid out-of-memory.
903  */
904  if (isError)
905  pqClearAsyncResult(conn);
906 
907  /*
908  * Since the fields might be pretty long, we create a temporary
909  * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
910  * for stuff that is expected to be short. We shouldn't use
911  * conn->errorMessage either, since this might be only a notice.
912  */
913  initPQExpBuffer(&workBuf);
914 
915  /*
916  * Make a PGresult to hold the accumulated fields. We temporarily lie
917  * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
918  * copy conn->errorMessage.
919  *
920  * NB: This allocation can fail, if you run out of memory. The rest of the
921  * function handles that gracefully, and we still try to set the error
922  * message as the connection's error message.
923  */
925  if (res)
927 
928  /*
929  * Read the fields and save into res.
930  *
931  * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
932  * we saw a PG_DIAG_STATEMENT_POSITION field.
933  */
934  for (;;)
935  {
936  if (pqGetc(&id, conn))
937  goto fail;
938  if (id == '\0')
939  break; /* terminator found */
940  if (pqGets(&workBuf, conn))
941  goto fail;
942  pqSaveMessageField(res, id, workBuf.data);
943  if (id == PG_DIAG_SQLSTATE)
944  strlcpy(conn->last_sqlstate, workBuf.data,
945  sizeof(conn->last_sqlstate));
946  else if (id == PG_DIAG_STATEMENT_POSITION)
947  have_position = true;
948  }
949 
950  /*
951  * Save the active query text, if any, into res as well; but only if we
952  * might need it for an error cursor display, which is only true if there
953  * is a PG_DIAG_STATEMENT_POSITION field.
954  */
955  if (have_position && res && conn->cmd_queue_head && conn->cmd_queue_head->query)
956  res->errQuery = pqResultStrdup(res, conn->cmd_queue_head->query);
957 
958  /*
959  * Now build the "overall" error message for PQresultErrorMessage.
960  */
961  resetPQExpBuffer(&workBuf);
962  pqBuildErrorMessage3(&workBuf, res, conn->verbosity, conn->show_context);
963 
964  /*
965  * Either save error as current async result, or just emit the notice.
966  */
967  if (isError)
968  {
969  if (res)
970  pqSetResultError(res, &workBuf);
971  pqClearAsyncResult(conn); /* redundant, but be safe */
972  conn->result = res;
973  if (PQExpBufferDataBroken(workBuf))
975  libpq_gettext("out of memory\n"));
976  else
977  appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
978  }
979  else
980  {
981  /* if we couldn't allocate the result set, just discard the NOTICE */
982  if (res)
983  {
984  /*
985  * We can cheat a little here and not copy the message. But if we
986  * were unlucky enough to run out of memory while filling workBuf,
987  * insert "out of memory", as in pqSetResultError.
988  */
989  if (PQExpBufferDataBroken(workBuf))
990  res->errMsg = libpq_gettext("out of memory\n");
991  else
992  res->errMsg = workBuf.data;
993  if (res->noticeHooks.noticeRec != NULL)
995  PQclear(res);
996  }
997  }
998 
999  termPQExpBuffer(&workBuf);
1000  return 0;
1001 
1002 fail:
1003  PQclear(res);
1004  termPQExpBuffer(&workBuf);
1005  return EOF;
1006 }
PGContextVisibility show_context
Definition: libpq-int.h:475
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:139
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:434
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:417
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * errMsg
Definition: libpq-int.h:197
PGresult * result
Definition: libpq-int.h:500
PGNoticeHooks noticeHooks
Definition: libpq-int.h:187
PGVerbosity verbosity
Definition: libpq-int.h:474
PQnoticeReceiver noticeRec
Definition: libpq-int.h:153
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:146
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
void pqSetResultError(PGresult *res, PQExpBuffer errorMessage)
Definition: fe-exec.c:665
char * errQuery
Definition: libpq-int.h:199
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:80
void pqSaveMessageField(PGresult *res, char code, const char *value)
Definition: fe-exec.c:961
PQExpBufferData errorMessage
Definition: libpq-int.h:571
void PQclear(PGresult *res)
Definition: fe-exec.c:694
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:749
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
ExecStatusType resultStatus
Definition: libpq-int.h:178
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define libpq_gettext(x)
Definition: libpq-int.h:841
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:651
void * noticeRecArg
Definition: libpq-int.h:154
char last_sqlstate[6]
Definition: libpq-int.h:413

◆ pqGetHomeDirectory()

bool pqGetHomeDirectory ( char *  buf,
int  bufsize 
)

Definition at line 7242 of file fe-connect.c.

References pqGetpwuid(), snprintf, and strlcpy().

Referenced by connectOptions2(), initialize_SSL(), and parseServiceInfo().

7243 {
7244 #ifndef WIN32
7245  char pwdbuf[BUFSIZ];
7246  struct passwd pwdstr;
7247  struct passwd *pwd = NULL;
7248 
7249  (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
7250  if (pwd == NULL)
7251  return false;
7252  strlcpy(buf, pwd->pw_dir, bufsize);
7253  return true;
7254 #else
7255  char tmppath[MAX_PATH];
7256 
7257  ZeroMemory(tmppath, sizeof(tmppath));
7258  if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
7259  return false;
7260  snprintf(buf, bufsize, "%s/postgresql", tmppath);
7261  return true;
7262 #endif
7263 }
static char * buf
Definition: pg_test_fsync.c:68
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
Definition: thread.c:65
#define snprintf
Definition: port.h:217

◆ pqGetInt()

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

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

References 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(), and pqParseInput3().

220 {
221  uint16 tmp2;
222  uint32 tmp4;
223 
224  switch (bytes)
225  {
226  case 2:
227  if (conn->inCursor + 2 > conn->inEnd)
228  return EOF;
229  memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
230  conn->inCursor += 2;
231  *result = (int) pg_ntoh16(tmp2);
232  break;
233  case 4:
234  if (conn->inCursor + 4 > conn->inEnd)
235  return EOF;
236  memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
237  conn->inCursor += 4;
238  *result = (int) pg_ntoh32(tmp4);
239  break;
240  default:
242  "integer of size %lu not supported by pqGetInt",
243  (unsigned long) bytes);
244  return EOF;
245  }
246 
247  return 0;
248 }
int inEnd
Definition: libpq-int.h:483
def bytes(source, encoding='ascii', errors='strict')
#define pg_ntoh16(x)
Definition: pg_bswap.h:124
unsigned short uint16
Definition: c.h:440
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
PGNoticeHooks noticeHooks
Definition: libpq-int.h:402
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:839
unsigned int uint32
Definition: c.h:441
char * inBuffer
Definition: libpq-int.h:479
int inCursor
Definition: libpq-int.h:482

◆ pqGetline3()

int pqGetline3 ( PGconn conn,
char *  s,
int  maxlen 
)

Definition at line 1754 of file fe-protocol3.c.

References appendPQExpBufferStr(), pg_conn::asyncStatus, pg_conn::copy_is_binary, pg_conn::errorMessage, libpq_gettext, PGASYNC_COPY_BOTH, PGASYNC_COPY_OUT, PGINVALID_SOCKET, PQgetlineAsync(), pqReadData(), pqWait(), pg_conn::sock, and status().

Referenced by PQgetline().

1755 {
1756  int status;
1757 
1758  if (conn->sock == PGINVALID_SOCKET ||
1759  (conn->asyncStatus != PGASYNC_COPY_OUT &&
1760  conn->asyncStatus != PGASYNC_COPY_BOTH) ||
1761  conn->copy_is_binary)
1762  {
1764  libpq_gettext("PQgetline: not doing text COPY OUT\n"));
1765  *s = '\0';
1766  return EOF;
1767  }
1768 
1769  while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1770  {
1771  /* need to load more data */
1772  if (pqWait(true, false, conn) ||
1773  pqReadData(conn) < 0)
1774  {
1775  *s = '\0';
1776  return EOF;
1777  }
1778  }
1779 
1780  if (status < 0)
1781  {
1782  /* End of copy detected; gin up old-style terminator */
1783  strcpy(s, "\\.");
1784  return 0;
1785  }
1786 
1787  /* Add null terminator, and strip trailing \n if present */
1788  if (s[status - 1] == '\n')
1789  {
1790  s[status - 1] = '\0';
1791  return 0;
1792  }
1793  else
1794  {
1795  s[status] = '\0';
1796  return 1;
1797  }
1798 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2754
char copy_is_binary
Definition: libpq-int.h:419
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
int pqReadData(PGconn *conn)
Definition: fe-misc.c:568
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:990
pgsocket sock
Definition: libpq-int.h:444
#define PGINVALID_SOCKET
Definition: port.h:33
PQExpBufferData errorMessage
Definition: libpq-int.h:571
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqGetlineAsync3()

int pqGetlineAsync3 ( PGconn conn,
char *  buffer,
int  bufsize 
)

Definition at line 1806 of file fe-protocol3.c.

References pg_conn::asyncStatus, pg_conn::copy_already_done, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, PGASYNC_COPY_BOTH, and PGASYNC_COPY_OUT.

Referenced by PQgetlineAsync().

1807 {
1808  int msgLength;
1809  int avail;
1810 
1811  if (conn->asyncStatus != PGASYNC_COPY_OUT
1812  && conn->asyncStatus != PGASYNC_COPY_BOTH)
1813  return -1; /* we are not doing a copy... */
1814 
1815  /*
1816  * Recognize the next input message. To make life simpler for async
1817  * callers, we keep returning 0 until the next message is fully available
1818  * even if it is not Copy Data. This should keep PQendcopy from blocking.
1819  * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1820  */
1821  msgLength = getCopyDataMessage(conn);
1822  if (msgLength < 0)
1823  return -1; /* end-of-copy or error */
1824  if (msgLength == 0)
1825  return 0; /* no data yet */
1826 
1827  /*
1828  * Move data from libpq's buffer to the caller's. In the case where a
1829  * prior call found the caller's buffer too small, we use
1830  * conn->copy_already_done to remember how much of the row was already
1831  * returned to the caller.
1832  */
1833  conn->inCursor += conn->copy_already_done;
1834  avail = msgLength - 4 - conn->copy_already_done;
1835  if (avail <= bufsize)
1836  {
1837  /* Able to consume the whole message */
1838  memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1839  /* Mark message consumed */
1840  conn->inStart = conn->inCursor + avail;
1841  /* Reset state for next time */
1842  conn->copy_already_done = 0;
1843  return avail;
1844  }
1845  else
1846  {
1847  /* We must return a partial message */
1848  memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1849  /* The message is NOT consumed from libpq's buffer */
1850  conn->copy_already_done += bufsize;
1851  return bufsize;
1852  }
1853 }
int inStart
Definition: libpq-int.h:481
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
char * inBuffer
Definition: libpq-int.h:479
static int getCopyDataMessage(PGconn *conn)
int copy_already_done
Definition: libpq-int.h:420
int inCursor
Definition: libpq-int.h:482

◆ pqGetnchar()

int pqGetnchar ( char *  s,
size_t  len,
PGconn conn 
)

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

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

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

169 {
170  if (len > (size_t) (conn->inEnd - conn->inCursor))
171  return EOF;
172 
173  memcpy(s, conn->inBuffer + conn->inCursor, len);
174  /* no terminating null */
175 
176  conn->inCursor += len;
177 
178  return 0;
179 }
int inEnd
Definition: libpq-int.h:483
char * inBuffer
Definition: libpq-int.h:479
int inCursor
Definition: libpq-int.h:482

◆ pqGets()

int pqGets ( PQExpBuffer  buf,
PGconn conn 
)

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

References pqGets_internal().

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

140 {
141  return pqGets_internal(buf, conn, true);
142 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:112

◆ pqGets_append()

int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

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

References pqGets_internal().

Referenced by PQconnectPoll().

146 {
147  return pqGets_internal(buf, conn, false);
148 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:112

◆ pqInternalNotice()

void pqInternalNotice ( const PGNoticeHooks hooks,
const char *  fmt,
  ... 
)

◆ pqPacketSend()

int pqPacketSend ( PGconn conn,
char  pack_type,
const void *  buf,
size_t  buf_len 
)

Definition at line 4573 of file fe-connect.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), DefaultHost, free, hostname, i, _internalPQconninfoOption::keyword, _PQconninfoOption::keyword, libpq_gettext, malloc, pg_strcasecmp(), pg_strncasecmp(), port, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), STATUS_ERROR, STATUS_OK, _internalPQconninfoOption::val, _PQconninfoOption::val, and values.

Referenced by pg_password_sendauth(), pg_SASL_continue(), and PQconnectPoll().

4575 {
4576  /* Start the message. */
4577  if (pqPutMsgStart(pack_type, conn))
4578  return STATUS_ERROR;
4579 
4580  /* Send the message body. */
4581  if (pqPutnchar(buf, buf_len, conn))
4582  return STATUS_ERROR;
4583 
4584  /* Finish the message. */
4585  if (pqPutMsgEnd(conn))
4586  return STATUS_ERROR;
4587 
4588  /* Flush to ensure backend gets it. */
4589  if (pqFlush(conn))
4590  return STATUS_ERROR;
4591 
4592  return STATUS_OK;
4593 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:965
#define STATUS_ERROR
Definition: c.h:1171
static char * buf
Definition: pg_test_fsync.c:68
#define STATUS_OK
Definition: c.h:1170
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:205
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:461
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:520

◆ pqParseInput3()

void pqParseInput3 ( PGconn conn)

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

References appendPQExpBuffer(), appendPQExpBufferStr(), pg_conn::asyncStatus, pg_conn::be_key, pg_conn::be_pid, pg_conn::cmd_queue_head, pg_result::cmdStatus, CMDSTATUS_LEN, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::errorMessage, getAnotherTuple(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), handleSyncLoss(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_gettext, pg_conn::noticeHooks, pg_conn::Pfdebug, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, PGQUERY_DESCRIBE, PGQUERY_PREPARE, PGQUERY_SIMPLE, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_PIPELINE_SYNC, PGRES_TUPLES_OK, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQ_PIPELINE_ON, pqCheckInBufferSpace(), pqCommandQueueAdvance(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGets(), pqInternalNotice(), PQmakeEmptyPGresult(), pqSaveErrorResult(), pqTraceOutputMessage(), PGcmdQueueEntry::queryclass, pg_conn::result, pg_result::resultStatus, strlcpy(), VALID_LONG_MESSAGE_TYPE, and pg_conn::workBuffer.

Referenced by parseInput().

64 {
65  char id;
66  int msgLength;
67  int avail;
68 
69  /*
70  * Loop to parse successive complete messages available in the buffer.
71  */
72  for (;;)
73  {
74  /*
75  * Try to read a message. First get the type code and length. Return
76  * if not enough data.
77  */
78  conn->inCursor = conn->inStart;
79  if (pqGetc(&id, conn))
80  return;
81  if (pqGetInt(&msgLength, 4, conn))
82  return;
83 
84  /*
85  * Try to validate message type/length here. A length less than 4 is
86  * definitely broken. Large lengths should only be believed for a few
87  * message types.
88  */
89  if (msgLength < 4)
90  {
91  handleSyncLoss(conn, id, msgLength);
92  return;
93  }
94  if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
95  {
96  handleSyncLoss(conn, id, msgLength);
97  return;
98  }
99 
100  /*
101  * Can't process if message body isn't all here yet.
102  */
103  msgLength -= 4;
104  avail = conn->inEnd - conn->inCursor;
105  if (avail < msgLength)
106  {
107  /*
108  * Before returning, enlarge the input buffer if needed to hold
109  * the whole message. This is better than leaving it to
110  * pqReadData because we can avoid multiple cycles of realloc()
111  * when the message is large; also, we can implement a reasonable
112  * recovery strategy if we are unable to make the buffer big
113  * enough.
114  */
115  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
116  conn))
117  {
118  /*
119  * XXX add some better recovery code... plan is to skip over
120  * the message using its length, then report an error. For the
121  * moment, just treat this like loss of sync (which indeed it
122  * might be!)
123  */
124  handleSyncLoss(conn, id, msgLength);
125  }
126  return;
127  }
128 
129  /*
130  * NOTIFY and NOTICE messages can happen in any state; always process
131  * them right away.
132  *
133  * Most other messages should only be processed while in BUSY state.
134  * (In particular, in READY state we hold off further parsing until
135  * the application collects the current PGresult.)
136  *
137  * However, if the state is IDLE then we got trouble; we need to deal
138  * with the unexpected message somehow.
139  *
140  * ParameterStatus ('S') messages are a special case: in IDLE state we
141  * must process 'em (this case could happen if a new value was adopted
142  * from config file due to SIGHUP), but otherwise we hold off until
143  * BUSY state.
144  */
145  if (id == 'A')
146  {
147  if (getNotify(conn))
148  return;
149  }
150  else if (id == 'N')
151  {
152  if (pqGetErrorNotice3(conn, false))
153  return;
154  }
155  else if (conn->asyncStatus != PGASYNC_BUSY)
156  {
157  /* If not IDLE state, just wait ... */
158  if (conn->asyncStatus != PGASYNC_IDLE)
159  return;
160 
161  /*
162  * We're also notionally not-IDLE when in pipeline mode the state
163  * says "idle" (so we have completed receiving the results of one
164  * query from the server and dispatched them to the application)
165  * but another query is queued; yield back control to caller so
166  * that they can initiate processing of the next query in the
167  * queue.
168  */
169  if (conn->pipelineStatus != PQ_PIPELINE_OFF &&
170  conn->cmd_queue_head != NULL)
171  return;
172 
173  /*
174  * Unexpected message in IDLE state; need to recover somehow.
175  * ERROR messages are handled using the notice processor;
176  * ParameterStatus is handled normally; anything else is just
177  * dropped on the floor after displaying a suitable warning
178  * notice. (An ERROR is very possibly the backend telling us why
179  * it is about to close the connection, so we don't want to just
180  * discard it...)
181  */
182  if (id == 'E')
183  {
184  if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
185  return;
186  }
187  else if (id == 'S')
188  {
189  if (getParameterStatus(conn))
190  return;
191  }
192  else
193  {
194  /* Any other case is unexpected and we summarily skip it */
196  "message type 0x%02x arrived from server while idle",
197  id);
198  /* Discard the unexpected message */
199  conn->inCursor += msgLength;
200  }
201  }
202  else
203  {
204  /*
205  * In BUSY state, we can process everything.
206  */
207  switch (id)
208  {
209  case 'C': /* command complete */
210  if (pqGets(&conn->workBuffer, conn))
211  return;
212  if (conn->result == NULL)
213  {
214  conn->result = PQmakeEmptyPGresult(conn,
216  if (!conn->result)
217  {
219  libpq_gettext("out of memory"));
220  pqSaveErrorResult(conn);
221  }
222  }
223  if (conn->result)
224  strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
225  CMDSTATUS_LEN);
226  conn->asyncStatus = PGASYNC_READY;
227  break;
228  case 'E': /* error return */
229  if (pqGetErrorNotice3(conn, true))
230  return;
231  conn->asyncStatus = PGASYNC_READY;
232  break;
233  case 'Z': /* sync response, backend is ready for new
234  * query */
235  if (getReadyForQuery(conn))
236  return;
237  if (conn->pipelineStatus != PQ_PIPELINE_OFF)
238  {
239  conn->result = PQmakeEmptyPGresult(conn,
241  if (!conn->result)
242  {
244  libpq_gettext("out of memory"));
245  pqSaveErrorResult(conn);
246  }
247  else
248  {
250  conn->asyncStatus = PGASYNC_READY;
251  }
252  }
253  else
254  {
255  /*
256  * In simple query protocol, advance the command queue
257  * (see PQgetResult).
258  */
259  if (conn->cmd_queue_head &&
261  pqCommandQueueAdvance(conn);
262  conn->asyncStatus = PGASYNC_IDLE;
263  }
264  break;
265  case 'I': /* empty query */
266  if (conn->result == NULL)
267  {
268  conn->result = PQmakeEmptyPGresult(conn,
270  if (!conn->result)
271  {
273  libpq_gettext("out of memory"));
274  pqSaveErrorResult(conn);
275  }
276  }
277  conn->asyncStatus = PGASYNC_READY;
278  break;
279  case '1': /* Parse Complete */
280  /* If we're doing PQprepare, we're done; else ignore */
281  if (conn->cmd_queue_head &&
283  {
284  if (conn->result == NULL)
285  {
286  conn->result = PQmakeEmptyPGresult(conn,
288  if (!conn->result)
289  {
291  libpq_gettext("out of memory"));
292  pqSaveErrorResult(conn);
293  }
294  }
295  conn->asyncStatus = PGASYNC_READY;
296  }
297  break;
298  case '2': /* Bind Complete */
299  case '3': /* Close Complete */
300  /* Nothing to do for these message types */
301  break;
302  case 'S': /* parameter status */
303  if (getParameterStatus(conn))
304  return;
305  break;
306  case 'K': /* secret key data from the backend */
307 
308  /*
309  * This is expected only during backend startup, but it's
310  * just as easy to handle it as part of the main loop.
311  * Save the data and continue processing.
312  */
313  if (pqGetInt(&(conn->be_pid), 4, conn))
314  return;
315  if (pqGetInt(&(conn->be_key), 4, conn))
316  return;
317  break;
318  case 'T': /* Row Description */
319  if (conn->result != NULL &&
321  {
322  /*
323  * We've already choked for some reason. Just discard
324  * the data till we get to the end of the query.
325  */
326  conn->inCursor += msgLength;
327  }
328  else if (conn->result == NULL ||
329  (conn->cmd_queue_head &&
331  {
332  /* First 'T' in a query sequence */
333  if (getRowDescriptions(conn, msgLength))
334  return;
335  }
336  else
337  {
338  /*
339  * A new 'T' message is treated as the start of
340  * another PGresult. (It is not clear that this is
341  * really possible with the current backend.) We stop
342  * parsing until the application accepts the current
343  * result.
344  */
345  conn->asyncStatus = PGASYNC_READY;
346  return;
347  }
348  break;
349  case 'n': /* No Data */
350 
351  /*
352  * NoData indicates that we will not be seeing a
353  * RowDescription message because the statement or portal
354  * inquired about doesn't return rows.
355  *
356  * If we're doing a Describe, we have to pass something
357  * back to the client, so set up a COMMAND_OK result,
358  * instead of PGRES_TUPLES_OK. Otherwise we can just
359  * ignore this message.
360  */
361  if (conn->cmd_queue_head &&
363  {
364  if (conn->result == NULL)
365  {
366  conn->result = PQmakeEmptyPGresult(conn,
368  if (!conn->result)
369  {
371  libpq_gettext("out of memory"));
372  pqSaveErrorResult(conn);
373  }
374  }
375  conn->asyncStatus = PGASYNC_READY;
376  }
377  break;
378  case 't': /* Parameter Description */
379  if (getParamDescriptions(conn, msgLength))
380  return;
381  break;
382  case 'D': /* Data Row */
383  if (conn->result != NULL &&
385  {
386  /* Read another tuple of a normal query response */
387  if (getAnotherTuple(conn, msgLength))
388  return;
389  }
390  else if (conn->result != NULL &&
392  {
393  /*
394  * We've already choked for some reason. Just discard
395  * tuples till we get to the end of the query.
396  */
397  conn->inCursor += msgLength;
398  }
399  else
400  {
401  /* Set up to report error at end of query */
403  libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
404  pqSaveErrorResult(conn);
405  /* Discard the unexpected message */
406  conn->inCursor += msgLength;
407  }
408  break;
409  case 'G': /* Start Copy In */
410  if (getCopyStart(conn, PGRES_COPY_IN))
411  return;
413  break;
414  case 'H': /* Start Copy Out */
415  if (getCopyStart(conn, PGRES_COPY_OUT))
416  return;
418  conn->copy_already_done = 0;
419  break;
420  case 'W': /* Start Copy Both */
421  if (getCopyStart(conn, PGRES_COPY_BOTH))
422  return;
424  conn->copy_already_done = 0;
425  break;
426  case 'd': /* Copy Data */
427 
428  /*
429  * If we see Copy Data, just silently drop it. This would
430  * only occur if application exits COPY OUT mode too
431  * early.
432  */
433  conn->inCursor += msgLength;
434  break;
435  case 'c': /* Copy Done */
436 
437  /*
438  * If we see Copy Done, just silently drop it. This is
439  * the normal case during PQendcopy. We will keep
440  * swallowing data, expecting to see command-complete for
441  * the COPY command.
442  */
443  break;
444  default:
446  libpq_gettext("unexpected response from server; first received character was \"%c\"\n"),
447  id);
448  /* build an error result holding the error message */
449  pqSaveErrorResult(conn);
450  /* not sure if we will see more, so go to ready state */
451  conn->asyncStatus = PGASYNC_READY;
452  /* Discard the unexpected message */
453  conn->inCursor += msgLength;
454  break;
455  } /* switch on protocol character */
456  }
457  /* Successfully consumed this message */
458  if (conn->inCursor == conn->inStart + 5 + msgLength)
459  {
460  /* trace server-to-client message */
461  if (conn->Pfdebug)
462  pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
463 
464  /* Normal case: parsing agrees with specified length */
465  conn->inStart = conn->inCursor;
466  }
467  else
468  {
469  /* Trouble --- report it */
471  libpq_gettext("message contents do not agree with length in message type \"%c\"\n"),
472  id);
473  /* build an error result holding the error message */
474  pqSaveErrorResult(conn);
475  conn->asyncStatus = PGASYNC_READY;
476  /* trust the specified message length as what to skip */
477  conn->inStart += 5 + msgLength;
478  }
479  }
480 }
int inEnd
Definition: libpq-int.h:483
int inStart
Definition: libpq-int.h:481
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:139
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
PQExpBufferData workBuffer
Definition: libpq-int.h:574
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:354
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:434
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:417
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:219
static int getParamDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:680
#define CMDSTATUS_LEN
Definition: libpq-int.h:87
FILE * Pfdebug
Definition: libpq-int.h:398
PGresult * result
Definition: libpq-int.h:500
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
PGQueryClass queryclass
Definition: libpq-int.h:322
static int getRowDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:509
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:888
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
PGNoticeHooks noticeHooks
Definition: libpq-int.h:402
static int getAnotherTuple(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:768
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:839
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:146
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:80
void pqCommandQueueAdvance(PGconn *conn)
Definition: fe-exec.c:2976
char * inBuffer
Definition: libpq-int.h:479
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:529
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:38
PQExpBufferData errorMessage
Definition: libpq-int.h:571
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static int getReadyForQuery(PGconn *conn)
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:179
int be_key
Definition: libpq-int.h:468
int copy_already_done
Definition: libpq-int.h:420
static int getParameterStatus(PGconn *conn)
static int getNotify(PGconn *conn)
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:488
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:765
int inCursor
Definition: libpq-int.h:482
int be_pid
Definition: libpq-int.h:467
ExecStatusType resultStatus
Definition: libpq-int.h:178
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqPrepareAsyncResult()

PGresult* pqPrepareAsyncResult ( PGconn conn)

Definition at line 804 of file fe-exec.c.

References pg_conn::next_result, PGRES_FATAL_ERROR, PQmakeEmptyPGresult(), and pg_conn::result.

Referenced by getCopyResult(), pqFunctionCall3(), and PQgetResult().

805 {
806  PGresult *res;
807 
808  /*
809  * conn->result is the PGresult to return. If it is NULL (which probably
810  * shouldn't happen) we assume there is an appropriate error message in
811  * conn->errorMessage.
812  */
813  res = conn->result;
814  if (!res)
816 
817  /*
818  * Replace conn->result with next_result, if any. In the normal case
819  * there isn't a next result and we're just dropping ownership of the
820  * current result. In single-row mode this restores the situation to what
821  * it was before we created the current single-row result.
822  */
823  conn->result = conn->next_result;
824  conn->next_result = NULL;
825 
826  return res;
827 }
PGresult * result
Definition: libpq-int.h:500
PGresult * next_result
Definition: libpq-int.h:501
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:146

◆ pqPutc()

int pqPutc ( char  c,
PGconn conn 
)

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

References pqPutMsgBytes().

Referenced by PQsendDescribe(), PQsendQueryGuts(), and PQsendQueryInternal().

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

◆ pqPutInt()

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

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

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

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

257 {
258  uint16 tmp2;
259  uint32 tmp4;
260 
261  switch (bytes)
262  {
263  case 2:
264  tmp2 = pg_hton16((uint16) value);
265  if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
266  return EOF;
267  break;
268  case 4:
269  tmp4 = pg_hton32((uint32) value);
270  if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
271  return EOF;
272  break;
273  default:
275  "integer of size %lu not supported by pqPutInt",
276  (unsigned long) bytes);
277  return EOF;
278  }
279 
280  return 0;
281 }
def bytes(source, encoding='ascii', errors='strict')
#define pg_hton16(x)
Definition: pg_bswap.h:120
unsigned short uint16
Definition: c.h:440
#define pg_hton32(x)
Definition: pg_bswap.h:121
PGNoticeHooks noticeHooks
Definition: libpq-int.h:402
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:497
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:839
unsigned int uint32
Definition: c.h:441
static struct @143 value

◆ pqPutMsgEnd()

int pqPutMsgEnd ( PGconn conn)

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

References 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(), PQpipelineSync(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), and sendTerminateConn().

521 {
522  /* Fill in length word if needed */
523  if (conn->outMsgStart >= 0)
524  {
525  uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
526 
527  msgLen = pg_hton32(msgLen);
528  memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
529  }
530 
531  /* trace client-to-server message */
532  if (conn->Pfdebug)
533  {
534  if (conn->outCount < conn->outMsgStart)
535  pqTraceOutputMessage(conn, conn->outBuffer + conn->outCount, true);
536  else
538  conn->outBuffer + conn->outMsgStart);
539  }
540 
541  /* Make message eligible to send */
542  conn->outCount = conn->outMsgEnd;
543 
544  if (conn->outCount >= 8192)
545  {
546  int toSend = conn->outCount - (conn->outCount % 8192);
547 
548  if (pqSendSome(conn, toSend) < 0)
549  return EOF;
550  /* in nonblock mode, don't complain if unable to send it all */
551  }
552 
553  return 0;
554 }
int outCount
Definition: libpq-int.h:488
int outMsgEnd
Definition: libpq-int.h:493
FILE * Pfdebug
Definition: libpq-int.h:398
#define pg_hton32(x)
Definition: pg_bswap.h:121
unsigned int uint32
Definition: c.h:441
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:529
int outMsgStart
Definition: libpq-int.h:491
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition: fe-trace.c:694
char * outBuffer
Definition: libpq-int.h:486
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:788

◆ pqPutMsgStart()

int pqPutMsgStart ( char  msg_type,
PGconn conn 
)

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

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

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), PQpipelineSync(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), and sendTerminateConn().

462 {
463  int lenPos;
464  int endPos;
465 
466  /* allow room for message type byte */
467  if (msg_type)
468  endPos = conn->outCount + 1;
469  else
470  endPos = conn->outCount;
471 
472  /* do we want a length word? */
473  lenPos = endPos;
474  /* allow room for message length */
475  endPos += 4;
476 
477  /* make sure there is room for message header */
478  if (pqCheckOutBufferSpace(endPos, conn))
479  return EOF;
480  /* okay, save the message type byte if any */
481  if (msg_type)
482  conn->outBuffer[conn->outCount] = msg_type;
483  /* set up the message pointers */
484  conn->outMsgStart = lenPos;
485  conn->outMsgEnd = endPos;
486  /* length word, if needed, will be filled in by pqPutMsgEnd */
487 
488  return 0;
489 }
int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:290
int outCount
Definition: libpq-int.h:488
int outMsgEnd
Definition: libpq-int.h:493
int outMsgStart
Definition: libpq-int.h:491
char * outBuffer
Definition: libpq-int.h:486

◆ pqPutnchar()

int pqPutnchar ( const char *  s,
size_t  len,
PGconn conn 
)

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

References pqPutMsgBytes().

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

206 {
207  if (pqPutMsgBytes(s, len, conn))
208  return EOF;
209 
210  return 0;
211 }
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:497

◆ pqPuts()

int pqPuts ( const char *  s,
PGconn conn 
)

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

References pqPutMsgBytes().

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

156 {
157  if (pqPutMsgBytes(s, strlen(s) + 1, conn))
158  return EOF;
159 
160  return 0;
161 }
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:497

◆ pqReadData()

int pqReadData ( PGconn conn)

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

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

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

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

◆ pqReadReady()

int pqReadReady ( PGconn conn)

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

References pqSocketCheck().

Referenced by gss_read(), and pqReadData().

1028 {
1029  return pqSocketCheck(conn, 1, 0, (time_t) 0);
1030 }
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
Definition: fe-misc.c:1051

◆ pqResultAlloc()

void* pqResultAlloc ( PGresult res,
size_t  nBytes,
bool  isBinary 
)

Definition at line 539 of file fe-exec.c.

References pg_result::curBlock, pg_result::curOffset, malloc, pg_result::memorySize, pgresult_data::next, pg_result::null_field, PGRESULT_ALIGN_BOUNDARY, PGRESULT_BLOCK_OVERHEAD, PGRESULT_DATA_BLOCKSIZE, PGRESULT_SEP_ALLOC_THRESHOLD, pgresult_data::space, and pg_result::spaceLeft.

Referenced by getCopyStart(), getParamDescriptions(), getRowDescriptions(), pqInternalNotice(), PQresultAlloc(), pqResultStrdup(), pqRowProcessor(), pqSaveMessageField(), and PQsetvalue().

540 {
541  char *space;
542  PGresult_data *block;
543 
544  if (!res)
545  return NULL;
546 
547  if (nBytes <= 0)
548  return res->null_field;
549 
550  /*
551  * If alignment is needed, round up the current position to an alignment
552  * boundary.
553  */
554  if (isBinary)
555  {
556  int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
557 
558  if (offset)
559  {
560  res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
561  res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
562  }
563  }
564 
565  /* If there's enough space in the current block, no problem. */
566  if (nBytes <= (size_t) res->spaceLeft)
567  {
568  space = res->curBlock->space + res->curOffset;
569  res->curOffset += nBytes;
570  res->spaceLeft -= nBytes;
571  return space;
572  }
573 
574  /*
575  * If the requested object is very large, give it its own block; this
576  * avoids wasting what might be most of the current block to start a new
577  * block. (We'd have to special-case requests bigger than the block size
578  * anyway.) The object is always given binary alignment in this case.
579  */
580  if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
581  {
582  size_t alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD;
583 
584  block = (PGresult_data *) malloc(alloc_size);
585  if (!block)
586  return NULL;
587  res->memorySize += alloc_size;
588  space = block->space + PGRESULT_BLOCK_OVERHEAD;
589  if (res->curBlock)
590  {
591  /*
592  * Tuck special block below the active block, so that we don't
593  * have to waste the free space in the active block.
594  */
595  block->next = res->curBlock->next;
596  res->curBlock->next = block;
597  }
598  else
599  {
600  /* Must set up the new block as the first active block. */
601  block->next = NULL;
602  res->curBlock = block;
603  res->spaceLeft = 0; /* be sure it's marked full */
604  }
605  return space;
606  }
607 
608  /* Otherwise, start a new block. */
610  if (!block)
611  return NULL;
613  block->next = res->curBlock;
614  res->curBlock = block;
615  if (isBinary)
616  {
617  /* object needs full alignment */
620  }
621  else
622  {
623  /* we can cram it right after the overhead pointer */
624  res->curOffset = sizeof(PGresult_data);
626  }
627 
628  space = block->space + res->curOffset;
629  res->curOffset += nBytes;
630  res->spaceLeft -= nBytes;
631  return space;
632 }
size_t memorySize
Definition: libpq-int.h:213
char space[1]
Definition: libpq-int.h:107
PGresult_data * next
Definition: libpq-int.h:106
union pgresult_data PGresult_data
Definition: libpq-int.h:102
int spaceLeft
Definition: libpq-int.h:211
char null_field[1]
Definition: libpq-int.h:202
#define malloc(a)
Definition: header.h:50
#define PGRESULT_ALIGN_BOUNDARY
Definition: fe-exec.c:134
int curOffset
Definition: libpq-int.h:210
#define PGRESULT_BLOCK_OVERHEAD
Definition: fe-exec.c:135
PGresult_data * curBlock
Definition: libpq-int.h:209
#define PGRESULT_SEP_ALLOC_THRESHOLD
Definition: fe-exec.c:136
#define PGRESULT_DATA_BLOCKSIZE
Definition: fe-exec.c:133

◆ pqResultStrdup()

char* pqResultStrdup ( PGresult res,
const char *  str 
)

Definition at line 651 of file fe-exec.c.

References pqResultAlloc().

Referenced by getRowDescriptions(), pqGetErrorNotice3(), PQsetResultAttrs(), and pqSetResultError().

652 {
653  char *space = (char *) pqResultAlloc(res, strlen(str) + 1, false);
654 
655  if (space)
656  strcpy(space, str);
657  return space;
658 }
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:539

◆ pqRowProcessor()

int pqRowProcessor ( PGconn conn,
const char **  errmsgp 
)

Definition at line 1107 of file fe-exec.c.

References pg_conn::asyncStatus, pg_result::attDescs, pgresAttDesc::format, i, pgresAttValue::len, pgDataValue::len, pg_conn::next_result, pg_result::null_field, NULL_LEN, pg_result::numAttributes, PG_COPYRES_ATTRS, PG_COPYRES_EVENTS, PG_COPYRES_NOTICEHOOKS, PGASYNC_READY_MORE, PGRES_SINGLE_TUPLE, pqAddTuple(), PQclear(), PQcopyResult(), pqResultAlloc(), pg_conn::result, pg_result::resultStatus, pg_conn::rowBuf, pg_conn::singleRowMode, val, pgresAttValue::value, and value.

Referenced by getAnotherTuple().

1108 {
1109  PGresult *res = conn->result;
1110  int nfields = res->numAttributes;
1111  const PGdataValue *columns = conn->rowBuf;
1112  PGresAttValue *tup;
1113  int i;
1114 
1115  /*
1116  * In single-row mode, make a new PGresult that will hold just this one
1117  * row; the original conn->result is left unchanged so that it can be used
1118  * again as the template for future rows.
1119  */
1120  if (conn->singleRowMode)
1121  {
1122  /* Copy everything that should be in the result at this point */
1123  res = PQcopyResult(res,
1126  if (!res)
1127  return 0;
1128  }
1129 
1130  /*
1131  * Basically we just allocate space in the PGresult for each field and
1132  * copy the data over.
1133  *
1134  * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1135  * caller will take to mean "out of memory". This is preferable to trying
1136  * to set up such a message here, because evidently there's not enough
1137  * memory for gettext() to do anything.
1138  */
1139  tup = (PGresAttValue *)
1140  pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
1141  if (tup == NULL)
1142  goto fail;
1143 
1144  for (i = 0; i < nfields; i++)
1145  {
1146  int clen = columns[i].len;
1147 
1148  if (clen < 0)
1149  {
1150  /* null field */
1151  tup[i].len = NULL_LEN;
1152  tup[i].value = res->null_field;
1153  }
1154  else
1155  {
1156  bool isbinary = (res->attDescs[i].format != 0);
1157  char *val;
1158 
1159  val = (char *) pqResultAlloc(res, clen + 1, isbinary);
1160  if (val == NULL)
1161  goto fail;
1162 
1163  /* copy and zero-terminate the data (even if it's binary) */
1164  memcpy(val, columns[i].value, clen);
1165  val[clen] = '\0';
1166 
1167  tup[i].len = clen;
1168  tup[i].value = val;
1169  }
1170  }
1171 
1172  /* And add the tuple to the PGresult's tuple array */
1173  if (!pqAddTuple(res, tup, errmsgp))
1174  goto fail;
1175 
1176  /*
1177  * Success. In single-row mode, make the result available to the client
1178  * immediately.
1179  */
1180  if (conn->singleRowMode)
1181  {
1182  /* Change result status to special single-row value */
1184  /* Stash old result for re-use later */
1185  conn->next_result = conn->result;
1186  conn->result = res;
1187  /* And mark the result ready to return */
1189  }
1190 
1191  return 1;
1192 
1193 fail:
1194  /* release locally allocated PGresult, if we made one */
1195  if (res != conn->result)
1196  PQclear(res);
1197  return 0;
1198 }
bool singleRowMode
Definition: libpq-int.h:418
PGresult * PQcopyResult(const PGresult *src, int flags)
Definition: fe-exec.c:299
#define NULL_LEN
Definition: libpq-int.h:134
char null_field[1]
Definition: libpq-int.h:202
PGresAttDesc * attDescs
Definition: libpq-int.h:172
PGresult * result
Definition: libpq-int.h:500
PGresult * next_result
Definition: libpq-int.h:501
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:45
static bool pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
Definition: fe-exec.c:894
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:46
PGdataValue * rowBuf
Definition: libpq-int.h:496
int numAttributes
Definition: libpq-int.h:171
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:43
static struct @143 value
void PQclear(PGresult *res)
Definition: fe-exec.c:694
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:539
int i
char * value
Definition: libpq-int.h:139
ExecStatusType resultStatus
Definition: libpq-int.h:178
long val
Definition: informix.c:664

◆ pqSaveErrorResult()

void pqSaveErrorResult ( PGconn conn)

Definition at line 765 of file fe-exec.c.

References PGRES_FATAL_ERROR, pqClearAsyncResult(), PQmakeEmptyPGresult(), and pg_conn::result.

Referenced by getAnotherTuple(), getCopyResult(), getParamDescriptions(), getRowDescriptions(), handleSyncLoss(), pqFunctionCall3(), PQgetResult(), pqParseInput3(), pqPipelineProcessQueue(), and pqSaveWriteError().

766 {
767  pqClearAsyncResult(conn);
769 }
PGresult * result
Definition: libpq-int.h:500
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:146
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:749

◆ pqSaveMessageField()

void void pqSaveMessageField ( PGresult res,
char  code,
const char *  value 
)

Definition at line 961 of file fe-exec.c.

References pgMessageField::code, pgMessageField::contents, pg_result::errFields, pgMessageField::next, offsetof, and pqResultAlloc().

Referenced by pqGetErrorNotice3(), and pqInternalNotice().

962 {
963  PGMessageField *pfield;
964 
965  pfield = (PGMessageField *)
966  pqResultAlloc(res,
967  offsetof(PGMessageField, contents) +
968  strlen(value) + 1,
969  true);
970  if (!pfield)
971  return; /* out of memory? */
972  pfield->code = code;
973  strcpy(pfield->contents, value);
974  pfield->next = res->errFields;
975  res->errFields = pfield;
976 }
PGMessageField * errFields
Definition: libpq-int.h:198
struct pgMessageField * next
Definition: libpq-int.h:145
static struct @143 value
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:539
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:147
#define offsetof(type, field)
Definition: c.h:727

◆ pqSaveParameterStatus()

void pqSaveParameterStatus ( PGconn conn,
const char *  name,
const char *  value 
)

Definition at line 982 of file fe-exec.c.

References pg_conn::client_encoding, pg_conn::default_transaction_read_only, free, pg_conn::in_hot_standby, malloc, pgParameterStatus::name, pgParameterStatus::next, PG_BOOL_NO, PG_BOOL_YES, pg_char_to_encoding(), PG_SQL_ASCII, pg_conn::pstatus, static_client_encoding, static_std_strings, pg_conn::std_strings, pg_conn::sversion, and pgParameterStatus::value.

Referenced by getParameterStatus().

983 {
984  pgParameterStatus *pstatus;
985  pgParameterStatus *prev;
986 
987  /*
988  * Forget any old information about the parameter
989  */
990  for (pstatus = conn->pstatus, prev = NULL;
991  pstatus != NULL;
992  prev = pstatus, pstatus = pstatus->next)
993  {
994  if (strcmp(pstatus->name, name) == 0)
995  {
996  if (prev)
997  prev->next = pstatus->next;
998  else
999  conn->pstatus = pstatus->next;
1000  free(pstatus); /* frees name and value strings too */
1001  break;
1002  }
1003  }
1004 
1005  /*
1006  * Store new info as a single malloc block
1007  */
1008  pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
1009  strlen(name) + strlen(value) + 2);
1010  if (pstatus)
1011  {
1012  char *ptr;
1013 
1014  ptr = ((char *) pstatus) + sizeof(pgParameterStatus);
1015  pstatus->name = ptr;
1016  strcpy(ptr, name);
1017  ptr += strlen(name) + 1;
1018  pstatus->value = ptr;
1019  strcpy(ptr, value);
1020  pstatus->next = conn->pstatus;
1021  conn->pstatus = pstatus;
1022  }
1023 
1024  /*
1025  * Save values of settings that are of interest to libpq in fields of the
1026  * PGconn object. We keep client_encoding and standard_conforming_strings
1027  * in static variables as well, so that PQescapeString and PQescapeBytea
1028  * can behave somewhat sanely (at least in single-connection-using
1029  * programs).
1030  */
1031  if (strcmp(name, "client_encoding") == 0)
1032  {
1034  /* if we don't recognize the encoding name, fall back to SQL_ASCII */
1035  if (conn->client_encoding < 0)
1036  conn->client_encoding = PG_SQL_ASCII;
1038  }
1039  else if (strcmp(name, "standard_conforming_strings") == 0)
1040  {
1041  conn->std_strings = (strcmp(value, "on") == 0);
1043  }
1044  else if (strcmp(name, "server_version") == 0)
1045  {
1046  /* We convert the server version to numeric form. */
1047  int cnt;
1048  int vmaj,
1049  vmin,
1050  vrev;
1051 
1052  cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);
1053 
1054  if (cnt == 3)
1055  {
1056  /* old style, e.g. 9.6.1 */
1057  conn->sversion = (100 * vmaj + vmin) * 100 + vrev;
1058  }
1059  else if (cnt == 2)
1060  {
1061  if (vmaj >= 10)
1062  {
1063  /* new style, e.g. 10.1 */
1064  conn->sversion = 100 * 100 * vmaj + vmin;
1065  }
1066  else
1067  {
1068  /* old style without minor version, e.g. 9.6devel */
1069  conn->sversion = (100 * vmaj + vmin) * 100;
1070  }
1071  }
1072  else if (cnt == 1)
1073  {
1074  /* new style without minor version, e.g. 10devel */
1075  conn->sversion = 100 * 100 * vmaj;
1076  }
1077  else
1078  conn->sversion = 0; /* unknown */
1079  }
1080  else if (strcmp(name, "default_transaction_read_only") == 0)
1081  {
1083  (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1084  }
1085  else if (strcmp(name, "in_hot_standby") == 0)
1086  {
1087  conn->in_hot_standby =
1088  (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1089  }
1090 }
static bool static_std_strings
Definition: fe-exec.c:52
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
#define malloc(a)
Definition: header.h:50
int sversion
Definition: libpq-int.h:449
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:472
struct pgParameterStatus pgParameterStatus
static int static_client_encoding
Definition: fe-exec.c:51
PGTernaryBool in_hot_standby
Definition: libpq-int.h:473
pgParameterStatus * pstatus
Definition: libpq-int.h:469
bool std_strings
Definition: libpq-int.h:471
static struct @143 value
#define free(a)
Definition: header.h:65
struct pgParameterStatus * next
Definition: libpq-int.h:261
const char * name
Definition: encode.c:561
int client_encoding
Definition: libpq-int.h:470

◆ pqsecure_close()

void pqsecure_close ( PGconn )

Definition at line 191 of file fe-secure.c.

References pgtls_close().

Referenced by pqDropConnection().

192 {
193 #ifdef USE_SSL
194  pgtls_close(conn);
195 #endif
196 }
PGconn * conn
Definition: streamutil.c:54
void pgtls_close(PGconn *conn)

◆ pqsecure_initialize()

int pqsecure_initialize ( PGconn ,
bool  ,
bool   
)

Definition at line 162 of file fe-secure.c.

References pgtls_init().

Referenced by PQconnectPoll().

163 {
164  int r = 0;
165 
166 #ifdef USE_SSL
167  r = pgtls_init(conn, do_ssl, do_crypto);
168 #endif
169 
170  return r;
171 }
int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
PGconn * conn
Definition: streamutil.c:54

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn )

Definition at line 177 of file fe-secure.c.

References PGRES_POLLING_FAILED, and pgtls_open_client().

Referenced by PQconnectPoll().

178 {
179 #ifdef USE_SSL
180  return pgtls_open_client(conn);
181 #else
182  /* shouldn't get here */
183  return PGRES_POLLING_FAILED;
184 #endif
185 }
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
PGconn * conn
Definition: streamutil.c:54

◆ pqsecure_raw_read()

ssize_t pqsecure_raw_read ( PGconn ,
void *  ptr,
size_t  len 
)

Definition at line 232 of file fe-secure.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), EAGAIN, ECONNRESET, EINTR, pg_conn::errorMessage, EWOULDBLOCK, libpq_gettext, PG_STRERROR_R_BUFLEN, recv, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, and SOCK_STRERROR.

Referenced by gss_read(), my_sock_read(), pg_GSS_read(), and pqsecure_read().

233 {
234  ssize_t n;
235  int result_errno = 0;
236  char sebuf[PG_STRERROR_R_BUFLEN];
237 
238  n = recv(conn->sock, ptr, len, 0);
239 
240  if (n < 0)
241  {
242  result_errno = SOCK_ERRNO;
243 
244  /* Set error message if appropriate */
245  switch (result_errno)
246  {
247 #ifdef EAGAIN
248  case EAGAIN:
249 #endif
250 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
251  case EWOULDBLOCK:
252 #endif
253  case EINTR:
254  /* no error message, caller is expected to retry */
255  break;
256 
257  case EPIPE:
258  case ECONNRESET:
260  libpq_gettext("server closed the connection unexpectedly\n"
261  "\tThis probably means the server terminated abnormally\n"
262  "\tbefore or while processing the request.\n"));
263  break;
264 
265  default:
267  libpq_gettext("could not receive data from server: %s\n"),
268  SOCK_STRERROR(result_errno,
269  sebuf, sizeof(sebuf)));
270  break;
271  }
272  }
273 
274  /* ensure we return the intended errno to caller */
275  SOCK_ERRNO_SET(result_errno);
276 
277  return n;
278 }
#define EAGAIN
Definition: win32_port.h:349
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define PG_STRERROR_R_BUFLEN
Definition: port.h:235
#define recv(s, buf, len, flags)
Definition: win32_port.h:475
#define SOCK_STRERROR
Definition: libpq-int.h:855
#define SOCK_ERRNO
Definition: libpq-int.h:854
PGconn * conn
Definition: streamutil.c:54
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:856
pgsocket sock
Definition: libpq-int.h:444
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define ECONNRESET
Definition: win32_port.h:361
#define EWOULDBLOCK
Definition: win32_port.h:357
#define EINTR
Definition: win32_port.h:351
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqsecure_raw_write()

ssize_t pqsecure_raw_write ( PGconn ,
const void *  ptr,
size_t  len 
)

Definition at line 314 of file fe-secure.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), DECLARE_SIGPIPE_INFO, DISABLE_SIGPIPE, EAGAIN, ECONNRESET, EINTR, pg_conn::errorMessage, EWOULDBLOCK, libpq_gettext, PG_STRERROR_R_BUFLEN, REMEMBER_EPIPE, RESTORE_SIGPIPE, send, pg_conn::sigpipe_flag, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, and SOCK_STRERROR.

Referenced by my_sock_write(), pg_GSS_write(), pqsecure_open_gss(), and pqsecure_write().

315 {
316  ssize_t n;
317  int flags = 0;
318  int result_errno = 0;
319  char sebuf[PG_STRERROR_R_BUFLEN];
320 
321  DECLARE_SIGPIPE_INFO(spinfo);
322 
323 #ifdef MSG_NOSIGNAL
324  if (conn->sigpipe_flag)
325  flags |= MSG_NOSIGNAL;
326 
327 retry_masked:
328 #endif /* MSG_NOSIGNAL */
329 
330  DISABLE_SIGPIPE(conn, spinfo, return -1);
331 
332  n = send(conn->sock, ptr, len, flags);
333 
334  if (n < 0)
335  {
336  result_errno = SOCK_ERRNO;
337 
338  /*
339  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
340  * on this machine. So, clear sigpipe_flag so we don't try the flag
341  * again, and retry the send().
342  */
343 #ifdef MSG_NOSIGNAL
344  if (flags != 0 && result_errno == EINVAL)
345  {
346  conn->sigpipe_flag = false;
347  flags = 0;
348  goto retry_masked;
349  }
350 #endif /* MSG_NOSIGNAL */
351 
352  /* Set error message if appropriate */
353  switch (result_errno)
354  {
355 #ifdef EAGAIN
356  case EAGAIN:
357 #endif
358 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
359  case EWOULDBLOCK:
360 #endif
361  case EINTR:
362  /* no error message, caller is expected to retry */
363  break;
364 
365  case EPIPE:
366  /* Set flag for EPIPE */
367  REMEMBER_EPIPE(spinfo, true);
368 
369  /* FALL THRU */
370 
371  case ECONNRESET:
373  libpq_gettext("server closed the connection unexpectedly\n"
374  "\tThis probably means the server terminated abnormally\n"
375  "\tbefore or while processing the request.\n"));
376  break;
377 
378  default:
380  libpq_gettext("could not send data to server: %s\n"),
381  SOCK_STRERROR(result_errno,
382  sebuf, sizeof(sebuf)));
383  break;
384  }
385  }
386 
387  RESTORE_SIGPIPE(conn, spinfo);
388 
389  /* ensure we return the intended errno to caller */
390  SOCK_ERRNO_SET(result_errno);
391 
392  return n;
393 }
bool sigpipe_flag
Definition: libpq-int.h:453
#define EAGAIN
Definition: win32_port.h:349
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:97
#define PG_STRERROR_R_BUFLEN
Definition: port.h:235
#define SOCK_STRERROR
Definition: libpq-int.h:855
#define SOCK_ERRNO
Definition: libpq-int.h:854
PGconn * conn
Definition: streamutil.c:54
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:107
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:856
pgsocket sock
Definition: libpq-int.h:444
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:105
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define ECONNRESET
Definition: win32_port.h:361
#define EWOULDBLOCK
Definition: win32_port.h:357
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:99
#define EINTR
Definition: win32_port.h:351
#define libpq_gettext(x)
Definition: libpq-int.h:841
#define send(s, buf, len, flags)
Definition: win32_port.h:476

◆ pqsecure_read()

ssize_t pqsecure_read ( PGconn ,
void *  ptr,
size_t  len 
)

Definition at line 206 of file fe-secure.c.

References pg_GSS_read(), pgtls_read(), pqsecure_raw_read(), and pg_conn::ssl_in_use.

Referenced by pqReadData().

207 {
208  ssize_t n;
209 
210 #ifdef USE_SSL
211  if (conn->ssl_in_use)
212  {
213  n = pgtls_read(conn, ptr, len);
214  }
215  else
216 #endif
217 #ifdef ENABLE_GSS
218  if (conn->gssenc)
219  {
220  n = pg_GSS_read(conn, ptr, len);
221  }
222  else
223 #endif
224  {
225  n = pqsecure_raw_read(conn, ptr, len);
226  }
227 
228  return n;
229 }
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:232
PGconn * conn
Definition: streamutil.c:54
bool ssl_in_use
Definition: libpq-int.h:508
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)

◆ pqsecure_write()

ssize_t pqsecure_write ( PGconn ,
const void *  ptr,
size_t  len 
)

Definition at line 288 of file fe-secure.c.

References pg_GSS_write(), pgtls_write(), pqsecure_raw_write(), and pg_conn::ssl_in_use.

Referenced by pqSendSome().

289 {
290  ssize_t n;
291 
292 #ifdef USE_SSL
293  if (conn->ssl_in_use)
294  {
295  n = pgtls_write(conn, ptr, len);
296  }
297  else
298 #endif
299 #ifdef ENABLE_GSS
300  if (conn->gssenc)
301  {
302  n = pg_GSS_write(conn, ptr, len);
303  }
304  else
305 #endif
306  {
307  n = pqsecure_raw_write(conn, ptr, len);
308  }
309 
310  return n;
311 }
PGconn * conn
Definition: streamutil.c:54
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
bool ssl_in_use
Definition: libpq-int.h:508
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:314

◆ PQsendQueryContinue()

int PQsendQueryContinue ( PGconn conn,
const char *  query 
)

Definition at line 1332 of file fe-exec.c.

References PQsendQueryInternal().

Referenced by PQconnectPoll().

1333 {
1334  return PQsendQueryInternal(conn, query, false);
1335 }
static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
Definition: fe-exec.c:1338

◆ pqSetResultError()

void pqSetResultError ( PGresult res,
PQExpBuffer  errorMessage 
)

Definition at line 665 of file fe-exec.c.

References PQExpBufferData::data, pg_result::errMsg, libpq_gettext, PQExpBufferBroken, and pqResultStrdup().

Referenced by pqGetErrorNotice3(), PQgetResult(), and PQmakeEmptyPGresult().

666 {
667  char *msg;
668 
669  if (!res)
670  return;
671 
672  /*
673  * We handle two OOM scenarios here. The errorMessage buffer might be
674  * marked "broken" due to having previously failed to allocate enough
675  * memory for the message, or it might be fine but pqResultStrdup fails
676  * and returns NULL. In either case, just make res->errMsg point directly
677  * at a constant "out of memory" string.
678  */
679  if (!PQExpBufferBroken(errorMessage))
680  msg = pqResultStrdup(res, errorMessage->data);
681  else
682  msg = NULL;
683  if (msg)
684  res->errMsg = msg;
685  else
686  res->errMsg = libpq_gettext("out of memory\n");
687 }
char * errMsg
Definition: libpq-int.h:197
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
#define libpq_gettext(x)
Definition: libpq-int.h:841
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:651

◆ pqSkipnchar()

int pqSkipnchar ( size_t  len,
PGconn conn 
)

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

References pg_conn::inCursor, and pg_conn::inEnd.

Referenced by getAnotherTuple().

191 {
192  if (len > (size_t) (conn->inEnd - conn->inCursor))
193  return EOF;
194 
195  conn->inCursor += len;
196 
197  return 0;
198 }
int inEnd
Definition: libpq-int.h:483
int inCursor
Definition: libpq-int.h:482

◆ pqTraceOutputMessage()

void pqTraceOutputMessage ( PGconn conn,
const char *  message,
bool  toServer 
)

Definition at line 529 of file fe-trace.c.

References fprintf, pg_conn::Pfdebug, pg_ntoh32, PQTRACE_REGRESS_MODE, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutputA(), pqTraceOutputB(), pqTraceOutputC(), pqTraceOutputD(), pqTraceOutputE(), pqTraceOutputf(), pqTraceOutputF(), pqTraceOutputG(), pqTraceOutputH(), pqTraceOutputK(), pqTraceOutputNR(), pqTraceOutputP(), pqTraceOutputQ(), pqTraceOutputR(), pqTraceOutputS(), pqTraceOutputt(), pqTraceOutputT(), pqTraceOutputv(), pqTraceOutputV(), pqTraceOutputW(), pqTraceOutputZ(), and pg_conn::traceFlags.

Referenced by getCopyDataMessage(), pqFunctionCall3(), pqParseInput3(), and pqPutMsgEnd().

530 {
531  char id;
532  int length;
533  char *prefix = toServer ? "F" : "B";
534  int logCursor = 0;
535  bool regress;
536 
537  if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0)
538  {
539  char timestr[128];
540 
541  pqTraceFormatTimestamp(timestr, sizeof(timestr));
542  fprintf(conn->Pfdebug, "%s\t", timestr);
543  }
544  regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
545 
546  id = message[logCursor++];
547 
548  memcpy(&length, message + logCursor, 4);
549  length = (int) pg_ntoh32(length);
550  logCursor += 4;
551 
552  /*
553  * In regress mode, suppress the length of ErrorResponse and
554  * NoticeResponse. The F (file name), L (line number) and R (routine
555  * name) fields can change as server code is modified, and if their
556  * lengths differ from the originals, that would break tests.
557  */
558  if (regress && !toServer && (id == 'E' || id == 'N'))
559  fprintf(conn->Pfdebug, "%s\tNN\t", prefix);
560  else
561  fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length);
562 
563  switch (id)
564  {
565  case '1':
566  fprintf(conn->Pfdebug, "ParseComplete");
567  /* No message content */
568  break;
569  case '2':
570  fprintf(conn->Pfdebug, "BindComplete");
571  /* No message content */
572  break;
573  case '3':
574  fprintf(conn->Pfdebug, "CloseComplete");
575  /* No message content */
576  break;
577  case 'A': /* Notification Response */
578  pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
579  break;
580  case 'B': /* Bind */
581  pqTraceOutputB(conn->Pfdebug, message, &logCursor);
582  break;
583  case 'c':
584  fprintf(conn->Pfdebug, "CopyDone");
585  /* No message content */
586  break;
587  case 'C': /* Close(F) or Command Complete(B) */
588  pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor);
589  break;
590  case 'd': /* Copy Data */
591  /* Drop COPY data to reduce the overhead of logging. */
592  break;
593  case 'D': /* Describe(F) or Data Row(B) */
594  pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor);
595  break;
596  case 'E': /* Execute(F) or Error Response(B) */
597  pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor,
598  regress);
599  break;
600  case 'f': /* Copy Fail */
601  pqTraceOutputf(conn->Pfdebug, message, &logCursor);
602  break;
603  case 'F': /* Function Call */
604  pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
605  break;
606  case 'G': /* Start Copy In */
607  pqTraceOutputG(conn->Pfdebug, message, &logCursor);
608  break;
609  case 'H': /* Flush(F) or Start Copy Out(B) */
610  if (!toServer)
611  pqTraceOutputH(conn->Pfdebug, message, &logCursor);
612  else
613  fprintf(conn->Pfdebug, "Flush"); /* no message content */
614  break;
615  case 'I':
616  fprintf(conn->Pfdebug, "EmptyQueryResponse");
617  /* No message content */
618  break;
619  case 'K': /* secret key data from the backend */
620  pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
621  break;
622  case 'n':
623  fprintf(conn->Pfdebug, "NoData");
624  /* No message content */
625  break;
626  case 'N':
627  pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
628  &logCursor, regress);
629  break;
630  case 'P': /* Parse */
631  pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
632  break;
633  case 'Q': /* Query */
634  pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
635  break;
636  case 'R': /* Authentication */
637  pqTraceOutputR(conn->Pfdebug, message, &logCursor);
638  break;
639  case 's':
640  fprintf(conn->Pfdebug, "PortalSuspended");
641  /* No message content */
642  break;
643  case 'S': /* Parameter Status(B) or Sync(F) */
644  if (!toServer)
645  pqTraceOutputS(conn->Pfdebug, message, &logCursor);
646  else
647  fprintf(conn->Pfdebug, "Sync"); /* no message content */
648  break;
649  case 't': /* Parameter Description */
650  pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
651  break;
652  case 'T': /* Row Description */
653  pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
654  break;
655  case 'v': /* Negotiate Protocol Version */
656  pqTraceOutputv(conn->Pfdebug, message, &logCursor);
657  break;
658  case 'V': /* Function Call response */
659  pqTraceOutputV(conn->Pfdebug, message, &logCursor);
660  break;
661  case 'W': /* Start Copy Both */
662  pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
663  break;
664  case 'X':
665  fprintf(conn->Pfdebug, "Terminate");
666  /* No message content */
667  break;
668  case 'Z': /* Ready For Query */
669  pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
670  break;
671  default:
672  fprintf(conn->Pfdebug, "Unknown message: %02x", id);
673  break;
674  }
675 
676  fputc('\n', conn->Pfdebug);
677 
678  /*
679  * Verify the printing routine did it right. Note that the one-byte
680  * message identifier is not included in the length, but our cursor does
681  * include it.
682  */
683  if (logCursor - 1 != length)
684  fprintf(conn->Pfdebug,
685  "mismatched message length: consumed %d, expected %d\n",
686  logCursor - 1, length);
687 }
static void pqTraceOutputK(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:404
static void pqTraceOutputC(FILE *f, bool toServer, const char *message, int *cursor)
Definition: fe-trace.c:261
static void pqTraceOutputNR(FILE *f, const char *type, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:306
static void pqTraceOutputG(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:376
static void pqTraceOutputT(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:466
static void pqTraceOutputQ(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:428
static void pqTraceOutputA(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:220
static void pqTraceOutputR(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:436
static void pqTraceOutputV(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:496
static void pqTraceOutputH(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:390
static void pqTraceOutputf(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:341
static void pqTraceOutputW(FILE *f, const char *message, int *cursor, int length)
Definition: fe-trace.c:508
int traceFlags
Definition: libpq-int.h:399
#define fprintf
Definition: port.h:221
FILE * Pfdebug
Definition: libpq-int.h:398
static void pqTraceOutputB(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:230
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
static void pqTraceOutputF(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:349
static void pqTraceOutputD(FILE *f, bool toServer, const char *message, int *cursor)
Definition: fe-trace.c:278
static void pqTraceOutputt(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:453
static void pqTraceOutputZ(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:519
static void pqTraceOutputE(FILE *f, bool toServer, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:327
static void pqTraceOutputP(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:413
#define PQTRACE_REGRESS_MODE
Definition: libpq-fe.h:414
static void pqTraceOutputv(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:487
#define PQTRACE_SUPPRESS_TIMESTAMPS
Definition: libpq-fe.h:412
static void pqTraceFormatTimestamp(char *timestr, size_t ts_len)
Definition: fe-trace.c:80
static void pqTraceOutputS(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:444

◆ pqTraceOutputNoTypeByteMessage()

void pqTraceOutputNoTypeByteMessage ( PGconn conn,
const char *  message 
)

Definition at line 694 of file fe-trace.c.

References fprintf, pg_conn::Pfdebug, pg_ntoh32, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutputInt32(), and pg_conn::traceFlags.

Referenced by pqPutMsgEnd().

695 {
696  int length;
697  int logCursor = 0;
698 
699  if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0)
700  {
701  char timestr[128];
702 
703  pqTraceFormatTimestamp(timestr, sizeof(timestr));
704  fprintf(conn->Pfdebug, "%s\t", timestr);
705  }
706 
707  memcpy(&length, message + logCursor, 4);
708  length = (int) pg_ntoh32(length);
709  logCursor += 4;
710 
711  fprintf(conn->Pfdebug, "F\t%d\t", length);
712 
713  switch (length)
714  {
715  case 16: /* CancelRequest */
716  fprintf(conn->Pfdebug, "CancelRequest\t");
717  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
718  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
719  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
720  break;
721  case 8: /* GSSENCRequest or SSLRequest */
722  /* These messages do not reach here. */
723  default:
724  fprintf(conn->Pfdebug, "Unknown message: length is %d", length);
725  break;
726  }
727 
728  fputc('\n', conn->Pfdebug);
729 }
int traceFlags
Definition: libpq-int.h:399
#define fprintf
Definition: port.h:221
FILE * Pfdebug
Definition: libpq-int.h:398
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
#define PQTRACE_SUPPRESS_TIMESTAMPS
Definition: libpq-fe.h:412
static int pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:144
static void pqTraceFormatTimestamp(char *timestr, size_t ts_len)
Definition: fe-trace.c:80

◆ pqWait()

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

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

References pqWaitTimed().

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

991 {
992  return pqWaitTimed(forRead, forWrite, conn, (time_t) -1);
993 }
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:1003

◆ pqWaitTimed()

int pqWaitTimed ( int  forRead,
int  forWrite,
PGconn conn,
time_t  finish_time 
)

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

References appendPQExpBufferStr(), pg_conn::errorMessage, libpq_gettext, and pqSocketCheck().

Referenced by connectDBComplete(), and pqWait().

1004 {
1005  int result;
1006 
1007  result = pqSocketCheck(conn, forRead, forWrite, finish_time);
1008 
1009  if (result < 0)
1010  return -1; /* errorMessage is already set */
1011 
1012  if (result == 0)
1013  {
1015  libpq_gettext("timeout expired\n"));
1016  return 1;
1017  }
1018 
1019  return 0;
1020 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
Definition: fe-misc.c:1051
PQExpBufferData errorMessage
Definition: libpq-int.h:571
#define libpq_gettext(x)
Definition: libpq-int.h:841

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

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

References pqSocketCheck().

1038 {
1039  return pqSocketCheck(conn, 0, 1, (time_t) 0);
1040 }
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
Definition: fe-misc.c:1051

Variable Documentation

◆ pgresStatus

char* const pgresStatus[]

Definition at line 32 of file fe-exec.c.

Referenced by PQresStatus().