PostgreSQL Source Code  git master
libpq-int.h File Reference
#include "libpq-events.h"
#include <netdb.h>
#include <sys/socket.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>
#include "libpq/pqcomm.h"
#include "fe-auth-sasl.h"
#include "pqexpbuffer.h"
#include "common/pg_prng.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
 

Macros

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */
 
#define NULL_LEN   (-1) /* pg_result len for NULL value */
 
#define ENC_ERROR   0
 
#define ENC_PLAINTEXT   0x01
 
#define ENC_GSSAPI   0x02
 
#define ENC_DIRECT_SSL   0x04
 
#define ENC_NEGOTIATED_SSL   0x08
 
#define pglock_thread()   pg_g_threadlock(true)
 
#define pgunlock_thread()   pg_g_threadlock(false)
 
#define pqClearConnErrorState(conn)
 
#define pgHavePendingResult(conn)    ((conn)->result != NULL || (conn)->error_result)
 
#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 , PGASYNC_PIPELINE_IDLE
}
 
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  PGLoadBalanceType { LOAD_BALANCE_DISABLE = 0 , LOAD_BALANCE_RANDOM }
 
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 , PGQUERY_CLOSE
}
 

Functions

void pqDropConnection (PGconn *conn, bool flushInput)
 
bool pqConnectOptions2 (PGconn *conn)
 
int pqConnectDBStart (PGconn *conn)
 
int pqConnectDBComplete (PGconn *conn)
 
PGconnpqMakeEmptyPGconn (void)
 
void pqReleaseConnHosts (PGconn *conn)
 
void pqClosePGconn (PGconn *conn)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
bool pqCopyPGconn (PGconn *srcConn, PGconn *dstConn)
 
bool pqParseIntParam (const char *value, int *result, PGconn *conn, const char *context)
 
void pqSetResultError (PGresult *res, PQExpBuffer errorMessage, int offset)
 
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, bool isReadyForQuery, bool gotSync)
 
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 pqGetNegotiateProtocolVersion3 (PGconn *conn)
 
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)
 
int pq_block_sigpipe (sigset_t *osigset, bool *sigpipe_pending)
 
void pq_reset_sigpipe (sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 
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)
 
char * pgtls_get_peer_certificate_hash (PGconn *conn, 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)
 
void libpq_append_error (PQExpBuffer errorMessage, const char *fmt,...) pg_attribute_printf(2
 
void void libpq_append_conn_error (PGconn *conn, const char *fmt,...) pg_attribute_printf(2
 

Variables

char *const pgresStatus []
 
pgthreadlock_t pg_g_threadlock
 

Macro Definition Documentation

◆ CMDSTATUS_LEN

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */

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

◆ ENC_DIRECT_SSL

#define ENC_DIRECT_SSL   0x04

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

◆ ENC_ERROR

#define ENC_ERROR   0

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

◆ ENC_GSSAPI

#define ENC_GSSAPI   0x02

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

◆ ENC_NEGOTIATED_SSL

#define ENC_NEGOTIATED_SSL   0x08

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

◆ ENC_PLAINTEXT

#define ENC_PLAINTEXT   0x01

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

◆ libpq_gettext

#define libpq_gettext (   x)    (x)

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

◆ libpq_ngettext

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

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

◆ NULL_LEN

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

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

◆ OUTBUFFER_THRESHOLD

#define OUTBUFFER_THRESHOLD   65536

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

◆ pgHavePendingResult

#define pgHavePendingResult (   conn)     ((conn)->result != NULL || (conn)->error_result)

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

◆ pglock_thread

#define pglock_thread ( )    pg_g_threadlock(true)

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

◆ pgunlock_thread

#define pgunlock_thread ( )    pg_g_threadlock(false)

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

◆ pqClearConnErrorState

#define pqClearConnErrorState (   conn)
Value:
(resetPQExpBuffer(&(conn)->errorMessage), \
(conn)->errorReported = 0)
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
PGconn * conn
Definition: streamutil.c:55

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

◆ pqIsnonblocking

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

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

◆ SOCK_ERRNO

#define SOCK_ERRNO   errno

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

◆ SOCK_ERRNO_SET

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

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

◆ SOCK_STRERROR

#define SOCK_STRERROR   strerror_r

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

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 1 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 314 of file libpq-int.h.

315 {
pg_conn_host_type
Definition: libpq-int.h:315
@ CHT_UNIX_SOCKET
Definition: libpq-int.h:318
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:317
@ CHT_HOST_NAME
Definition: libpq-int.h:316

◆ PGAsyncStatusType

Enumerator
PGASYNC_IDLE 
PGASYNC_BUSY 
PGASYNC_READY 
PGASYNC_READY_MORE 
PGASYNC_COPY_IN 
PGASYNC_COPY_OUT 
PGASYNC_COPY_BOTH 
PGASYNC_PIPELINE_IDLE 

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

220 {
221  PGASYNC_IDLE, /* nothing's happening, dude */
222  PGASYNC_BUSY, /* query in progress */
223  PGASYNC_READY, /* query done, waiting for client to fetch
224  * result */
225  PGASYNC_READY_MORE, /* query done, waiting for client to fetch
226  * result, more results expected from this
227  * query */
228  PGASYNC_COPY_IN, /* Copy In data transfer in progress */
229  PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */
230  PGASYNC_COPY_BOTH, /* Copy In/Out data transfer in progress */
231  PGASYNC_PIPELINE_IDLE, /* "Idle" between commands in pipeline mode */
PGAsyncStatusType
Definition: libpq-int.h:220
@ PGASYNC_COPY_OUT
Definition: libpq-int.h:229
@ PGASYNC_READY_MORE
Definition: libpq-int.h:225
@ PGASYNC_READY
Definition: libpq-int.h:223
@ PGASYNC_COPY_BOTH
Definition: libpq-int.h:230
@ PGASYNC_IDLE
Definition: libpq-int.h:221
@ PGASYNC_COPY_IN
Definition: libpq-int.h:228
@ PGASYNC_BUSY
Definition: libpq-int.h:222
@ PGASYNC_PIPELINE_IDLE
Definition: libpq-int.h:231

◆ PGLoadBalanceType

Enumerator
LOAD_BALANCE_DISABLE 
LOAD_BALANCE_RANDOM 

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

255 {
256  LOAD_BALANCE_DISABLE = 0, /* Use the existing host order (default) */
257  LOAD_BALANCE_RANDOM, /* Randomly shuffle the hosts */
PGLoadBalanceType
Definition: libpq-int.h:255
@ LOAD_BALANCE_DISABLE
Definition: libpq-int.h:256
@ LOAD_BALANCE_RANDOM
Definition: libpq-int.h:257

◆ PGQueryClass

Enumerator
PGQUERY_SIMPLE 
PGQUERY_EXTENDED 
PGQUERY_PREPARE 
PGQUERY_DESCRIBE 
PGQUERY_SYNC 
PGQUERY_CLOSE 

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

326 {
327  PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
328  PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
329  PGQUERY_PREPARE, /* Parse only (PQprepare) */
330  PGQUERY_DESCRIBE, /* Describe Statement or Portal */
331  PGQUERY_SYNC, /* Sync (at end of a pipeline) */
332  PGQUERY_CLOSE /* Close Statement or Portal */
333 } PGQueryClass;
PGQueryClass
Definition: libpq-int.h:326
@ PGQUERY_SIMPLE
Definition: libpq-int.h:327
@ PGQUERY_SYNC
Definition: libpq-int.h:331
@ PGQUERY_EXTENDED
Definition: libpq-int.h:328
@ PGQUERY_DESCRIBE
Definition: libpq-int.h:330
@ PGQUERY_CLOSE
Definition: libpq-int.h:332
@ PGQUERY_PREPARE
Definition: libpq-int.h:329

◆ 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 242 of file libpq-int.h.

243 {
244  SERVER_TYPE_ANY = 0, /* Any server (default) */
245  SERVER_TYPE_READ_WRITE, /* Read-write server */
246  SERVER_TYPE_READ_ONLY, /* Read-only server */
247  SERVER_TYPE_PRIMARY, /* Primary server */
248  SERVER_TYPE_STANDBY, /* Standby server */
249  SERVER_TYPE_PREFER_STANDBY, /* Prefer standby server */
250  SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */
PGTargetServerType
Definition: libpq-int.h:243
@ SERVER_TYPE_STANDBY
Definition: libpq-int.h:248
@ SERVER_TYPE_PRIMARY
Definition: libpq-int.h:247
@ SERVER_TYPE_ANY
Definition: libpq-int.h:244
@ SERVER_TYPE_READ_WRITE
Definition: libpq-int.h:245
@ SERVER_TYPE_PREFER_STANDBY_PASS2
Definition: libpq-int.h:250
@ SERVER_TYPE_PREFER_STANDBY
Definition: libpq-int.h:249
@ SERVER_TYPE_READ_ONLY
Definition: libpq-int.h:246

◆ PGTernaryBool

Enumerator
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 

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

262 {
263  PG_BOOL_UNKNOWN = 0, /* Currently unknown */
264  PG_BOOL_YES, /* Yes (true) */
265  PG_BOOL_NO /* No (false) */
266 } PGTernaryBool;
PGTernaryBool
Definition: libpq-int.h:262
@ PG_BOOL_YES
Definition: libpq-int.h:264
@ PG_BOOL_NO
Definition: libpq-int.h:265
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:263

Function Documentation

◆ libpq_append_conn_error()

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

◆ libpq_append_error()

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

◆ pgtls_close()

void pgtls_close ( PGconn conn)

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

1617 {
1618  bool destroy_needed = false;
1619 
1620  if (conn->ssl_in_use)
1621  {
1622  if (conn->ssl)
1623  {
1624  /*
1625  * We can't destroy everything SSL-related here due to the
1626  * possible later calls to OpenSSL routines which may need our
1627  * thread callbacks, so set a flag here and check at the end.
1628  */
1629 
1630  SSL_shutdown(conn->ssl);
1631  SSL_free(conn->ssl);
1632  conn->ssl = NULL;
1633  conn->ssl_in_use = false;
1634  conn->ssl_handshake_started = false;
1635 
1636  destroy_needed = true;
1637  }
1638 
1639  if (conn->peer)
1640  {
1641  X509_free(conn->peer);
1642  conn->peer = NULL;
1643  }
1644 
1645 #ifdef USE_SSL_ENGINE
1646  if (conn->engine)
1647  {
1648  ENGINE_finish(conn->engine);
1649  ENGINE_free(conn->engine);
1650  conn->engine = NULL;
1651  }
1652 #endif
1653  }
1654  else
1655  {
1656  /*
1657  * In the non-SSL case, just remove the crypto callbacks if the
1658  * connection has them loaded. This code path has no dependency on
1659  * any pending SSL calls.
1660  */
1661  if (conn->crypto_loaded)
1662  destroy_needed = true;
1663  }
1664 
1665  /*
1666  * This will remove our crypto locking hooks if this is the last
1667  * connection using libcrypto which means we must wait to call it until
1668  * after all the potential SSL calls have been made, otherwise we can end
1669  * up with a race condition and possible deadlocks.
1670  *
1671  * See comments above destroy_ssl_system().
1672  */
1673  if (destroy_needed)
1674  {
1676  conn->crypto_loaded = false;
1677  }
1678 }
static void destroy_ssl_system(void)
bool ssl_handshake_started
Definition: libpq-int.h:569
bool ssl_in_use
Definition: libpq-int.h:568

References conn, destroy_ssl_system(), pg_conn::ssl_handshake_started, and pg_conn::ssl_in_use.

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

◆ pgtls_get_peer_certificate_hash()

char* pgtls_get_peer_certificate_hash ( PGconn conn,
size_t *  len 
)

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

363 {
364  X509 *peer_cert;
365  const EVP_MD *algo_type;
366  unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
367  unsigned int hash_size;
368  int algo_nid;
369  char *cert_hash;
370 
371  *len = 0;
372 
373  if (!conn->peer)
374  return NULL;
375 
376  peer_cert = conn->peer;
377 
378  /*
379  * Get the signature algorithm of the certificate to determine the hash
380  * algorithm to use for the result. Prefer X509_get_signature_info(),
381  * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
382  */
383 #if HAVE_X509_GET_SIGNATURE_INFO
384  if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
385 #else
386  if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
387  &algo_nid, NULL))
388 #endif
389  {
390  libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
391  return NULL;
392  }
393 
394  /*
395  * The TLS server's certificate bytes need to be hashed with SHA-256 if
396  * its signature algorithm is MD5 or SHA-1 as per RFC 5929
397  * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
398  * is used, the same hash as the signature algorithm is used.
399  */
400  switch (algo_nid)
401  {
402  case NID_md5:
403  case NID_sha1:
404  algo_type = EVP_sha256();
405  break;
406  default:
407  algo_type = EVP_get_digestbynid(algo_nid);
408  if (algo_type == NULL)
409  {
410  libpq_append_conn_error(conn, "could not find digest for NID %s",
411  OBJ_nid2sn(algo_nid));
412  return NULL;
413  }
414  break;
415  }
416 
417  if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
418  {
419  libpq_append_conn_error(conn, "could not generate peer certificate hash");
420  return NULL;
421  }
422 
423  /* save result */
424  cert_hash = malloc(hash_size);
425  if (cert_hash == NULL)
426  {
427  libpq_append_conn_error(conn, "out of memory");
428  return NULL;
429  }
430  memcpy(cert_hash, hash, hash_size);
431  *len = hash_size;
432 
433  return cert_hash;
434 }
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1324
#define malloc(a)
Definition: header.h:50
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715

References conn, hash(), len, libpq_append_conn_error(), and malloc.

Referenced by build_client_final_message().

◆ pgtls_init()

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

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

770 {
772  return -1;
773 
774 #ifdef HAVE_CRYPTO_LOCK
775  if (pq_init_crypto_lib)
776  {
777  /*
778  * If necessary, set up an array to hold locks for libcrypto.
779  * libcrypto will tell us how big to make this array.
780  */
781  if (pq_lockarray == NULL)
782  {
783  int i;
784 
785  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
786  if (!pq_lockarray)
787  {
789  return -1;
790  }
791  for (i = 0; i < CRYPTO_num_locks(); i++)
792  {
793  if (pthread_mutex_init(&pq_lockarray[i], NULL))
794  {
795  free(pq_lockarray);
796  pq_lockarray = NULL;
798  return -1;
799  }
800  }
801  }
802 
803  if (do_crypto && !conn->crypto_loaded)
804  {
805  if (crypto_open_connections++ == 0)
806  {
807  /*
808  * These are only required for threaded libcrypto
809  * applications, but make sure we don't stomp on them if
810  * they're already set.
811  */
812  if (CRYPTO_get_id_callback() == NULL)
813  CRYPTO_set_id_callback(pq_threadidcallback);
814  if (CRYPTO_get_locking_callback() == NULL)
815  CRYPTO_set_locking_callback(pq_lockingcallback);
816  }
817 
818  conn->crypto_loaded = true;
819  }
820  }
821 #endif /* HAVE_CRYPTO_LOCK */
822 
823  if (!ssl_lib_initialized && do_ssl)
824  {
825  if (pq_init_ssl_lib)
826  {
827 #ifdef HAVE_OPENSSL_INIT_SSL
828  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
829 #else
830  OPENSSL_config(NULL);
831  SSL_library_init();
832  SSL_load_error_strings();
833 #endif
834  }
835  ssl_lib_initialized = true;
836  }
837 
839  return 0;
840 }
static bool pq_init_crypto_lib
static long crypto_open_connections
static bool ssl_lib_initialized
static bool pq_init_ssl_lib
static pthread_mutex_t ssl_config_mutex
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:73
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:60
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:42
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35

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

Referenced by pqsecure_initialize().

◆ pgtls_init_library()

void pgtls_init_library ( bool  do_ssl,
int  do_crypto 
)

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

105 {
106  /*
107  * Disallow changing the flags while we have open connections, else we'd
108  * get completely confused.
109  */
110  if (crypto_open_connections != 0)
111  return;
112 
113  pq_init_ssl_lib = do_ssl;
114  pq_init_crypto_lib = do_crypto;
115 }

References crypto_open_connections, pq_init_crypto_lib, and pq_init_ssl_lib.

Referenced by PQinitOpenSSL(), and PQinitSSL().

◆ pgtls_open_client()

PostgresPollingStatusType pgtls_open_client ( PGconn conn)

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

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

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

Referenced by pqsecure_open_client().

◆ pgtls_read()

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

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

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

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_read().

◆ pgtls_read_pending()

bool pgtls_read_pending ( PGconn conn)

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

257 {
258  return SSL_pending(conn->ssl) > 0;
259 }

References conn.

Referenced by pqSocketCheck().

◆ 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 574 of file fe-secure-openssl.c.

577 {
578  STACK_OF(GENERAL_NAME) * peer_san;
579  int i;
580  int rc = 0;
581  char *host = conn->connhost[conn->whichhost].host;
582  int host_type;
583  bool check_cn = true;
584 
585  Assert(host && host[0]); /* should be guaranteed by caller */
586 
587  /*
588  * We try to match the NSS behavior here, which is a slight departure from
589  * the spec but seems to make more intuitive sense:
590  *
591  * If connhost contains a DNS name, and the certificate's SANs contain any
592  * dNSName entries, then we'll ignore the Subject Common Name entirely;
593  * otherwise, we fall back to checking the CN. (This behavior matches the
594  * RFC.)
595  *
596  * If connhost contains an IP address, and the SANs contain iPAddress
597  * entries, we again ignore the CN. Otherwise, we allow the CN to match,
598  * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A
599  * client MUST NOT seek a match for a reference identifier of CN-ID if the
600  * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any
601  * application-specific identifier types supported by the client.")
602  *
603  * NOTE: Prior versions of libpq did not consider iPAddress entries at
604  * all, so this new behavior might break a certificate that has different
605  * IP addresses in the Subject CN and the SANs.
606  */
607  if (is_ip_address(host))
608  host_type = GEN_IPADD;
609  else
610  host_type = GEN_DNS;
611 
612  /*
613  * First, get the Subject Alternative Names (SANs) from the certificate,
614  * and compare them against the originally given hostname.
615  */
616  peer_san = (STACK_OF(GENERAL_NAME) *)
617  X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
618 
619  if (peer_san)
620  {
621  int san_len = sk_GENERAL_NAME_num(peer_san);
622 
623  for (i = 0; i < san_len; i++)
624  {
625  const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
626  char *alt_name = NULL;
627 
628  if (name->type == host_type)
629  {
630  /*
631  * This SAN is of the same type (IP or DNS) as our host name,
632  * so don't allow a fallback check of the CN.
633  */
634  check_cn = false;
635  }
636 
637  if (name->type == GEN_DNS)
638  {
639  (*names_examined)++;
641  name->d.dNSName,
642  &alt_name);
643  }
644  else if (name->type == GEN_IPADD)
645  {
646  (*names_examined)++;
648  name->d.iPAddress,
649  &alt_name);
650  }
651 
652  if (alt_name)
653  {
654  if (!*first_name)
655  *first_name = alt_name;
656  else
657  free(alt_name);
658  }
659 
660  if (rc != 0)
661  {
662  /*
663  * Either we hit an error or a match, and either way we should
664  * not fall back to the CN.
665  */
666  check_cn = false;
667  break;
668  }
669  }
670  sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
671  }
672 
673  /*
674  * If there is no subjectAltName extension of the matching type, check the
675  * Common Name.
676  *
677  * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
678  * dNSName is present, the CN must be ignored. We break this rule if host
679  * is an IP address; see the comment above.)
680  */
681  if (check_cn)
682  {
683  X509_NAME *subject_name;
684 
685  subject_name = X509_get_subject_name(conn->peer);
686  if (subject_name != NULL)
687  {
688  int cn_index;
689 
690  cn_index = X509_NAME_get_index_by_NID(subject_name,
691  NID_commonName, -1);
692  if (cn_index >= 0)
693  {
694  char *common_name = NULL;
695 
696  (*names_examined)++;
698  X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
699  &common_name);
700 
701  if (common_name)
702  {
703  if (!*first_name)
704  *first_name = common_name;
705  else
706  free(common_name);
707  }
708  }
709  }
710  }
711 
712  return rc;
713 }
#define Assert(condition)
Definition: c.h:858
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry, char **store_name)
static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, ASN1_OCTET_STRING *addr_entry, char **store_name)
static bool is_ip_address(const char *host)
char * host
Definition: libpq-int.h:353
int whichhost
Definition: libpq-int.h:457
pg_conn_host * connhost
Definition: libpq-int.h:458
const char * name

References Assert, conn, pg_conn::connhost, free, pg_conn_host::host, i, is_ip_address(), name, openssl_verify_peer_name_matches_certificate_ip(), openssl_verify_peer_name_matches_certificate_name(), and pg_conn::whichhost.

Referenced by pq_verify_peer_name_matches_certificate().

◆ pgtls_write()

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

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

263 {
264  ssize_t n;
265  int result_errno = 0;
266  char sebuf[PG_STRERROR_R_BUFLEN];
267  int err;
268  unsigned long ecode;
269 
270  SOCK_ERRNO_SET(0);
271  ERR_clear_error();
272  n = SSL_write(conn->ssl, ptr, len);
273  err = SSL_get_error(conn->ssl, n);
274  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
275  switch (err)
276  {
277  case SSL_ERROR_NONE:
278  if (n < 0)
279  {
280  /* Not supposed to happen, so we don't translate the msg */
282  "SSL_write failed but did not provide error information\n");
283  /* assume the connection is broken */
284  result_errno = ECONNRESET;
285  }
286  break;
287  case SSL_ERROR_WANT_READ:
288 
289  /*
290  * Returning 0 here causes caller to wait for write-ready, which
291  * is not really the right thing, but it's the best we can do.
292  */
293  n = 0;
294  break;
295  case SSL_ERROR_WANT_WRITE:
296  n = 0;
297  break;
298  case SSL_ERROR_SYSCALL:
299 
300  /*
301  * If errno is still zero then assume it's a read EOF situation,
302  * and report EOF. (This seems possible because SSL_write can
303  * also do reads.)
304  */
305  if (n < 0 && SOCK_ERRNO != 0)
306  {
307  result_errno = SOCK_ERRNO;
308  if (result_errno == EPIPE || result_errno == ECONNRESET)
309  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
310  "\tThis probably means the server terminated abnormally\n"
311  "\tbefore or while processing the request.");
312  else
313  libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
314  SOCK_STRERROR(result_errno,
315  sebuf, sizeof(sebuf)));
316  }
317  else
318  {
319  libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
320  /* assume the connection is broken */
321  result_errno = ECONNRESET;
322  n = -1;
323  }
324  break;
325  case SSL_ERROR_SSL:
326  {
327  char *errm = SSLerrmessage(ecode);
328 
329  libpq_append_conn_error(conn, "SSL error: %s", errm);
330  SSLerrfree(errm);
331  /* assume the connection is broken */
332  result_errno = ECONNRESET;
333  n = -1;
334  break;
335  }
336  case SSL_ERROR_ZERO_RETURN:
337 
338  /*
339  * Per OpenSSL documentation, this error code is only returned for
340  * a clean connection closure, so we should not report it as a
341  * server crash.
342  */
343  libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
344  result_errno = ECONNRESET;
345  n = -1;
346  break;
347  default:
348  libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
349  /* assume the connection is broken */
350  result_errno = ECONNRESET;
351  n = -1;
352  break;
353  }
354 
355  /* ensure we return the intended errno to caller */
356  SOCK_ERRNO_SET(result_errno);
357 
358  return n;
359 }

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_write().

◆ pq_block_sigpipe()

int pq_block_sigpipe ( sigset_t *  osigset,
bool sigpipe_pending 
)

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

520 {
521  sigset_t sigpipe_sigset;
522  sigset_t sigset;
523 
524  sigemptyset(&sigpipe_sigset);
525  sigaddset(&sigpipe_sigset, SIGPIPE);
526 
527  /* Block SIGPIPE and save previous mask for later reset */
528  SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
529  if (SOCK_ERRNO)
530  return -1;
531 
532  /* We can have a pending SIGPIPE only if it was blocked before */
533  if (sigismember(osigset, SIGPIPE))
534  {
535  /* Is there a pending SIGPIPE? */
536  if (sigpending(&sigset) != 0)
537  return -1;
538 
539  if (sigismember(&sigset, SIGPIPE))
540  *sigpipe_pending = true;
541  else
542  *sigpipe_pending = false;
543  }
544  else
545  *sigpipe_pending = false;
546 
547  return 0;
548 }
#define SIGPIPE
Definition: win32_port.h:173

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by PQprint().

◆ pq_reset_sigpipe()

void pq_reset_sigpipe ( sigset_t *  osigset,
bool  sigpipe_pending,
bool  got_epipe 
)

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

570 {
571  int save_errno = SOCK_ERRNO;
572  int signo;
573  sigset_t sigset;
574 
575  /* Clear SIGPIPE only if none was pending */
576  if (got_epipe && !sigpipe_pending)
577  {
578  if (sigpending(&sigset) == 0 &&
579  sigismember(&sigset, SIGPIPE))
580  {
581  sigset_t sigpipe_sigset;
582 
583  sigemptyset(&sigpipe_sigset);
584  sigaddset(&sigpipe_sigset, SIGPIPE);
585 
586  sigwait(&sigpipe_sigset, &signo);
587  }
588  }
589 
590  /* Restore saved block mask */
591  pthread_sigmask(SIG_SETMASK, osigset, NULL);
592 
593  SOCK_ERRNO_SET(save_errno);
594 }

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by PQprint().

◆ pqBuildErrorMessage3()

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

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

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

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(), res, pg_result::resultStatus, and val.

Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().

◆ pqBuildStartupPacket3()

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

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

2239 {
2240  char *startpacket;
2241 
2242  *packetlen = build_startup_packet(conn, NULL, options);
2243  startpacket = (char *) malloc(*packetlen);
2244  if (!startpacket)
2245  return NULL;
2246  *packetlen = build_startup_packet(conn, startpacket, options);
2247  return startpacket;
2248 }
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)

References build_startup_packet(), conn, and malloc.

Referenced by PQconnectPoll().

◆ pqCheckInBufferSpace()

int pqCheckInBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

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

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

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

◆ pqCheckOutBufferSpace()

int pqCheckOutBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

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

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

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

◆ pqClearAsyncResult()

void pqClearAsyncResult ( PGconn conn)

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

780 {
781  PQclear(conn->result);
782  conn->result = NULL;
783  conn->error_result = false;
785  conn->saved_result = NULL;
786 }
void PQclear(PGresult *res)
Definition: fe-exec.c:721
PGresult * result
Definition: libpq-int.h:554
PGresult * saved_result
Definition: libpq-int.h:556
bool error_result
Definition: libpq-int.h:555

References conn, pg_conn::error_result, PQclear(), pg_conn::result, and pg_conn::saved_result.

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

◆ pqClosePGconn()

void pqClosePGconn ( PGconn conn)

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

4823 {
4824  /*
4825  * If possible, send Terminate message to close the connection politely.
4826  */
4828 
4829  /*
4830  * Must reset the blocking status so a possible reconnect will work.
4831  *
4832  * Don't call PQsetnonblocking() because it will fail if it's unable to
4833  * flush the connection.
4834  */
4835  conn->nonblocking = false;
4836 
4837  /*
4838  * Close the connection, reset all transient state, flush I/O buffers.
4839  * Note that this includes clearing conn's error state; we're no longer
4840  * interested in any failures associated with the old connection, and we
4841  * want a clean slate for any new connection attempt.
4842  */
4843  pqDropConnection(conn, true);
4844  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
4848  pqClearAsyncResult(conn); /* deallocate result */
4850 
4851  /*
4852  * Release addrinfo, but since cancel requests never change their addrinfo
4853  * we don't do that. Otherwise we would have to rebuild it during a
4854  * PQcancelReset.
4855  */
4856  if (!conn->cancelRequest)
4858 
4859  /* Reset all state obtained from server, too */
4861 }
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:471
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:4788
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:4774
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:584
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:779
@ CONNECTION_BAD
Definition: libpq-fe.h:62
@ PQTRANS_IDLE
Definition: libpq-fe.h:122
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:162
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:886
PGTransactionStatusType xactStatus
Definition: libpq-int.h:440
bool cancelRequest
Definition: libpq-int.h:421
bool nonblocking
Definition: libpq-int.h:443
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:439
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:445
ConnStatusType status
Definition: libpq-int.h:438

References pg_conn::asyncStatus, pg_conn::cancelRequest, conn, CONNECTION_BAD, pg_conn::nonblocking, PGASYNC_IDLE, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqClearAsyncResult(), pqClearConnErrorState, pqDropConnection(), pqDropServerData(), PQTRANS_IDLE, release_conn_addrinfo(), sendTerminateConn(), pg_conn::status, and pg_conn::xactStatus.

Referenced by PQcancelReset(), PQfinish(), PQreset(), and PQresetStart().

◆ pqCommandQueueAdvance()

void pqCommandQueueAdvance ( PGconn conn,
bool  isReadyForQuery,
bool  gotSync 
)

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

3143 {
3144  PGcmdQueueEntry *prevquery;
3145 
3146  if (conn->cmd_queue_head == NULL)
3147  return;
3148 
3149  /*
3150  * If processing a query of simple query protocol, we only advance the
3151  * queue when we receive the ReadyForQuery message for it.
3152  */
3153  if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
3154  return;
3155 
3156  /*
3157  * If we're waiting for a SYNC, don't advance the queue until we get one.
3158  */
3159  if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
3160  return;
3161 
3162  /* delink element from queue */
3163  prevquery = conn->cmd_queue_head;
3165 
3166  /* If the queue is now empty, reset the tail too */
3167  if (conn->cmd_queue_head == NULL)
3168  conn->cmd_queue_tail = NULL;
3169 
3170  /* and make the queue element recyclable */
3171  prevquery->next = NULL;
3172  pqRecycleCmdQueueEntry(conn, prevquery);
3173 }
static void pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
Definition: fe-exec.c:1386
PGQueryClass queryclass
Definition: libpq-int.h:340
struct PGcmdQueueEntry * next
Definition: libpq-int.h:342
PGcmdQueueEntry * cmd_queue_tail
Definition: libpq-int.h:466
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:465

References pg_conn::cmd_queue_head, pg_conn::cmd_queue_tail, conn, PGcmdQueueEntry::next, PGQUERY_SIMPLE, PGQUERY_SYNC, pqRecycleCmdQueueEntry(), and PGcmdQueueEntry::queryclass.

Referenced by PQgetResult(), and pqParseInput3().

◆ pqConnectDBComplete()

int pqConnectDBComplete ( PGconn conn)

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

2453 {
2455  time_t finish_time = ((time_t) -1);
2456  int timeout = 0;
2457  int last_whichhost = -2; /* certainly different from whichhost */
2458  int last_whichaddr = -2; /* certainly different from whichaddr */
2459 
2460  if (conn == NULL || conn->status == CONNECTION_BAD)
2461  return 0;
2462 
2463  /*
2464  * Set up a time limit, if connect_timeout isn't zero.
2465  */
2466  if (conn->connect_timeout != NULL)
2467  {
2468  if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
2469  "connect_timeout"))
2470  {
2471  /* mark the connection as bad to report the parsing failure */
2473  return 0;
2474  }
2475 
2476  if (timeout > 0)
2477  {
2478  /*
2479  * Rounding could cause connection to fail unexpectedly quickly;
2480  * to prevent possibly waiting hardly-at-all, insist on at least
2481  * two seconds.
2482  */
2483  if (timeout < 2)
2484  timeout = 2;
2485  }
2486  else /* negative means 0 */
2487  timeout = 0;
2488  }
2489 
2490  for (;;)
2491  {
2492  int ret = 0;
2493 
2494  /*
2495  * (Re)start the connect_timeout timer if it's active and we are
2496  * considering a different host than we were last time through. If
2497  * we've already succeeded, though, needn't recalculate.
2498  */
2499  if (flag != PGRES_POLLING_OK &&
2500  timeout > 0 &&
2501  (conn->whichhost != last_whichhost ||
2502  conn->whichaddr != last_whichaddr))
2503  {
2504  finish_time = time(NULL) + timeout;
2505  last_whichhost = conn->whichhost;
2506  last_whichaddr = conn->whichaddr;
2507  }
2508 
2509  /*
2510  * Wait, if necessary. Note that the initial state (just after
2511  * PQconnectStart) is to wait for the socket to select for writing.
2512  */
2513  switch (flag)
2514  {
2515  case PGRES_POLLING_OK:
2516  return 1; /* success! */
2517 
2518  case PGRES_POLLING_READING:
2519  ret = pqWaitTimed(1, 0, conn, finish_time);
2520  if (ret == -1)
2521  {
2522  /* hard failure, eg select() problem, aborts everything */
2524  return 0;
2525  }
2526  break;
2527 
2528  case PGRES_POLLING_WRITING:
2529  ret = pqWaitTimed(0, 1, conn, finish_time);
2530  if (ret == -1)
2531  {
2532  /* hard failure, eg select() problem, aborts everything */
2534  return 0;
2535  }
2536  break;
2537 
2538  default:
2539  /* Just in case we failed to set it in PQconnectPoll */
2541  return 0;
2542  }
2543 
2544  if (ret == 1) /* connect_timeout elapsed */
2545  {
2546  /*
2547  * Give up on current server/address, try the next one.
2548  */
2549  conn->try_next_addr = true;
2551  }
2552 
2553  /*
2554  * Now try to advance the state machine.
2555  */
2556  if (conn->cancelRequest)
2558  else
2559  flag = PQconnectPoll(conn);
2560  }
2561 }
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition: fe-cancel.c:207
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2591
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:7682
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:991
@ CONNECTION_NEEDED
Definition: libpq-fe.h:77
PostgresPollingStatusType
Definition: libpq-fe.h:89
@ PGRES_POLLING_OK
Definition: libpq-fe.h:93
@ PGRES_POLLING_READING
Definition: libpq-fe.h:91
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:92
int whichaddr
Definition: libpq-int.h:504
char * connect_timeout
Definition: libpq-int.h:378
bool try_next_addr
Definition: libpq-int.h:501
char * flag(int b)
Definition: test-ctype.c:33

References pg_conn::cancelRequest, conn, pg_conn::connect_timeout, CONNECTION_BAD, CONNECTION_NEEDED, flag(), PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQcancelPoll(), PQconnectPoll(), pqParseIntParam(), pqWaitTimed(), pg_conn::status, pg_conn::try_next_addr, pg_conn::whichaddr, and pg_conn::whichhost.

Referenced by internal_ping(), PQcancelBlocking(), PQconnectdb(), PQconnectdbParams(), PQreset(), and PQsetdbLogin().

◆ pqConnectDBStart()

int pqConnectDBStart ( PGconn conn)

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

2375 {
2376  if (!conn)
2377  return 0;
2378 
2379  if (!conn->options_valid)
2380  goto connect_errReturn;
2381 
2382  /*
2383  * Check for bad linking to backend-internal versions of src/common
2384  * functions (see comments in link-canary.c for the reason we need this).
2385  * Nobody but developers should see this message, so we don't bother
2386  * translating it.
2387  */
2389  {
2391  "libpq is incorrectly linked to backend functions\n");
2392  goto connect_errReturn;
2393  }
2394 
2395  /* Ensure our buffers are empty */
2396  conn->inStart = conn->inCursor = conn->inEnd = 0;
2397  conn->outCount = 0;
2398 
2399  /*
2400  * Set up to try to connect to the first host. (Setting whichhost = -1 is
2401  * a bit of a cheat, but PQconnectPoll will advance it to 0 before
2402  * anything else looks at it.)
2403  *
2404  * Cancel requests are special though, they should only try one host and
2405  * address, and these fields have already been set up in PQcancelCreate,
2406  * so leave these fields alone for cancel requests.
2407  */
2408  if (!conn->cancelRequest)
2409  {
2410  conn->whichhost = -1;
2411  conn->try_next_host = true;
2412  conn->try_next_addr = false;
2413  }
2414 
2416 
2417  /* Also reset the target_server_type state if needed */
2420 
2421  /*
2422  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
2423  * so that it can easily be re-executed if needed again during the
2424  * asynchronous startup process. However, we must run it once here,
2425  * because callers expect a success return from this routine to mean that
2426  * we are in PGRES_POLLING_WRITING connection state.
2427  */
2429  return 1;
2430 
2431 connect_errReturn:
2432 
2433  /*
2434  * If we managed to open a socket, close it immediately rather than
2435  * waiting till PQfinish. (The application cannot have gotten the socket
2436  * from PQsocket yet, so this doesn't risk breaking anything.)
2437  */
2438  pqDropConnection(conn, true);
2440  return 0;
2441 }
bool try_next_host
Definition: libpq-int.h:502
bool options_valid
Definition: libpq-int.h:442
PGTargetServerType target_server_type
Definition: libpq-int.h:498
int outCount
Definition: libpq-int.h:533

References appendPQExpBufferStr(), pg_conn::cancelRequest, conn, CONNECTION_BAD, CONNECTION_NEEDED, pg_conn::errorMessage, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, pg_conn::options_valid, pg_conn::outCount, pg_link_canary_is_frontend(), PGRES_POLLING_WRITING, PQconnectPoll(), pqDropConnection(), SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PREFER_STANDBY_PASS2, pg_conn::status, pg_conn::target_server_type, pg_conn::try_next_addr, pg_conn::try_next_host, and pg_conn::whichhost.

Referenced by PQcancelStart(), PQconnectStart(), PQconnectStartParams(), PQreset(), PQresetStart(), and PQsetdbLogin().

◆ pqConnectOptions2()

bool pqConnectOptions2 ( PGconn conn)

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

1121 {
1122  int i;
1123 
1124  /*
1125  * Allocate memory for details about each host to which we might possibly
1126  * try to connect. For that, count the number of elements in the hostaddr
1127  * or host options. If neither is given, assume one host.
1128  */
1129  conn->whichhost = 0;
1130  if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
1132  else if (conn->pghost && conn->pghost[0] != '\0')
1134  else
1135  conn->nconnhost = 1;
1136  conn->connhost = (pg_conn_host *)
1137  calloc(conn->nconnhost, sizeof(pg_conn_host));
1138  if (conn->connhost == NULL)
1139  goto oom_error;
1140 
1141  /*
1142  * We now have one pg_conn_host structure per possible host. Fill in the
1143  * host and hostaddr fields for each, by splitting the parameter strings.
1144  */
1145  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
1146  {
1147  char *s = conn->pghostaddr;
1148  bool more = true;
1149 
1150  for (i = 0; i < conn->nconnhost && more; i++)
1151  {
1153  if (conn->connhost[i].hostaddr == NULL)
1154  goto oom_error;
1155  }
1156 
1157  /*
1158  * If hostaddr was given, the array was allocated according to the
1159  * number of elements in the hostaddr list, so it really should be the
1160  * right size.
1161  */
1162  Assert(!more);
1163  Assert(i == conn->nconnhost);
1164  }
1165 
1166  if (conn->pghost != NULL && conn->pghost[0] != '\0')
1167  {
1168  char *s = conn->pghost;
1169  bool more = true;
1170 
1171  for (i = 0; i < conn->nconnhost && more; i++)
1172  {
1174  if (conn->connhost[i].host == NULL)
1175  goto oom_error;
1176  }
1177 
1178  /* Check for wrong number of host items. */
1179  if (more || i != conn->nconnhost)
1180  {
1182  libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
1184  return false;
1185  }
1186  }
1187 
1188  /*
1189  * Now, for each host slot, identify the type of address spec, and fill in
1190  * the default address if nothing was given.
1191  */
1192  for (i = 0; i < conn->nconnhost; i++)
1193  {
1194  pg_conn_host *ch = &conn->connhost[i];
1195 
1196  if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1197  ch->type = CHT_HOST_ADDRESS;
1198  else if (ch->host != NULL && ch->host[0] != '\0')
1199  {
1200  ch->type = CHT_HOST_NAME;
1201  if (is_unixsock_path(ch->host))
1202  ch->type = CHT_UNIX_SOCKET;
1203  }
1204  else
1205  {
1206  free(ch->host);
1207 
1208  /*
1209  * This bit selects the default host location. If you change
1210  * this, see also pg_regress.
1211  */
1212  if (DEFAULT_PGSOCKET_DIR[0])
1213  {
1214  ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1215  ch->type = CHT_UNIX_SOCKET;
1216  }
1217  else
1218  {
1219  ch->host = strdup(DefaultHost);
1220  ch->type = CHT_HOST_NAME;
1221  }
1222  if (ch->host == NULL)
1223  goto oom_error;
1224  }
1225  }
1226 
1227  /*
1228  * Next, work out the port number corresponding to each host name.
1229  *
1230  * Note: unlike the above for host names, this could leave the port fields
1231  * as null or empty strings. We will substitute DEF_PGPORT whenever we
1232  * read such a port field.
1233  */
1234  if (conn->pgport != NULL && conn->pgport[0] != '\0')
1235  {
1236  char *s = conn->pgport;
1237  bool more = true;
1238 
1239  for (i = 0; i < conn->nconnhost && more; i++)
1240  {
1242  if (conn->connhost[i].port == NULL)
1243  goto oom_error;
1244  }
1245 
1246  /*
1247  * If exactly one port was given, use it for every host. Otherwise,
1248  * there must be exactly as many ports as there were hosts.
1249  */
1250  if (i == 1 && !more)
1251  {
1252  for (i = 1; i < conn->nconnhost; i++)
1253  {
1254  conn->connhost[i].port = strdup(conn->connhost[0].port);
1255  if (conn->connhost[i].port == NULL)
1256  goto oom_error;
1257  }
1258  }
1259  else if (more || i != conn->nconnhost)
1260  {
1262  libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
1264  return false;
1265  }
1266  }
1267 
1268  /*
1269  * If user name was not given, fetch it. (Most likely, the fetch will
1270  * fail, since the only way we get here is if pg_fe_getauthname() failed
1271  * during conninfo_add_defaults(). But now we want an error message.)
1272  */
1273  if (conn->pguser == NULL || conn->pguser[0] == '\0')
1274  {
1275  free(conn->pguser);
1277  if (!conn->pguser)
1278  {
1280  return false;
1281  }
1282  }
1283 
1284  /*
1285  * If database name was not given, default it to equal user name
1286  */
1287  if (conn->dbName == NULL || conn->dbName[0] == '\0')
1288  {
1289  free(conn->dbName);
1290  conn->dbName = strdup(conn->pguser);
1291  if (!conn->dbName)
1292  goto oom_error;
1293  }
1294 
1295  /*
1296  * If password was not given, try to look it up in password file. Note
1297  * that the result might be different for each host/port pair.
1298  */
1299  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1300  {
1301  /* If password file wasn't specified, use ~/PGPASSFILE */
1302  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1303  {
1304  char homedir[MAXPGPATH];
1305 
1306  if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1307  {
1308  free(conn->pgpassfile);
1310  if (!conn->pgpassfile)
1311  goto oom_error;
1312  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1313  homedir, PGPASSFILE);
1314  }
1315  }
1316 
1317  if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1318  {
1319  for (i = 0; i < conn->nconnhost; i++)
1320  {
1321  /*
1322  * Try to get a password for this host from file. We use host
1323  * for the hostname search key if given, else hostaddr (at
1324  * least one of them is guaranteed nonempty by now).
1325  */
1326  const char *pwhost = conn->connhost[i].host;
1327 
1328  if (pwhost == NULL || pwhost[0] == '\0')
1329  pwhost = conn->connhost[i].hostaddr;
1330 
1331  conn->connhost[i].password =
1332  passwordFromFile(pwhost,
1333  conn->connhost[i].port,
1334  conn->dbName,
1335  conn->pguser,
1336  conn->pgpassfile);
1337  }
1338  }
1339  }
1340 
1341  /*
1342  * parse and validate require_auth option
1343  */
1344  if (conn->require_auth && conn->require_auth[0])
1345  {
1346  char *s = conn->require_auth;
1347  bool first,
1348  more;
1349  bool negated = false;
1350 
1351  /*
1352  * By default, start from an empty set of allowed options and add to
1353  * it.
1354  */
1355  conn->auth_required = true;
1357 
1358  for (first = true, more = true; more; first = false)
1359  {
1360  char *method,
1361  *part;
1362  uint32 bits;
1363 
1364  part = parse_comma_separated_list(&s, &more);
1365  if (part == NULL)
1366  goto oom_error;
1367 
1368  /*
1369  * Check for negation, e.g. '!password'. If one element is
1370  * negated, they all have to be.
1371  */
1372  method = part;
1373  if (*method == '!')
1374  {
1375  if (first)
1376  {
1377  /*
1378  * Switch to a permissive set of allowed options, and
1379  * subtract from it.
1380  */
1381  conn->auth_required = false;
1382  conn->allowed_auth_methods = -1;
1383  }
1384  else if (!negated)
1385  {
1387  libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
1388  method);
1389 
1390  free(part);
1391  return false;
1392  }
1393 
1394  negated = true;
1395  method++;
1396  }
1397  else if (negated)
1398  {
1400  libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
1401  method);
1402 
1403  free(part);
1404  return false;
1405  }
1406 
1407  if (strcmp(method, "password") == 0)
1408  {
1409  bits = (1 << AUTH_REQ_PASSWORD);
1410  }
1411  else if (strcmp(method, "md5") == 0)
1412  {
1413  bits = (1 << AUTH_REQ_MD5);
1414  }
1415  else if (strcmp(method, "gss") == 0)
1416  {
1417  bits = (1 << AUTH_REQ_GSS);
1418  bits |= (1 << AUTH_REQ_GSS_CONT);
1419  }
1420  else if (strcmp(method, "sspi") == 0)
1421  {
1422  bits = (1 << AUTH_REQ_SSPI);
1423  bits |= (1 << AUTH_REQ_GSS_CONT);
1424  }
1425  else if (strcmp(method, "scram-sha-256") == 0)
1426  {
1427  /* This currently assumes that SCRAM is the only SASL method. */
1428  bits = (1 << AUTH_REQ_SASL);
1429  bits |= (1 << AUTH_REQ_SASL_CONT);
1430  bits |= (1 << AUTH_REQ_SASL_FIN);
1431  }
1432  else if (strcmp(method, "none") == 0)
1433  {
1434  /*
1435  * Special case: let the user explicitly allow (or disallow)
1436  * connections where the server does not send an explicit
1437  * authentication challenge, such as "trust" and "cert" auth.
1438  */
1439  if (negated) /* "!none" */
1440  {
1441  if (conn->auth_required)
1442  goto duplicate;
1443 
1444  conn->auth_required = true;
1445  }
1446  else /* "none" */
1447  {
1448  if (!conn->auth_required)
1449  goto duplicate;
1450 
1451  conn->auth_required = false;
1452  }
1453 
1454  free(part);
1455  continue; /* avoid the bitmask manipulation below */
1456  }
1457  else
1458  {
1460  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1461  "require_auth", method);
1462 
1463  free(part);
1464  return false;
1465  }
1466 
1467  /* Update the bitmask. */
1468  if (negated)
1469  {
1470  if ((conn->allowed_auth_methods & bits) == 0)
1471  goto duplicate;
1472 
1473  conn->allowed_auth_methods &= ~bits;
1474  }
1475  else
1476  {
1477  if ((conn->allowed_auth_methods & bits) == bits)
1478  goto duplicate;
1479 
1480  conn->allowed_auth_methods |= bits;
1481  }
1482 
1483  free(part);
1484  continue;
1485 
1486  duplicate:
1487 
1488  /*
1489  * A duplicated method probably indicates a typo in a setting
1490  * where typos are extremely risky.
1491  */
1493  libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
1494  part);
1495 
1496  free(part);
1497  return false;
1498  }
1499  }
1500 
1501  /*
1502  * validate channel_binding option
1503  */
1504  if (conn->channel_binding)
1505  {
1506  if (strcmp(conn->channel_binding, "disable") != 0
1507  && strcmp(conn->channel_binding, "prefer") != 0
1508  && strcmp(conn->channel_binding, "require") != 0)
1509  {
1511  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1512  "channel_binding", conn->channel_binding);
1513  return false;
1514  }
1515  }
1516  else
1517  {
1519  if (!conn->channel_binding)
1520  goto oom_error;
1521  }
1522 
1523 #ifndef USE_SSL
1524 
1525  /*
1526  * sslrootcert=system is not supported. Since setting this changes the
1527  * default sslmode, check this _before_ we validate sslmode, to avoid
1528  * confusing the user with errors for an option they may not have set.
1529  */
1530  if (conn->sslrootcert
1531  && strcmp(conn->sslrootcert, "system") == 0)
1532  {
1534  libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1535  "sslrootcert", conn->sslrootcert);
1536  return false;
1537  }
1538 #endif
1539 
1540  /*
1541  * validate sslmode option
1542  */
1543  if (conn->sslmode)
1544  {
1545  if (strcmp(conn->sslmode, "disable") != 0
1546  && strcmp(conn->sslmode, "allow") != 0
1547  && strcmp(conn->sslmode, "prefer") != 0
1548  && strcmp(conn->sslmode, "require") != 0
1549  && strcmp(conn->sslmode, "verify-ca") != 0
1550  && strcmp(conn->sslmode, "verify-full") != 0)
1551  {
1553  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1554  "sslmode", conn->sslmode);
1555  return false;
1556  }
1557 
1558 #ifndef USE_SSL
1559  switch (conn->sslmode[0])
1560  {
1561  case 'a': /* "allow" */
1562  case 'p': /* "prefer" */
1563 
1564  /*
1565  * warn user that an SSL connection will never be negotiated
1566  * since SSL was not compiled in?
1567  */
1568  break;
1569 
1570  case 'r': /* "require" */
1571  case 'v': /* "verify-ca" or "verify-full" */
1573  libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1574  "sslmode", conn->sslmode);
1575  return false;
1576  }
1577 #endif
1578  }
1579  else
1580  {
1581  conn->sslmode = strdup(DefaultSSLMode);
1582  if (!conn->sslmode)
1583  goto oom_error;
1584  }
1585 
1586  /*
1587  * validate sslnegotiation option, default is "postgres" for the postgres
1588  * style negotiated connection with an extra round trip but more options.
1589  */
1590  if (conn->sslnegotiation)
1591  {
1592  if (strcmp(conn->sslnegotiation, "postgres") != 0
1593  && strcmp(conn->sslnegotiation, "direct") != 0
1594  && strcmp(conn->sslnegotiation, "requiredirect") != 0)
1595  {
1597  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1598  "sslnegotiation", conn->sslnegotiation);
1599  return false;
1600  }
1601 
1602 #ifndef USE_SSL
1603  if (conn->sslnegotiation[0] != 'p')
1604  {
1606  libpq_append_conn_error(conn, "sslnegotiation value \"%s\" invalid when SSL support is not compiled in",
1607  conn->sslnegotiation);
1608  return false;
1609  }
1610 #endif
1611  }
1612  else
1613  {
1615  if (!conn->sslnegotiation)
1616  goto oom_error;
1617  }
1618 
1619 #ifdef USE_SSL
1620 
1621  /*
1622  * If sslrootcert=system, make sure our chosen sslmode is compatible.
1623  */
1624  if (conn->sslrootcert
1625  && strcmp(conn->sslrootcert, "system") == 0
1626  && strcmp(conn->sslmode, "verify-full") != 0)
1627  {
1629  libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")",
1630  conn->sslmode);
1631  return false;
1632  }
1633 #endif
1634 
1635  /*
1636  * Validate TLS protocol versions for ssl_min_protocol_version and
1637  * ssl_max_protocol_version.
1638  */
1640  {
1642  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1643  "ssl_min_protocol_version",
1645  return false;
1646  }
1648  {
1650  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1651  "ssl_max_protocol_version",
1653  return false;
1654  }
1655 
1656  /*
1657  * Check if the range of SSL protocols defined is correct. This is done
1658  * at this early step because this is independent of the SSL
1659  * implementation used, and this avoids unnecessary cycles with an
1660  * already-built SSL context when the connection is being established, as
1661  * it would be doomed anyway.
1662  */
1665  {
1667  libpq_append_conn_error(conn, "invalid SSL protocol version range");
1668  return false;
1669  }
1670 
1671  /*
1672  * validate sslcertmode option
1673  */
1674  if (conn->sslcertmode)
1675  {
1676  if (strcmp(conn->sslcertmode, "disable") != 0 &&
1677  strcmp(conn->sslcertmode, "allow") != 0 &&
1678  strcmp(conn->sslcertmode, "require") != 0)
1679  {
1681  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1682  "sslcertmode", conn->sslcertmode);
1683  return false;
1684  }
1685 #ifndef USE_SSL
1686  if (strcmp(conn->sslcertmode, "require") == 0)
1687  {
1689  libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1690  "sslcertmode", conn->sslcertmode);
1691  return false;
1692  }
1693 #endif
1694 #ifndef HAVE_SSL_CTX_SET_CERT_CB
1695 
1696  /*
1697  * Without a certificate callback, the current implementation can't
1698  * figure out if a certificate was actually requested, so "require" is
1699  * useless.
1700  */
1701  if (strcmp(conn->sslcertmode, "require") == 0)
1702  {
1704  libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
1705  "sslcertmode", conn->sslcertmode);
1706  return false;
1707  }
1708 #endif
1709  }
1710  else
1711  {
1712  conn->sslcertmode = strdup(DefaultSSLCertMode);
1713  if (!conn->sslcertmode)
1714  goto oom_error;
1715  }
1716 
1717  /*
1718  * validate gssencmode option
1719  */
1720  if (conn->gssencmode)
1721  {
1722  if (strcmp(conn->gssencmode, "disable") != 0 &&
1723  strcmp(conn->gssencmode, "prefer") != 0 &&
1724  strcmp(conn->gssencmode, "require") != 0)
1725  {
1727  libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
1728  return false;
1729  }
1730 #ifndef ENABLE_GSS
1731  if (strcmp(conn->gssencmode, "require") == 0)
1732  {
1734  libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
1735  conn->gssencmode);
1736  return false;
1737  }
1738 #endif
1739  }
1740  else
1741  {
1742  conn->gssencmode = strdup(DefaultGSSMode);
1743  if (!conn->gssencmode)
1744  goto oom_error;
1745  }
1746 
1747  /*
1748  * validate target_session_attrs option, and set target_server_type
1749  */
1751  {
1752  if (strcmp(conn->target_session_attrs, "any") == 0)
1754  else if (strcmp(conn->target_session_attrs, "read-write") == 0)
1756  else if (strcmp(conn->target_session_attrs, "read-only") == 0)
1758  else if (strcmp(conn->target_session_attrs, "primary") == 0)
1760  else if (strcmp(conn->target_session_attrs, "standby") == 0)
1762  else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
1764  else
1765  {
1767  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1768  "target_session_attrs",
1770  return false;
1771  }
1772  }
1773  else
1775 
1776  /*
1777  * validate load_balance_hosts option, and set load_balance_type
1778  */
1779  if (conn->load_balance_hosts)
1780  {
1781  if (strcmp(conn->load_balance_hosts, "disable") == 0)
1783  else if (strcmp(conn->load_balance_hosts, "random") == 0)
1785  else
1786  {
1788  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1789  "load_balance_hosts",
1791  return false;
1792  }
1793  }
1794  else
1796 
1798  {
1800 
1801  /*
1802  * This is the "inside-out" variant of the Fisher-Yates shuffle
1803  * algorithm. Notionally, we append each new value to the array and
1804  * then swap it with a randomly-chosen array element (possibly
1805  * including itself, else we fail to generate permutations with the
1806  * last integer last). The swap step can be optimized by combining it
1807  * with the insertion.
1808  */
1809  for (i = 1; i < conn->nconnhost; i++)
1810  {
1811  int j = pg_prng_uint64_range(&conn->prng_state, 0, i);
1812  pg_conn_host temp = conn->connhost[j];
1813 
1814  conn->connhost[j] = conn->connhost[i];
1815  conn->connhost[i] = temp;
1816  }
1817  }
1818 
1819  /*
1820  * Resolve special "auto" client_encoding from the locale
1821  */
1823  strcmp(conn->client_encoding_initial, "auto") == 0)
1824  {
1828  goto oom_error;
1829  }
1830 
1831  /*
1832  * Only if we get this far is it appropriate to try to connect. (We need a
1833  * state flag, rather than just the boolean result of this function, in
1834  * case someone tries to PQreset() the PGconn.)
1835  */
1836  conn->options_valid = true;
1837 
1838  return true;
1839 
1840 oom_error:
1842  libpq_append_conn_error(conn, "out of memory");
1843  return false;
1844 }
unsigned int uint32
Definition: c.h:506
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1213
#define DefaultHost
Definition: fe-connect.c:116
static char * passwordFromFile(const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile)
Definition: fe-connect.c:7413
static bool sslVerifyProtocolRange(const char *min, const char *max)
Definition: fe-connect.c:7602
static void libpq_prng_init(PGconn *conn)
Definition: fe-connect.c:1093
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:7655
#define DefaultSSLMode
Definition: fe-connect.c:129
#define DefaultGSSMode
Definition: fe-connect.c:137
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:1034
#define DefaultChannelBinding
Definition: fe-connect.c:121
static bool sslVerifyProtocolVersion(const char *version)
Definition: fe-connect.c:7576
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:1058
#define DefaultSSLNegotiation
Definition: fe-connect.c:132
#define PGPASSFILE
Definition: fe-connect.c:75
#define DefaultSSLCertMode
Definition: fe-connect.c:130
#define calloc(a, b)
Definition: header.h:55
int j
Definition: isn.c:74
#define MAXPGPATH
#define DEFAULT_PGSOCKET_DIR
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
#define pg_encoding_to_char
Definition: pg_wchar.h:630
#define snprintf
Definition: port.h:238
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:428
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:67
#define AUTH_REQ_SSPI
Definition: protocol.h:79
#define AUTH_REQ_SASL_CONT
Definition: protocol.h:81
#define AUTH_REQ_GSS
Definition: protocol.h:77
#define AUTH_REQ_MD5
Definition: protocol.h:75
#define AUTH_REQ_PASSWORD
Definition: protocol.h:73
#define AUTH_REQ_GSS_CONT
Definition: protocol.h:78
#define AUTH_REQ_SASL
Definition: protocol.h:80
#define AUTH_REQ_SASL_FIN
Definition: protocol.h:82
char * password
Definition: libpq-int.h:356
char * port
Definition: libpq-int.h:355
char * hostaddr
Definition: libpq-int.h:354
pg_conn_host_type type
Definition: libpq-int.h:352
char * sslrootcert
Definition: libpq-int.h:405
char * sslnegotiation
Definition: libpq-int.h:398
int nconnhost
Definition: libpq-int.h:456
char * require_auth
Definition: libpq-int.h:418
char * channel_binding
Definition: libpq-int.h:389
char * pghost
Definition: libpq-int.h:368
char * ssl_max_protocol_version
Definition: libpq-int.h:416
char * pgpass
Definition: libpq-int.h:387
char * dbName
Definition: libpq-int.h:384
char * sslcertmode
Definition: libpq-int.h:404
uint32 allowed_auth_methods
Definition: libpq-int.h:491
char * target_session_attrs
Definition: libpq-int.h:417
bool auth_required
Definition: libpq-int.h:489
char * load_balance_hosts
Definition: libpq-int.h:419
char * pguser
Definition: libpq-int.h:386
char * client_encoding_initial
Definition: libpq-int.h:380
char * sslmode
Definition: libpq-int.h:397
pg_prng_state prng_state
Definition: libpq-int.h:520
char * ssl_min_protocol_version
Definition: libpq-int.h:415
char * gssencmode
Definition: libpq-int.h:410
char * pghostaddr
Definition: libpq-int.h:372
char * pgpassfile
Definition: libpq-int.h:388
PGLoadBalanceType load_balance_type
Definition: libpq-int.h:499
char * pgport
Definition: libpq-int.h:376

References pg_conn::allowed_auth_methods, Assert, AUTH_REQ_GSS, AUTH_REQ_GSS_CONT, AUTH_REQ_MD5, AUTH_REQ_PASSWORD, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SSPI, pg_conn::auth_required, calloc, pg_conn::channel_binding, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, pg_conn::client_encoding_initial, conn, CONNECTION_BAD, pg_conn::connhost, count_comma_separated_elems(), pg_conn::dbName, DEFAULT_PGSOCKET_DIR, DefaultChannelBinding, DefaultGSSMode, DefaultHost, DefaultSSLCertMode, DefaultSSLMode, DefaultSSLNegotiation, pg_conn::errorMessage, free, pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, is_unixsock_path(), j, libpq_append_conn_error(), libpq_prng_init(), LOAD_BALANCE_DISABLE, pg_conn::load_balance_hosts, LOAD_BALANCE_RANDOM, pg_conn::load_balance_type, malloc, MAXPGPATH, pg_conn::nconnhost, pg_conn::options_valid, parse_comma_separated_list(), pg_conn_host::password, passwordFromFile(), pg_encoding_to_char, pg_fe_getauthname(), pg_get_encoding_from_locale(), pg_prng_uint64_range(), pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgpass, PGPASSFILE, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pguser, pg_conn_host::port, pqGetHomeDirectory(), pg_conn::prng_state, pg_conn::require_auth, SERVER_TYPE_ANY, SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PRIMARY, SERVER_TYPE_READ_ONLY, SERVER_TYPE_READ_WRITE, SERVER_TYPE_STANDBY, snprintf, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, pg_conn::sslcertmode, pg_conn::sslmode, pg_conn::sslnegotiation, pg_conn::sslrootcert, sslVerifyProtocolRange(), sslVerifyProtocolVersion(), pg_conn::status, pg_conn::target_server_type, pg_conn::target_session_attrs, pg_conn_host::type, and pg_conn::whichhost.

Referenced by PQcancelCreate(), PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ pqCopyPGconn()

bool pqCopyPGconn ( PGconn srcConn,
PGconn dstConn 
)

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

957 {
959 
960  /* copy over connection options */
961  for (option = PQconninfoOptions; option->keyword; option++)
962  {
963  if (option->connofs >= 0)
964  {
965  const char **tmp = (const char **) ((char *) srcConn + option->connofs);
966 
967  if (*tmp)
968  {
969  char **dstConnmember = (char **) ((char *) dstConn + option->connofs);
970 
971  if (*dstConnmember)
972  free(*dstConnmember);
973  *dstConnmember = strdup(*tmp);
974  if (*dstConnmember == NULL)
975  {
976  libpq_append_conn_error(dstConn, "out of memory");
977  return false;
978  }
979  }
980  }
981  }
982  return true;
983 }
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:190

References free, libpq_append_conn_error(), and PQconninfoOptions.

Referenced by PQcancelCreate().

◆ pqDropConnection()

void pqDropConnection ( PGconn conn,
bool  flushInput 
)

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

472 {
473  /* Drop any SSL state */
475 
476  /* Close the socket itself */
477  if (conn->sock != PGINVALID_SOCKET)
480 
481  /* Optionally discard any unread data */
482  if (flushInput)
483  conn->inStart = conn->inCursor = conn->inEnd = 0;
484 
485  /* Always discard any unsent data */
486  conn->outCount = 0;
487 
488  /* Likewise, discard any pending pipelined commands */
492  conn->cmd_queue_recycle = NULL;
493 
494  /* Free authentication/encryption state */
495 #ifdef ENABLE_GSS
496  {
497  OM_uint32 min_s;
498 
499  if (conn->gcred != GSS_C_NO_CREDENTIAL)
500  {
501  gss_release_cred(&min_s, &conn->gcred);
502  conn->gcred = GSS_C_NO_CREDENTIAL;
503  }
504  if (conn->gctx)
505  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
506  if (conn->gtarg_nam)
507  gss_release_name(&min_s, &conn->gtarg_nam);
508  if (conn->gss_SendBuffer)
509  {
510  free(conn->gss_SendBuffer);
511  conn->gss_SendBuffer = NULL;
512  }
513  if (conn->gss_RecvBuffer)
514  {
515  free(conn->gss_RecvBuffer);
516  conn->gss_RecvBuffer = NULL;
517  }
518  if (conn->gss_ResultBuffer)
519  {
520  free(conn->gss_ResultBuffer);
521  conn->gss_ResultBuffer = NULL;
522  }
523  conn->gssenc = false;
524  }
525 #endif
526 #ifdef ENABLE_SSPI
527  if (conn->sspitarget)
528  {
529  free(conn->sspitarget);
530  conn->sspitarget = NULL;
531  }
532  if (conn->sspicred)
533  {
534  FreeCredentialsHandle(conn->sspicred);
535  free(conn->sspicred);
536  conn->sspicred = NULL;
537  }
538  if (conn->sspictx)
539  {
540  DeleteSecurityContext(conn->sspictx);
541  free(conn->sspictx);
542  conn->sspictx = NULL;
543  }
544  conn->usesspi = 0;
545 #endif
546  if (conn->sasl_state)
547  {
549  conn->sasl_state = NULL;
550  }
551 }
static void pqFreeCommandQueue(PGcmdQueueEntry *queue)
Definition: fe-connect.c:558
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:167
#define PGINVALID_SOCKET
Definition: port.h:31
#define closesocket
Definition: port.h:349
pgsocket sock
Definition: libpq-int.h:475
const pg_fe_sasl_mech * sasl
Definition: libpq-int.h:559
PGcmdQueueEntry * cmd_queue_recycle
Definition: libpq-int.h:472
void * sasl_state
Definition: libpq-int.h:560
void(* free)(void *state)
Definition: fe-auth-sasl.h:140

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

Referenced by handleSyncLoss(), pqClosePGconn(), pqConnectDBStart(), PQconnectPoll(), and pqReadData().

◆ pqEndcopy3()

int pqEndcopy3 ( PGconn conn)

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

1917 {
1918  PGresult *result;
1919 
1920  if (conn->asyncStatus != PGASYNC_COPY_IN &&
1923  {
1924  libpq_append_conn_error(conn, "no COPY in progress");
1925  return 1;
1926  }
1927 
1928  /* Send the CopyDone message if needed */
1929  if (conn->asyncStatus == PGASYNC_COPY_IN ||
1931  {
1932  if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
1933  pqPutMsgEnd(conn) < 0)
1934  return 1;
1935 
1936  /*
1937  * If we sent the COPY command in extended-query mode, we must issue a
1938  * Sync as well.
1939  */
1940  if (conn->cmd_queue_head &&
1942  {
1943  if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
1944  pqPutMsgEnd(conn) < 0)
1945  return 1;
1946  }
1947  }
1948 
1949  /*
1950  * make sure no data is waiting to be sent, abort if we are non-blocking
1951  * and the flush fails
1952  */
1953  if (pqFlush(conn) && pqIsnonblocking(conn))
1954  return 1;
1955 
1956  /* Return to active duty */
1958 
1959  /*
1960  * Non blocking connections may have to abort at this point. If everyone
1961  * played the game there should be no problem, but in error scenarios the
1962  * expected messages may not have arrived yet. (We are assuming that the
1963  * backend's packetizing will ensure that CommandComplete arrives along
1964  * with the CopyDone; are there corner cases where that doesn't happen?)
1965  */
1966  if (pqIsnonblocking(conn) && PQisBusy(conn))
1967  return 1;
1968 
1969  /* Wait for the completion response */
1970  result = PQgetResult(conn);
1971 
1972  /* Expecting a successful result */
1973  if (result && result->resultStatus == PGRES_COMMAND_OK)
1974  {
1975  PQclear(result);
1976  return 0;
1977  }
1978 
1979  /*
1980  * Trouble. For backwards-compatibility reasons, we issue the error
1981  * message as if it were a notice (would be nice to get rid of this
1982  * silliness, but too many apps probably don't handle errors from
1983  * PQendcopy reasonably). Note that the app can still obtain the error
1984  * status from the PGconn object.
1985  */
1986  if (conn->errorMessage.len > 0)
1987  {
1988  /* We have to strip the trailing newline ... pain in neck... */
1989  char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1990 
1991  if (svLast == '\n')
1992  conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1994  conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1995  }
1996 
1997  PQclear(result);
1998 
1999  return 1;
2000 }
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:938
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2031
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
int pqFlush(PGconn *conn)
Definition: fe-misc.c:953
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:458
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:517
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:100
#define pqIsnonblocking(conn)
Definition: libpq-int.h:902
#define PqMsg_CopyDone
Definition: protocol.h:64
#define PqMsg_Sync
Definition: protocol.h:27
PGNoticeHooks noticeHooks
Definition: libpq-int.h:430

References pg_conn::asyncStatus, pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_conn::errorMessage, PQExpBufferData::len, libpq_append_conn_error(), 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, PqMsg_CopyDone, PqMsg_Sync, pqPutMsgEnd(), pqPutMsgStart(), PGcmdQueueEntry::queryclass, and pg_result::resultStatus.

Referenced by PQendcopy().

◆ pqFlush()

int pqFlush ( PGconn conn)

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

954 {
955  if (conn->outCount > 0)
956  {
957  if (conn->Pfdebug)
958  fflush(conn->Pfdebug);
959 
960  return pqSendSome(conn, conn->outCount);
961  }
962 
963  return 0;
964 }
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:784
static void const char fflush(stdout)
FILE * Pfdebug
Definition: libpq-int.h:426

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

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

◆ 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 2009 of file fe-protocol3.c.

2013 {
2014  bool needInput = false;
2016  char id;
2017  int msgLength;
2018  int avail;
2019  int i;
2020 
2021  /* already validated by PQfn */
2023 
2024  /* PQfn already validated connection state */
2025 
2027  pqPutInt(fnid, 4, conn) < 0 || /* function id */
2028  pqPutInt(1, 2, conn) < 0 || /* # of format codes */
2029  pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
2030  pqPutInt(nargs, 2, conn) < 0) /* # of args */
2031  {
2032  /* error message should be set up already */
2033  return NULL;
2034  }
2035 
2036  for (i = 0; i < nargs; ++i)
2037  { /* len.int4 + contents */
2038  if (pqPutInt(args[i].len, 4, conn))
2039  return NULL;
2040  if (args[i].len == -1)
2041  continue; /* it's NULL */
2042 
2043  if (args[i].isint)
2044  {
2045  if (pqPutInt(args[i].u.integer, args[i].len, conn))
2046  return NULL;
2047  }
2048  else
2049  {
2050  if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
2051  return NULL;
2052  }
2053  }
2054 
2055  if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
2056  return NULL;
2057 
2058  if (pqPutMsgEnd(conn) < 0 ||
2059  pqFlush(conn))
2060  return NULL;
2061 
2062  for (;;)
2063  {
2064  if (needInput)
2065  {
2066  /* Wait for some data to arrive (or for the channel to close) */
2067  if (pqWait(true, false, conn) ||
2068  pqReadData(conn) < 0)
2069  break;
2070  }
2071 
2072  /*
2073  * Scan the message. If we run out of data, loop around to try again.
2074  */
2075  needInput = true;
2076 
2077  conn->inCursor = conn->inStart;
2078  if (pqGetc(&id, conn))
2079  continue;
2080  if (pqGetInt(&msgLength, 4, conn))
2081  continue;
2082 
2083  /*
2084  * Try to validate message type/length here. A length less than 4 is
2085  * definitely broken. Large lengths should only be believed for a few
2086  * message types.
2087  */
2088  if (msgLength < 4)
2089  {
2090  handleSyncLoss(conn, id, msgLength);
2091  break;
2092  }
2093  if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
2094  {
2095  handleSyncLoss(conn, id, msgLength);
2096  break;
2097  }
2098 
2099  /*
2100  * Can't process if message body isn't all here yet.
2101  */
2102  msgLength -= 4;
2103  avail = conn->inEnd - conn->inCursor;
2104  if (avail < msgLength)
2105  {
2106  /*
2107  * Before looping, enlarge the input buffer if needed to hold the
2108  * whole message. See notes in parseInput.
2109  */
2110  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2111  conn))
2112  {
2113  /*
2114  * XXX add some better recovery code... plan is to skip over
2115  * the message using its length, then report an error. For the
2116  * moment, just treat this like loss of sync (which indeed it
2117  * might be!)
2118  */
2119  handleSyncLoss(conn, id, msgLength);
2120  break;
2121  }
2122  continue;
2123  }
2124 
2125  /*
2126  * We should see V or E response to the command, but might get N
2127  * and/or A notices first. We also need to swallow the final Z before
2128  * returning.
2129  */
2130  switch (id)
2131  {
2132  case 'V': /* function result */
2133  if (pqGetInt(actual_result_len, 4, conn))
2134  continue;
2135  if (*actual_result_len != -1)
2136  {
2137  if (result_is_int)
2138  {
2139  if (pqGetInt(result_buf, *actual_result_len, conn))
2140  continue;
2141  }
2142  else
2143  {
2144  if (pqGetnchar((char *) result_buf,
2145  *actual_result_len,
2146  conn))
2147  continue;
2148  }
2149  }
2150  /* correctly finished function result message */
2151  status = PGRES_COMMAND_OK;
2152  break;
2153  case 'E': /* error return */
2154  if (pqGetErrorNotice3(conn, true))
2155  continue;
2156  status = PGRES_FATAL_ERROR;
2157  break;
2158  case 'A': /* notify message */
2159  /* handle notify and go back to processing return values */
2160  if (getNotify(conn))
2161  continue;
2162  break;
2163  case 'N': /* notice */
2164  /* handle notice and go back to processing return values */
2165  if (pqGetErrorNotice3(conn, false))
2166  continue;
2167  break;
2168  case 'Z': /* backend is ready for new query */
2169  if (getReadyForQuery(conn))
2170  continue;
2171  /* consume the message and exit */
2172  conn->inStart += 5 + msgLength;
2173 
2174  /*
2175  * If we already have a result object (probably an error), use
2176  * that. Otherwise, if we saw a function result message,
2177  * report COMMAND_OK. Otherwise, the backend violated the
2178  * protocol, so complain.
2179  */
2180  if (!pgHavePendingResult(conn))
2181  {
2182  if (status == PGRES_COMMAND_OK)
2183  {
2184  conn->result = PQmakeEmptyPGresult(conn, status);
2185  if (!conn->result)
2186  {
2187  libpq_append_conn_error(conn, "out of memory");
2189  }
2190  }
2191  else
2192  {
2193  libpq_append_conn_error(conn, "protocol error: no function result");
2195  }
2196  }
2197  return pqPrepareAsyncResult(conn);
2198  case 'S': /* parameter status */
2199  if (getParameterStatus(conn))
2200  continue;
2201  break;
2202  default:
2203  /* The backend violates the protocol. */
2204  libpq_append_conn_error(conn, "protocol error: id=0x%x", id);
2206  /* trust the specified message length as what to skip */
2207  conn->inStart += 5 + msgLength;
2208  return pqPrepareAsyncResult(conn);
2209  }
2210 
2211  /* trace server-to-client message */
2212  if (conn->Pfdebug)
2214 
2215  /* Completed this message, keep going */
2216  /* trust the specified message length as what to skip */
2217  conn->inStart += 5 + msgLength;
2218  needInput = false;
2219  }
2220 
2221  /*
2222  * We fall out of the loop only upon failing to read data.
2223  * conn->errorMessage has been set by pqWait or pqReadData. We want to
2224  * append it to any already-received error message.
2225  */
2227  return pqPrepareAsyncResult(conn);
2228 }
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:803
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:159
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:851
int pqReadData(PGconn *conn)
Definition: fe-misc.c:565
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:253
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:77
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:216
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:165
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:978
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:351
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:202
static int getNotify(PGconn *conn)
static int getParameterStatus(PGconn *conn)
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:36
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:483
static int getReadyForQuery(PGconn *conn)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:882
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:529
ExecStatusType
Definition: libpq-fe.h:98
#define pgHavePendingResult(conn)
Definition: libpq-int.h:895
#define PqMsg_FunctionCall
Definition: protocol.h:23

References generate_unaccent_rules::args, Assert, conn, getNotify(), getParameterStatus(), getReadyForQuery(), handleSyncLoss(), i, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, len, libpq_append_conn_error(), pg_conn::Pfdebug, pgHavePendingResult, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), PQmakeEmptyPGresult(), PqMsg_FunctionCall, pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), pqTraceOutputMessage(), pqWait(), pg_conn::result, and VALID_LONG_MESSAGE_TYPE.

Referenced by PQfn().

◆ pqGetc()

int pqGetc ( char *  result,
PGconn conn 
)

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

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

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

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

◆ pqGetCopyData3()

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

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

1752 {
1753  int msgLength;
1754 
1755  for (;;)
1756  {
1757  /*
1758  * Collect the next input message. To make life simpler for async
1759  * callers, we keep returning 0 until the next message is fully
1760  * available, even if it is not Copy Data.
1761  */
1762  msgLength = getCopyDataMessage(conn);
1763  if (msgLength < 0)
1764  return msgLength; /* end-of-copy or error */
1765  if (msgLength == 0)
1766  {
1767  /* Don't block if async read requested */
1768  if (async)
1769  return 0;
1770  /* Need to load more data */
1771  if (pqWait(true, false, conn) ||
1772  pqReadData(conn) < 0)
1773  return -2;
1774  continue;
1775  }
1776 
1777  /*
1778  * Drop zero-length messages (shouldn't happen anyway). Otherwise
1779  * pass the data back to the caller.
1780  */
1781  msgLength -= 4;
1782  if (msgLength > 0)
1783  {
1784  *buffer = (char *) malloc(msgLength + 1);
1785  if (*buffer == NULL)
1786  {
1787  libpq_append_conn_error(conn, "out of memory");
1788  return -2;
1789  }
1790  memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1791  (*buffer)[msgLength] = '\0'; /* Add terminating null */
1792 
1793  /* Mark message consumed */
1794  conn->inStart = conn->inCursor + msgLength;
1795 
1796  return msgLength;
1797  }
1798 
1799  /* Empty, so drop it and loop around for another */
1800  conn->inStart = conn->inCursor;
1801  }
1802 }
static int getCopyDataMessage(PGconn *conn)

References conn, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, libpq_append_conn_error(), malloc, pqReadData(), and pqWait().

Referenced by PQgetCopyData().

◆ pqGetErrorNotice3()

int pqGetErrorNotice3 ( PGconn conn,
bool  isError 
)

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

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

References appendPQExpBufferStr(), pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_result::errMsg, pg_conn::error_result, pg_conn::errorMessage, pg_result::errQuery, initPQExpBuffer(), pg_conn::last_sqlstate, libpq_append_conn_error(), 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, res, resetPQExpBuffer(), pg_conn::result, pg_result::resultStatus, pg_conn::show_context, strlcpy(), termPQExpBuffer(), and pg_conn::verbosity.

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

◆ pqGetHomeDirectory()

bool pqGetHomeDirectory ( char *  buf,
int  bufsize 
)

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

7656 {
7657 #ifndef WIN32
7658  const char *home;
7659 
7660  home = getenv("HOME");
7661  if (home == NULL || home[0] == '\0')
7662  return pg_get_user_home_dir(geteuid(), buf, bufsize);
7663  strlcpy(buf, home, bufsize);
7664  return true;
7665 #else
7666  char tmppath[MAX_PATH];
7667 
7668  ZeroMemory(tmppath, sizeof(tmppath));
7669  if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
7670  return false;
7671  snprintf(buf, bufsize, "%s/postgresql", tmppath);
7672  return true;
7673 #endif
7674 }
#define bufsize
Definition: indent_globs.h:36
static char * buf
Definition: pg_test_fsync.c:73
bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen)
Definition: user.c:64

References buf, bufsize, pg_get_user_home_dir(), snprintf, and strlcpy().

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

◆ pqGetInt()

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

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

217 {
218  uint16 tmp2;
219  uint32 tmp4;
220 
221  switch (bytes)
222  {
223  case 2:
224  if (conn->inCursor + 2 > conn->inEnd)
225  return EOF;
226  memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
227  conn->inCursor += 2;
228  *result = (int) pg_ntoh16(tmp2);
229  break;
230  case 4:
231  if (conn->inCursor + 4 > conn->inEnd)
232  return EOF;
233  memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
234  conn->inCursor += 4;
235  *result = (int) pg_ntoh32(tmp4);
236  break;
237  default:
239  "integer of size %lu not supported by pqGetInt",
240  (unsigned long) bytes);
241  return EOF;
242  }
243 
244  return 0;
245 }
unsigned short uint16
Definition: c.h:505
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
#define pg_ntoh16(x)
Definition: pg_bswap.h:124

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

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

◆ pqGetline3()

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

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

1811 {
1812  int status;
1813 
1814  if (conn->sock == PGINVALID_SOCKET ||
1818  {
1819  libpq_append_conn_error(conn, "PQgetline: not doing text COPY OUT");
1820  *s = '\0';
1821  return EOF;
1822  }
1823 
1824  while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1825  {
1826  /* need to load more data */
1827  if (pqWait(true, false, conn) ||
1828  pqReadData(conn) < 0)
1829  {
1830  *s = '\0';
1831  return EOF;
1832  }
1833  }
1834 
1835  if (status < 0)
1836  {
1837  /* End of copy detected; gin up old-style terminator */
1838  strcpy(s, "\\.");
1839  return 0;
1840  }
1841 
1842  /* Add null terminator, and strip trailing \n if present */
1843  if (s[status - 1] == '\n')
1844  {
1845  s[status - 1] = '\0';
1846  return 0;
1847  }
1848  else
1849  {
1850  s[status] = '\0';
1851  return 1;
1852  }
1853 }
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2901
char copy_is_binary
Definition: libpq-int.h:450

References pg_conn::asyncStatus, conn, pg_conn::copy_is_binary, libpq_append_conn_error(), PGASYNC_COPY_BOTH, PGASYNC_COPY_OUT, PGINVALID_SOCKET, PQgetlineAsync(), pqReadData(), pqWait(), and pg_conn::sock.

Referenced by PQgetline().

◆ pqGetlineAsync3()

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

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

1862 {
1863  int msgLength;
1864  int avail;
1865 
1868  return -1; /* we are not doing a copy... */
1869 
1870  /*
1871  * Recognize the next input message. To make life simpler for async
1872  * callers, we keep returning 0 until the next message is fully available
1873  * even if it is not Copy Data. This should keep PQendcopy from blocking.
1874  * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1875  */
1876  msgLength = getCopyDataMessage(conn);
1877  if (msgLength < 0)
1878  return -1; /* end-of-copy or error */
1879  if (msgLength == 0)
1880  return 0; /* no data yet */
1881 
1882  /*
1883  * Move data from libpq's buffer to the caller's. In the case where a
1884  * prior call found the caller's buffer too small, we use
1885  * conn->copy_already_done to remember how much of the row was already
1886  * returned to the caller.
1887  */
1889  avail = msgLength - 4 - conn->copy_already_done;
1890  if (avail <= bufsize)
1891  {
1892  /* Able to consume the whole message */
1893  memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1894  /* Mark message consumed */
1895  conn->inStart = conn->inCursor + avail;
1896  /* Reset state for next time */
1897  conn->copy_already_done = 0;
1898  return avail;
1899  }
1900  else
1901  {
1902  /* We must return a partial message */
1903  memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1904  /* The message is NOT consumed from libpq's buffer */
1906  return bufsize;
1907  }
1908 }
int copy_already_done
Definition: libpq-int.h:451

References pg_conn::asyncStatus, bufsize, conn, 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().

◆ pqGetnchar()

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

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

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

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

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

◆ pqGetNegotiateProtocolVersion3()

int pqGetNegotiateProtocolVersion3 ( PGconn conn)

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

1413 {
1414  int tmp;
1415  ProtocolVersion their_version;
1416  int num;
1418 
1419  if (pqGetInt(&tmp, 4, conn) != 0)
1420  return EOF;
1421  their_version = tmp;
1422 
1423  if (pqGetInt(&num, 4, conn) != 0)
1424  return EOF;
1425 
1426  initPQExpBuffer(&buf);
1427  for (int i = 0; i < num; i++)
1428  {
1429  if (pqGets(&conn->workBuffer, conn))
1430  {
1431  termPQExpBuffer(&buf);
1432  return EOF;
1433  }
1434  if (buf.len > 0)
1435  appendPQExpBufferChar(&buf, ' ');
1437  }
1438 
1439  if (their_version < conn->pversion)
1440  libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u",
1442  PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version));
1443  if (num > 0)
1444  {
1446  libpq_ngettext("protocol extension not supported by server: %s",
1447  "protocol extensions not supported by server: %s", num),
1448  buf.data);
1450  }
1451 
1452  /* neither -- server shouldn't have sent it */
1453  if (!(their_version < conn->pversion) && !(num > 0))
1454  libpq_append_conn_error(conn, "invalid %s message", "NegotiateProtocolVersion");
1455 
1456  termPQExpBuffer(&buf);
1457  return 0;
1458 }
#define libpq_ngettext(s, p, n)
Definition: libpq-int.h:914
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:87
uint32 ProtocolVersion
Definition: pqcomm.h:99
#define PG_PROTOCOL_MINOR(v)
Definition: pqcomm.h:88
ProtocolVersion pversion
Definition: libpq-int.h:479
PQExpBufferData workBuffer
Definition: libpq-int.h:639

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), buf, conn, PQExpBufferData::data, pg_conn::errorMessage, i, initPQExpBuffer(), libpq_append_conn_error(), libpq_ngettext, PG_PROTOCOL_MAJOR, PG_PROTOCOL_MINOR, pqGetInt(), pqGets(), pg_conn::pversion, termPQExpBuffer(), and pg_conn::workBuffer.

Referenced by PQconnectPoll().

◆ pqGets()

int pqGets ( PQExpBuffer  buf,
PGconn conn 
)

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

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

References buf, conn, and pqGets_internal().

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

◆ pqGets_append()

int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

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

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

References buf, conn, and pqGets_internal().

Referenced by PQconnectPoll().

◆ pqInternalNotice()

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

◆ pqMakeEmptyPGconn()

PGconn* pqMakeEmptyPGconn ( void  )

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

4526 {
4527  PGconn *conn;
4528 
4529 #ifdef WIN32
4530 
4531  /*
4532  * Make sure socket support is up and running in this process.
4533  *
4534  * Note: the Windows documentation says that we should eventually do a
4535  * matching WSACleanup() call, but experience suggests that that is at
4536  * least as likely to cause problems as fix them. So we don't.
4537  */
4538  static bool wsastartup_done = false;
4539 
4540  if (!wsastartup_done)
4541  {
4542  WSADATA wsaData;
4543 
4544  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4545  return NULL;
4546  wsastartup_done = true;
4547  }
4548 
4549  /* Forget any earlier error */
4550  WSASetLastError(0);
4551 #endif /* WIN32 */
4552 
4553  conn = (PGconn *) malloc(sizeof(PGconn));
4554  if (conn == NULL)
4555  return conn;
4556 
4557  /* Zero all pointers and booleans */
4558  MemSet(conn, 0, sizeof(PGconn));
4559 
4560  /* install default notice hooks */
4563 
4568  conn->options_valid = false;
4569  conn->nonblocking = false;
4571  conn->std_strings = false; /* unless server says differently */
4578  conn->Pfdebug = NULL;
4579 
4580  /*
4581  * We try to send at least 8K at a time, which is the usual size of pipe
4582  * buffers on Unix systems. That way, when we are sending a large amount
4583  * of data, we avoid incurring extra kernel context swaps for partial
4584  * bufferloads. The output buffer is initially made 16K in size, and we
4585  * try to dump it after accumulating 8K.
4586  *
4587  * With the same goal of minimizing context swaps, the input buffer will
4588  * be enlarged anytime it has less than 8K free, so we initially allocate
4589  * twice that.
4590  */
4591  conn->inBufSize = 16 * 1024;
4592  conn->inBuffer = (char *) malloc(conn->inBufSize);
4593  conn->outBufSize = 16 * 1024;
4594  conn->outBuffer = (char *) malloc(conn->outBufSize);
4595  conn->rowBufLen = 32;
4596  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
4599 
4600  if (conn->inBuffer == NULL ||
4601  conn->outBuffer == NULL ||
4602  conn->rowBuf == NULL ||
4605  {
4606  /* out of memory already :-( */
4607  freePGconn(conn);
4608  conn = NULL;
4609  }
4610 
4611  return conn;
4612 }
#define MemSet(start, val, len)
Definition: c.h:1020
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7349
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7364
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:4624
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:132
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
#define SCRAM_SHA_256_DEFAULT_ITERATIONS
Definition: scram-common.h:50
PQnoticeProcessor noticeProc
Definition: libpq-int.h:157
PGdataValue * rowBuf
Definition: libpq-int.h:541
bool std_strings
Definition: libpq-int.h:514
PGTernaryBool in_hot_standby
Definition: libpq-int.h:516
int client_encoding
Definition: libpq-int.h:513
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:515
int rowBufLen
Definition: libpq-int.h:542
int scram_sha_256_iterations
Definition: libpq-int.h:561

References pg_conn::asyncStatus, pg_conn::client_encoding, conn, CONNECTION_BAD, pg_conn::default_transaction_read_only, defaultNoticeProcessor(), defaultNoticeReceiver(), pg_conn::errorMessage, freePGconn(), pg_conn::in_hot_standby, pg_conn::inBuffer, pg_conn::inBufSize, initPQExpBuffer(), malloc, MemSet, pg_conn::nonblocking, pg_conn::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeRec, pg_conn::options_valid, pg_conn::outBuffer, pg_conn::outBufSize, pg_conn::Pfdebug, PG_BOOL_UNKNOWN, PG_SQL_ASCII, PGASYNC_IDLE, PGINVALID_SOCKET, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQERRORS_DEFAULT, PQExpBufferBroken, PQSHOW_CONTEXT_ERRORS, PQTRANS_IDLE, pg_conn::rowBuf, pg_conn::rowBufLen, SCRAM_SHA_256_DEFAULT_ITERATIONS, pg_conn::scram_sha_256_iterations, pg_conn::show_context, pg_conn::sock, pg_conn::status, pg_conn::std_strings, pg_conn::verbosity, pg_conn::workBuffer, and pg_conn::xactStatus.

Referenced by PQcancelCreate(), PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ pqPacketSend()

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

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

4978 {
4979  /* Start the message. */
4980  if (pqPutMsgStart(pack_type, conn))
4981  return STATUS_ERROR;
4982 
4983  /* Send the message body. */
4984  if (pqPutnchar(buf, buf_len, conn))
4985  return STATUS_ERROR;
4986 
4987  /* Finish the message. */
4988  if (pqPutMsgEnd(conn))
4989  return STATUS_ERROR;
4990 
4991  /* Flush to ensure backend gets it. */
4992  if (pqFlush(conn))
4993  return STATUS_ERROR;
4994 
4995  return STATUS_OK;
4996 }
#define STATUS_OK
Definition: c.h:1169
#define STATUS_ERROR
Definition: c.h:1170

References buf, conn, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), STATUS_ERROR, and STATUS_OK.

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

◆ pqParseInput3()

void pqParseInput3 ( PGconn conn)

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

67 {
68  char id;
69  int msgLength;
70  int avail;
71 
72  /*
73  * Loop to parse successive complete messages available in the buffer.
74  */
75  for (;;)
76  {
77  /*
78  * Try to read a message. First get the type code and length. Return
79  * if not enough data.
80  */
82  if (pqGetc(&id, conn))
83  return;
84  if (pqGetInt(&msgLength, 4, conn))
85  return;
86 
87  /*
88  * Try to validate message type/length here. A length less than 4 is
89  * definitely broken. Large lengths should only be believed for a few
90  * message types.
91  */
92  if (msgLength < 4)
93  {
94  handleSyncLoss(conn, id, msgLength);
95  return;
96  }
97  if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
98  {
99  handleSyncLoss(conn, id, msgLength);
100  return;
101  }
102 
103  /*
104  * Can't process if message body isn't all here yet.
105  */
106  msgLength -= 4;
107  avail = conn->inEnd - conn->inCursor;
108  if (avail < msgLength)
109  {
110  /*
111  * Before returning, enlarge the input buffer if needed to hold
112  * the whole message. This is better than leaving it to
113  * pqReadData because we can avoid multiple cycles of realloc()
114  * when the message is large; also, we can implement a reasonable
115  * recovery strategy if we are unable to make the buffer big
116  * enough.
117  */
118  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
119  conn))
120  {
121  /*
122  * XXX add some better recovery code... plan is to skip over
123  * the message using its length, then report an error. For the
124  * moment, just treat this like loss of sync (which indeed it
125  * might be!)
126  */
127  handleSyncLoss(conn, id, msgLength);
128  }
129  return;
130  }
131 
132  /*
133  * NOTIFY and NOTICE messages can happen in any state; always process
134  * them right away.
135  *
136  * Most other messages should only be processed while in BUSY state.
137  * (In particular, in READY state we hold off further parsing until
138  * the application collects the current PGresult.)
139  *
140  * However, if the state is IDLE then we got trouble; we need to deal
141  * with the unexpected message somehow.
142  *
143  * ParameterStatus ('S') messages are a special case: in IDLE state we
144  * must process 'em (this case could happen if a new value was adopted
145  * from config file due to SIGHUP), but otherwise we hold off until
146  * BUSY state.
147  */
148  if (id == PqMsg_NotificationResponse)
149  {
150  if (getNotify(conn))
151  return;
152  }
153  else if (id == PqMsg_NoticeResponse)
154  {
155  if (pqGetErrorNotice3(conn, false))
156  return;
157  }
158  else if (conn->asyncStatus != PGASYNC_BUSY)
159  {
160  /* If not IDLE state, just wait ... */
161  if (conn->asyncStatus != PGASYNC_IDLE)
162  return;
163 
164  /*
165  * Unexpected message in IDLE state; need to recover somehow.
166  * ERROR messages are handled using the notice processor;
167  * ParameterStatus is handled normally; anything else is just
168  * dropped on the floor after displaying a suitable warning
169  * notice. (An ERROR is very possibly the backend telling us why
170  * it is about to close the connection, so we don't want to just
171  * discard it...)
172  */
173  if (id == PqMsg_ErrorResponse)
174  {
175  if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
176  return;
177  }
178  else if (id == PqMsg_ParameterStatus)
179  {
181  return;
182  }
183  else
184  {
185  /* Any other case is unexpected and we summarily skip it */
187  "message type 0x%02x arrived from server while idle",
188  id);
189  /* Discard the unexpected message */
190  conn->inCursor += msgLength;
191  }
192  }
193  else
194  {
195  /*
196  * In BUSY state, we can process everything.
197  */
198  switch (id)
199  {
201  if (pqGets(&conn->workBuffer, conn))
202  return;
204  {
207  if (!conn->result)
208  {
209  libpq_append_conn_error(conn, "out of memory");
211  }
212  }
213  if (conn->result)
215  CMDSTATUS_LEN);
217  break;
218  case PqMsg_ErrorResponse:
219  if (pqGetErrorNotice3(conn, true))
220  return;
222  break;
223  case PqMsg_ReadyForQuery:
224  if (getReadyForQuery(conn))
225  return;
227  {
230  if (!conn->result)
231  {
232  libpq_append_conn_error(conn, "out of memory");
234  }
235  else
236  {
239  }
240  }
241  else
242  {
243  /* Advance the command queue and set us idle */
244  pqCommandQueueAdvance(conn, true, false);
246  }
247  break;
250  {
253  if (!conn->result)
254  {
255  libpq_append_conn_error(conn, "out of memory");
257  }
258  }
260  break;
261  case PqMsg_ParseComplete:
262  /* If we're doing PQprepare, we're done; else ignore */
263  if (conn->cmd_queue_head &&
265  {
267  {
270  if (!conn->result)
271  {
272  libpq_append_conn_error(conn, "out of memory");
274  }
275  }
277  }
278  break;
279  case PqMsg_BindComplete:
280  /* Nothing to do for this message type */
281  break;
282  case PqMsg_CloseComplete:
283  /* If we're doing PQsendClose, we're done; else ignore */
284  if (conn->cmd_queue_head &&
286  {
288  {
291  if (!conn->result)
292  {
293  libpq_append_conn_error(conn, "out of memory");
295  }
296  }
298  }
299  break;
302  return;
303  break;
305 
306  /*
307  * This is expected only during backend startup, but it's
308  * just as easy to handle it as part of the main loop.
309  * Save the data and continue processing.
310  */
311  if (pqGetInt(&(conn->be_pid), 4, conn))
312  return;
313  if (pqGetInt(&(conn->be_key), 4, conn))
314  return;
315  break;
317  if (conn->error_result ||
318  (conn->result != NULL &&
320  {
321  /*
322  * We've already choked for some reason. Just discard
323  * the data till we get to the end of the query.
324  */
325  conn->inCursor += msgLength;
326  }
327  else if (conn->result == NULL ||
328  (conn->cmd_queue_head &&
330  {
331  /* First 'T' in a query sequence */
332  if (getRowDescriptions(conn, msgLength))
333  return;
334  }
335  else
336  {
337  /*
338  * A new 'T' message is treated as the start of
339  * another PGresult. (It is not clear that this is
340  * really possible with the current backend.) We stop
341  * parsing until the application accepts the current
342  * result.
343  */
345  return;
346  }
347  break;
348  case PqMsg_NoData:
349 
350  /*
351  * NoData indicates that we will not be seeing a
352  * RowDescription message because the statement or portal
353  * inquired about doesn't return rows.
354  *
355  * If we're doing a Describe, we have to pass something
356  * back to the client, so set up a COMMAND_OK result,
357  * instead of PGRES_TUPLES_OK. Otherwise we can just
358  * ignore this message.
359  */
360  if (conn->cmd_queue_head &&
362  {
364  {
367  if (!conn->result)
368  {
369  libpq_append_conn_error(conn, "out of memory");
371  }
372  }
374  }
375  break;
377  if (getParamDescriptions(conn, msgLength))
378  return;
379  break;
380  case PqMsg_DataRow:
381  if (conn->result != NULL &&
384  {
385  /* Read another tuple of a normal query response */
386  if (getAnotherTuple(conn, msgLength))
387  return;
388  }
389  else if (conn->error_result ||
390  (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 */
402  libpq_append_conn_error(conn, "server sent data (\"D\" message) without prior row description (\"T\" message)");
404  /* Discard the unexpected message */
405  conn->inCursor += msgLength;
406  }
407  break;
410  return;
412  break;
415  return;
417  conn->copy_already_done = 0;
418  break;
421  return;
423  conn->copy_already_done = 0;
424  break;
425  case PqMsg_CopyData:
426 
427  /*
428  * If we see Copy Data, just silently drop it. This would
429  * only occur if application exits COPY OUT mode too
430  * early.
431  */
432  conn->inCursor += msgLength;
433  break;
434  case PqMsg_CopyDone:
435 
436  /*
437  * If we see Copy Done, just silently drop it. This is
438  * the normal case during PQendcopy. We will keep
439  * swallowing data, expecting to see command-complete for
440  * the COPY command.
441  */
442  break;
443  default:
444  libpq_append_conn_error(conn, "unexpected response from server; first received character was \"%c\"", id);
445  /* build an error result holding the error message */
447  /* not sure if we will see more, so go to ready state */
449  /* Discard the unexpected message */
450  conn->inCursor += msgLength;
451  break;
452  } /* switch on protocol character */
453  }
454  /* Successfully consumed this message */
455  if (conn->inCursor == conn->inStart + 5 + msgLength)
456  {
457  /* trace server-to-client message */
458  if (conn->Pfdebug)
460 
461  /* Normal case: parsing agrees with specified length */
463  }
464  else
465  {
466  /* Trouble --- report it */
467  libpq_append_conn_error(conn, "message contents do not agree with length in message type \"%c\"", id);
468  /* build an error result holding the error message */
471  /* trust the specified message length as what to skip */
472  conn->inStart += 5 + msgLength;
473  }
474  }
475 }
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
Definition: fe-exec.c:3142
static int getAnotherTuple(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:762
static int getRowDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:503
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
static int getParamDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:674
@ PGRES_COPY_IN
Definition: libpq-fe.h:107
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:112
@ PGRES_TUPLES_CHUNK
Definition: libpq-fe.h:117
@ PGRES_COPY_OUT
Definition: libpq-fe.h:106
@ PGRES_PIPELINE_SYNC
Definition: libpq-fe.h:114
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:103
@ PQ_PIPELINE_ON
Definition: libpq-fe.h:163
#define CMDSTATUS_LEN
Definition: libpq-int.h:89
#define PqMsg_CloseComplete
Definition: protocol.h:40
#define PqMsg_NotificationResponse
Definition: protocol.h:41
#define PqMsg_BindComplete
Definition: protocol.h:39
#define PqMsg_CopyData
Definition: protocol.h:65
#define PqMsg_ParameterDescription
Definition: protocol.h:58
#define PqMsg_ReadyForQuery
Definition: protocol.h:55
#define PqMsg_CopyInResponse
Definition: protocol.h:45
#define PqMsg_EmptyQueryResponse
Definition: protocol.h:47
#define PqMsg_RowDescription
Definition: protocol.h:52
#define PqMsg_CopyBothResponse
Definition: protocol.h:54
#define PqMsg_ParameterStatus
Definition: protocol.h:51
#define PqMsg_NoData
Definition: protocol.h:56
#define PqMsg_BackendKeyData
Definition: protocol.h:48
#define PqMsg_CommandComplete
Definition: protocol.h:42
#define PqMsg_ErrorResponse
Definition: protocol.h:44
#define PqMsg_DataRow
Definition: protocol.h:43
#define PqMsg_NoticeResponse
Definition: protocol.h:49
#define PqMsg_CopyOutResponse
Definition: protocol.h:46
#define PqMsg_ParseComplete
Definition: protocol.h:38
int be_pid
Definition: libpq-int.h:510
int be_key
Definition: libpq-int.h:511
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:181

References pg_conn::asyncStatus, pg_conn::be_key, pg_conn::be_pid, pg_conn::cmd_queue_head, pg_result::cmdStatus, CMDSTATUS_LEN, conn, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::error_result, getAnotherTuple(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), handleSyncLoss(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), pg_conn::noticeHooks, pg_conn::Pfdebug, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, pgHavePendingResult, PGQUERY_CLOSE, PGQUERY_DESCRIBE, PGQUERY_PREPARE, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_PIPELINE_SYNC, PGRES_TUPLES_CHUNK, PGRES_TUPLES_OK, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQ_PIPELINE_ON, pqCheckInBufferSpace(), pqCommandQueueAdvance(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGets(), pqInternalNotice(), PQmakeEmptyPGresult(), PqMsg_BackendKeyData, PqMsg_BindComplete, PqMsg_CloseComplete, PqMsg_CommandComplete, PqMsg_CopyBothResponse, PqMsg_CopyData, PqMsg_CopyDone, PqMsg_CopyInResponse, PqMsg_CopyOutResponse, PqMsg_DataRow, PqMsg_EmptyQueryResponse, PqMsg_ErrorResponse, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_ParseComplete, PqMsg_ReadyForQuery, PqMsg_RowDescription, pqSaveErrorResult(), pqTraceOutputMessage(), PGcmdQueueEntry::queryclass, pg_conn::result, pg_result::resultStatus, strlcpy(), VALID_LONG_MESSAGE_TYPE, and pg_conn::workBuffer.

Referenced by parseInput().

◆ pqParseIntParam()

bool pqParseIntParam ( const char *  value,
int *  result,
PGconn conn,
const char *  context 
)

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

7684 {
7685  char *end;
7686  long numval;
7687 
7688  Assert(value != NULL);
7689 
7690  *result = 0;
7691 
7692  /* strtol(3) skips leading whitespaces */
7693  errno = 0;
7694  numval = strtol(value, &end, 10);
7695 
7696  /*
7697  * If no progress was done during the parsing or an error happened, fail.
7698  * This tests properly for overflows of the result.
7699  */
7700  if (value == end || errno != 0 || numval != (int) numval)
7701  goto error;
7702 
7703  /*
7704  * Skip any trailing whitespace; if anything but whitespace remains before
7705  * the terminating character, fail
7706  */
7707  while (*end != '\0' && isspace((unsigned char) *end))
7708  end++;
7709 
7710  if (*end != '\0')
7711  goto error;
7712 
7713  *result = numval;
7714  return true;
7715 
7716 error:
7717  libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
7718  value, context);
7719  return false;
7720 }
static struct @155 value
tree context
Definition: radixtree.h:1833
static void error(void)
Definition: sql-dyntest.c:147

References Assert, conn, context, error(), libpq_append_conn_error(), and value.

Referenced by pqConnectDBComplete(), PQconnectPoll(), PQgetCancel(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), and setTCPUserTimeout().

◆ pqPrepareAsyncResult()

PGresult* pqPrepareAsyncResult ( PGconn conn)

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

852 {
853  PGresult *res;
854 
855  res = conn->result;
856  if (res)
857  {
858  /*
859  * If the pre-existing result is an ERROR (presumably something
860  * received from the server), assume that it represents whatever is in
861  * conn->errorMessage, and advance errorReported.
862  */
865  }
866  else
867  {
868  /*
869  * We get here after internal-to-libpq errors. We should probably
870  * always have error_result = true, but if we don't, gin up some error
871  * text.
872  */
873  if (!conn->error_result)
874  libpq_append_conn_error(conn, "no error text available");
875 
876  /* Paranoia: be sure errorReported offset is sane */
877  if (conn->errorReported < 0 ||
879  conn->errorReported = 0;
880 
881  /*
882  * Make a PGresult struct for the error. We temporarily lie about the
883  * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
884  * all of conn->errorMessage.
885  */
887  if (res)
888  {
889  /*
890  * Report whatever new error text we have, and advance
891  * errorReported.
892  */
896  }
897  else
898  {
899  /*
900  * Ouch, not enough memory for a PGresult. Fortunately, we have a
901  * card up our sleeve: we can use the static OOM_result. Casting
902  * away const here is a bit ugly, but it seems best to declare
903  * OOM_result as const, in hopes it will be allocated in read-only
904  * storage.
905  */
907 
908  /*
909  * Don't advance errorReported. Perhaps we'll be able to report
910  * the text later.
911  */
912  }
913  }
914 
915  /*
916  * Replace conn->result with saved_result, if any. In the normal case
917  * there isn't a saved result and we're just dropping ownership of the
918  * current result. In partial-result mode this restores the situation to
919  * what it was before we created the current partial result.
920  */
922  conn->error_result = false; /* saved_result is never an error */
923  conn->saved_result = NULL;
924 
925  return res;
926 }
#define unconstify(underlying_type, expr)
Definition: c.h:1245
static const PGresult OOM_result
Definition: fe-exec.c:49
int errorReported
Definition: libpq-int.h:636

References conn, pg_conn::error_result, pg_conn::errorMessage, pg_conn::errorReported, PQExpBufferData::len, libpq_append_conn_error(), OOM_result, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PQmakeEmptyPGresult(), pqSetResultError(), res, pg_conn::result, pg_result::resultStatus, pg_conn::saved_result, and unconstify.

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

◆ pqPutc()

int pqPutc ( char  c,
PGconn conn 
)

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

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

References conn, and pqPutMsgBytes().

Referenced by PQsendQueryGuts(), and PQsendTypedCommand().

◆ pqPutInt()

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

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

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

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

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

◆ pqPutMsgEnd()

int pqPutMsgEnd ( PGconn conn)

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

518 {
519  /* Fill in length word if needed */
520  if (conn->outMsgStart >= 0)
521  {
522  uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
523 
524  msgLen = pg_hton32(msgLen);
525  memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
526  }
527 
528  /* trace client-to-server message */
529  if (conn->Pfdebug)
530  {
531  if (conn->outCount < conn->outMsgStart)
533  else
536  }
537 
538  /* Make message eligible to send */
540 
541  if (conn->outCount >= 8192)
542  {
543  int toSend = conn->outCount - (conn->outCount % 8192);
544 
545  if (pqSendSome(conn, toSend) < 0)
546  return EOF;
547  /* in nonblock mode, don't complain if unable to send it all */
548  }
549 
550  return 0;
551 }
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition: fe-trace.c:704
int outMsgStart
Definition: libpq-int.h:536
int outMsgEnd
Definition: libpq-int.h:538

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

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

◆ pqPutMsgStart()

int pqPutMsgStart ( char  msg_type,
PGconn conn 
)

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

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

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

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

◆ pqPutnchar()

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

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

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

References conn, len, and pqPutMsgBytes().

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

◆ pqPuts()

int pqPuts ( const char *  s,
PGconn conn 
)

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

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

References conn, and pqPutMsgBytes().

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

◆ pqReadData()

int pqReadData ( PGconn conn)

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

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

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

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

◆ pqReadReady()

int pqReadReady ( PGconn conn)

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

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

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqReleaseConnHosts()

void pqReleaseConnHosts ( PGconn conn)

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

4707 {
4708  if (conn->connhost)
4709  {
4710  for (int i = 0; i < conn->nconnhost; ++i)
4711  {
4712  free(conn->connhost[i].host);
4714  free(conn->connhost[i].port);
4715  if (conn->connhost[i].password != NULL)
4716  {
4718  strlen(conn->connhost[i].password));
4720  }
4721  }
4722  free(conn->connhost);
4723  }
4724 }
void explicit_bzero(void *buf, size_t len)

References conn, pg_conn::connhost, explicit_bzero(), free, pg_conn_host::host, pg_conn_host::hostaddr, i, pg_conn::nconnhost, pg_conn_host::password, and pg_conn_host::port.

Referenced by freePGconn(), and PQcancelCreate().

◆ pqResultAlloc()

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

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

564 {
565  char *space;
566  PGresult_data *block;
567 
568  if (!res)
569  return NULL;
570 
571  if (nBytes <= 0)
572  return res->null_field;
573 
574  /*
575  * If alignment is needed, round up the current position to an alignment
576  * boundary.
577  */
578  if (isBinary)
579  {
580  int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
581 
582  if (offset)
583  {
586  }
587  }
588 
589  /* If there's enough space in the current block, no problem. */
590  if (nBytes <= (size_t) res->spaceLeft)
591  {
592  space = res->curBlock->space + res->curOffset;
593  res->curOffset += nBytes;
594  res->spaceLeft -= nBytes;
595  return space;
596  }
597 
598  /*
599  * If the requested object is very large, give it its own block; this
600  * avoids wasting what might be most of the current block to start a new
601  * block. (We'd have to special-case requests bigger than the block size
602  * anyway.) The object is always given binary alignment in this case.
603  */
604  if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
605  {
606  size_t alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD;
607 
608  block = (PGresult_data *) malloc(alloc_size);
609  if (!block)
610  return NULL;
611  res->memorySize += alloc_size;
612  space = block->space + PGRESULT_BLOCK_OVERHEAD;
613  if (res->curBlock)
614  {
615  /*
616  * Tuck special block below the active block, so that we don't
617  * have to waste the free space in the active block.
618  */
619  block->next = res->curBlock->next;
620  res->curBlock->next = block;
621  }
622  else
623  {
624  /* Must set up the new block as the first active block. */
625  block->next = NULL;
626  res->curBlock = block;
627  res->spaceLeft = 0; /* be sure it's marked full */
628  }
629  return space;
630  }
631 
632  /* Otherwise, start a new block. */
634  if (!block)
635  return NULL;
637  block->next = res->curBlock;
638  res->curBlock = block;
639  if (isBinary)
640  {
641  /* object needs full alignment */
644  }
645  else
646  {
647  /* we can cram it right after the overhead pointer */
648  res->curOffset = sizeof(PGresult_data);
650  }
651 
652  space = block->space + res->curOffset;
653  res->curOffset += nBytes;
654  res->spaceLeft -= nBytes;
655  return space;
656 }
#define PGRESULT_DATA_BLOCKSIZE
Definition: fe-exec.c:142
#define PGRESULT_BLOCK_OVERHEAD
Definition: fe-exec.c:144
#define PGRESULT_SEP_ALLOC_THRESHOLD
Definition: fe-exec.c:145
#define PGRESULT_ALIGN_BOUNDARY
Definition: fe-exec.c:143
union pgresult_data PGresult_data
Definition: libpq-int.h:104
size_t memorySize
Definition: libpq-int.h:215
int curOffset
Definition: libpq-int.h:212
char null_field[1]
Definition: libpq-int.h:204
int spaceLeft
Definition: libpq-int.h:213
PGresult_data * curBlock
Definition: libpq-int.h:211
PGresult_data * next
Definition: libpq-int.h:108
char space[1]
Definition: libpq-int.h:109

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, res, pgresult_data::space, and pg_result::spaceLeft.

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

◆ pqResultStrdup()

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

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

676 {
677  char *space = (char *) pqResultAlloc(res, strlen(str) + 1, false);
678 
679  if (space)
680  strcpy(space, str);
681  return space;
682 }
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:563
const char * str

References pqResultAlloc(), res, and str.

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

◆ pqRowProcessor()

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

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

1207 {
1208  PGresult *res = conn->result;
1209  int nfields = res->numAttributes;
1210  const PGdataValue *columns = conn->rowBuf;
1211  PGresAttValue *tup;
1212  int i;
1213 
1214  /*
1215  * In partial-result mode, if we don't already have a partial PGresult
1216  * then make one by cloning conn->result (which should hold the correct
1217  * result metadata by now). Then the original conn->result is moved over
1218  * to saved_result so that we can re-use it as a reference for future
1219  * partial results. The saved result will become active again after
1220  * pqPrepareAsyncResult() returns the partial result to the application.
1221  */
1222  if (conn->partialResMode && conn->saved_result == NULL)
1223  {
1224  /* Copy everything that should be in the result at this point */
1225  res = PQcopyResult(res,
1228  if (!res)
1229  return 0;
1230  /* Change result status to appropriate special value */
1232  /* And stash it as the active result */
1234  conn->result = res;
1235  }
1236 
1237  /*
1238  * Basically we just allocate space in the PGresult for each field and
1239  * copy the data over.
1240  *
1241  * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1242  * caller will take to mean "out of memory". This is preferable to trying
1243  * to set up such a message here, because evidently there's not enough
1244  * memory for gettext() to do anything.
1245  */
1246  tup = (PGresAttValue *)
1247  pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
1248  if (tup == NULL)
1249  return 0;
1250 
1251  for (i = 0; i < nfields; i++)
1252  {
1253  int clen = columns[i].len;
1254 
1255  if (clen < 0)
1256  {
1257  /* null field */
1258  tup[i].len = NULL_LEN;
1259  tup[i].value = res->null_field;
1260  }
1261  else
1262  {
1263  bool isbinary = (res->attDescs[i].format != 0);
1264  char *val;
1265 
1266  val = (char *) pqResultAlloc(res, clen + 1, isbinary);
1267  if (val == NULL)
1268  return 0;
1269 
1270  /* copy and zero-terminate the data (even if it's binary) */
1271  memcpy(val, columns[i].value, clen);
1272  val[clen] = '\0';
1273 
1274  tup[i].len = clen;
1275  tup[i].value = val;
1276  }
1277  }
1278 
1279  /* And add the tuple to the PGresult's tuple array */
1280  if (!pqAddTuple(res, tup, errmsgp))
1281  return 0;
1282 
1283  /*
1284  * Success. In partial-result mode, if we have enough rows then make the
1285  * result available to the client immediately.
1286  */
1289 
1290  return 1;
1291 }
PGresult * PQcopyResult(const PGresult *src, int flags)
Definition: fe-exec.c:318
static bool pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
Definition: fe-exec.c:993
@ PGRES_SINGLE_TUPLE
Definition: libpq-fe.h:113
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:46
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:48
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:49
#define NULL_LEN
Definition: libpq-int.h:136
int maxChunkSize
Definition: libpq-int.h:448
bool singleRowMode
Definition: libpq-int.h:447
bool partialResMode
Definition: libpq-int.h:446
int ntups
Definition: libpq-int.h:172
PGresAttDesc * attDescs
Definition: libpq-int.h:174
int numAttributes
Definition: libpq-int.h:173
char * value
Definition: libpq-int.h:141

References pg_conn::asyncStatus, pg_result::attDescs, conn, pgresAttDesc::format, i, pgresAttValue::len, pgDataValue::len, pg_conn::maxChunkSize, pg_result::ntups, pg_result::null_field, NULL_LEN, pg_result::numAttributes, pg_conn::partialResMode, PG_COPYRES_ATTRS, PG_COPYRES_EVENTS, PG_COPYRES_NOTICEHOOKS, PGASYNC_READY_MORE, PGRES_SINGLE_TUPLE, PGRES_TUPLES_CHUNK, pqAddTuple(), PQcopyResult(), pqResultAlloc(), res, pg_conn::result, pg_result::resultStatus, pg_conn::rowBuf, pg_conn::saved_result, pg_conn::singleRowMode, val, value, and pgresAttValue::value.

Referenced by getAnotherTuple().

◆ pqSaveErrorResult()

void pqSaveErrorResult ( PGconn conn)

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

804 {
805  /* Drop any pending result ... */
807  /* ... and set flag to remember to make an error result later */
808  conn->error_result = true;
809 }

References conn, pg_conn::error_result, and pqClearAsyncResult().

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

◆ pqSaveMessageField()

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

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

1061 {
1062  PGMessageField *pfield;
1063 
1064  pfield = (PGMessageField *)
1066  offsetof(PGMessageField, contents) +
1067  strlen(value) + 1,
1068  true);
1069  if (!pfield)
1070  return; /* out of memory? */
1071  pfield->code = code;
1072  strcpy(pfield->contents, value);
1073  pfield->next = res->errFields;
1074  res->errFields = pfield;
1075 }
struct pgMessageField * next
Definition: libpq-int.h:147
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:149

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

Referenced by pqGetErrorNotice3(), and pqInternalNotice().

◆ pqSaveParameterStatus()

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

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

1082 {
1083  pgParameterStatus *pstatus;
1084  pgParameterStatus *prev;
1085 
1086  /*
1087  * Forget any old information about the parameter
1088  */
1089  for (pstatus = conn->pstatus, prev = NULL;
1090  pstatus != NULL;
1091  prev = pstatus, pstatus = pstatus->next)
1092  {
1093  if (strcmp(pstatus->name, name) == 0)
1094  {
1095  if (prev)
1096  prev->next = pstatus->next;
1097  else
1098  conn->pstatus = pstatus->next;
1099  free(pstatus); /* frees name and value strings too */
1100  break;
1101  }
1102  }
1103 
1104  /*
1105  * Store new info as a single malloc block
1106  */
1107  pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
1108  strlen(name) + strlen(value) + 2);
1109  if (pstatus)
1110  {
1111  char *ptr;
1112 
1113  ptr = ((char *) pstatus) + sizeof(pgParameterStatus);
1114  pstatus->name = ptr;
1115  strcpy(ptr, name);
1116  ptr += strlen(name) + 1;
1117  pstatus->value = ptr;
1118  strcpy(ptr, value);
1119  pstatus->next = conn->pstatus;
1120  conn->pstatus = pstatus;
1121  }
1122 
1123  /*
1124  * Save values of settings that are of interest to libpq in fields of the
1125  * PGconn object. We keep client_encoding and standard_conforming_strings
1126  * in static variables as well, so that PQescapeString and PQescapeBytea
1127  * can behave somewhat sanely (at least in single-connection-using
1128  * programs).
1129  */
1130  if (strcmp(name, "client_encoding") == 0)
1131  {
1133  /* if we don't recognize the encoding name, fall back to SQL_ASCII */
1134  if (conn->client_encoding < 0)
1137  }
1138  else if (strcmp(name, "standard_conforming_strings") == 0)
1139  {
1140  conn->std_strings = (strcmp(value, "on") == 0);
1142  }
1143  else if (strcmp(name, "server_version") == 0)
1144  {
1145  /* We convert the server version to numeric form. */
1146  int cnt;
1147  int vmaj,
1148  vmin,
1149  vrev;
1150 
1151  cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);
1152 
1153  if (cnt == 3)
1154  {
1155  /* old style, e.g. 9.6.1 */
1156  conn->sversion = (100 * vmaj + vmin) * 100 + vrev;
1157  }
1158  else if (cnt == 2)
1159  {
1160  if (vmaj >= 10)
1161  {
1162  /* new style, e.g. 10.1 */
1163  conn->sversion = 100 * 100 * vmaj + vmin;
1164  }
1165  else
1166  {
1167  /* old style without minor version, e.g. 9.6devel */
1168  conn->sversion = (100 * vmaj + vmin) * 100;
1169  }
1170  }
1171  else if (cnt == 1)
1172  {
1173  /* new style without minor version, e.g. 10devel */
1174  conn->sversion = 100 * 100 * vmaj;
1175  }
1176  else
1177  conn->sversion = 0; /* unknown */
1178  }
1179  else if (strcmp(name, "default_transaction_read_only") == 0)
1180  {
1182  (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1183  }
1184  else if (strcmp(name, "in_hot_standby") == 0)
1185  {
1186  conn->in_hot_standby =
1187  (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1188  }
1189  else if (strcmp(name, "scram_iterations") == 0)
1190  {
1192  }
1193 }
static bool static_std_strings
Definition: fe-exec.c:60
static int static_client_encoding
Definition: fe-exec.c:59
struct pgParameterStatus pgParameterStatus
#define pg_char_to_encoding
Definition: pg_wchar.h:629
struct pgParameterStatus * next
Definition: libpq-int.h:278
int sversion
Definition: libpq-int.h:480
pgParameterStatus * pstatus
Definition: libpq-int.h:512

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

Referenced by getParameterStatus().

◆ pqsecure_close()

void pqsecure_close ( PGconn conn)

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

168 {
169 #ifdef USE_SSL
170  pgtls_close(conn);
171 #endif
172 }

References conn, and pgtls_close().

Referenced by pqDropConnection().

◆ pqsecure_initialize()

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

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

139 {
140  int r = 0;
141 
142 #ifdef USE_SSL
143  r = pgtls_init(conn, do_ssl, do_crypto);
144 #endif
145 
146  return r;
147 }
int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)

References conn, and pgtls_init().

Referenced by PQconnectPoll().

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn conn)

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

154 {
155 #ifdef USE_SSL
156  return pgtls_open_client(conn);
157 #else
158  /* shouldn't get here */
159  return PGRES_POLLING_FAILED;
160 #endif
161 }
PostgresPollingStatusType pgtls_open_client(PGconn *conn)

References conn, PGRES_POLLING_FAILED, and pgtls_open_client().

Referenced by PQconnectPoll().

◆ pqsecure_raw_read()

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

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

209 {
210  ssize_t n;
211  int result_errno = 0;
212  char sebuf[PG_STRERROR_R_BUFLEN];
213 
214  SOCK_ERRNO_SET(0);
215 
216  n = recv(conn->sock, ptr, len, 0);
217 
218  if (n < 0)
219  {
220  result_errno = SOCK_ERRNO;
221 
222  /* Set error message if appropriate */
223  switch (result_errno)
224  {
225 #ifdef EAGAIN
226  case EAGAIN:
227 #endif
228 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
229  case EWOULDBLOCK:
230 #endif
231  case EINTR:
232  /* no error message, caller is expected to retry */
233  break;
234 
235  case EPIPE:
236  case ECONNRESET:
237  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
238  "\tThis probably means the server terminated abnormally\n"
239  "\tbefore or while processing the request.");
240  break;
241 
242  case 0:
243  /* If errno didn't get set, treat it as regular EOF */
244  n = 0;
245  break;
246 
247  default:
248  libpq_append_conn_error(conn, "could not receive data from server: %s",
249  SOCK_STRERROR(result_errno,
250  sebuf, sizeof(sebuf)));
251  break;
252  }
253  }
254 
255  /* ensure we return the intended errno to caller */
256  SOCK_ERRNO_SET(result_errno);
257 
258  return n;
259 }
#define recv(s, buf, len, flags)
Definition: win32_port.h:496

References conn, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_append_conn_error(), 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().

◆ pqsecure_raw_write()

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

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

332 {
333  ssize_t n;
334  int flags = 0;
335  int result_errno = 0;
336  char msgbuf[1024];
337  char sebuf[PG_STRERROR_R_BUFLEN];
338 
339  DECLARE_SIGPIPE_INFO(spinfo);
340 
341  /*
342  * If we already had a write failure, we will never again try to send data
343  * on that connection. Even if the kernel would let us, we've probably
344  * lost message boundary sync with the server. conn->write_failed
345  * therefore persists until the connection is reset, and we just discard
346  * all data presented to be written.
347  */
348  if (conn->write_failed)
349  return len;
350 
351 #ifdef MSG_NOSIGNAL
352  if (conn->sigpipe_flag)
353  flags |= MSG_NOSIGNAL;
354 
355 retry_masked:
356 #endif /* MSG_NOSIGNAL */
357 
358  DISABLE_SIGPIPE(conn, spinfo, return -1);
359 
360  n = send(conn->sock, ptr, len, flags);
361 
362  if (n < 0)
363  {
364  result_errno = SOCK_ERRNO;
365 
366  /*
367  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
368  * on this machine. So, clear sigpipe_flag so we don't try the flag
369  * again, and retry the send().
370  */
371 #ifdef MSG_NOSIGNAL
372  if (flags != 0 && result_errno == EINVAL)
373  {
374  conn->sigpipe_flag = false;
375  flags = 0;
376  goto retry_masked;
377  }
378 #endif /* MSG_NOSIGNAL */
379 
380  /* Set error message if appropriate */
381  switch (result_errno)
382  {
383 #ifdef EAGAIN
384  case EAGAIN:
385 #endif
386 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
387  case EWOULDBLOCK:
388 #endif
389  case EINTR:
390  /* no error message, caller is expected to retry */
391  break;
392 
393  case EPIPE:
394  /* Set flag for EPIPE */
395  REMEMBER_EPIPE(spinfo, true);
396 
397  /* FALL THRU */
398 
399  case ECONNRESET:
400  conn->write_failed = true;
401  /* Store error message in conn->write_err_msg, if possible */
402  /* (strdup failure is OK, we'll cope later) */
403  snprintf(msgbuf, sizeof(msgbuf),
404  libpq_gettext("server closed the connection unexpectedly\n"
405  "\tThis probably means the server terminated abnormally\n"
406  "\tbefore or while processing the request."));
407  /* keep newline out of translated string */
408  strlcat(msgbuf, "\n", sizeof(msgbuf));
409  conn->write_err_msg = strdup(msgbuf);
410  /* Now claim the write succeeded */
411  n = len;
412  break;
413 
414  default:
415  conn->write_failed = true;
416  /* Store error message in conn->write_err_msg, if possible */
417  /* (strdup failure is OK, we'll cope later) */
418  snprintf(msgbuf, sizeof(msgbuf),
419  libpq_gettext("could not send data to server: %s"),
420  SOCK_STRERROR(result_errno,
421  sebuf, sizeof(sebuf)));
422  /* keep newline out of translated string */
423  strlcat(msgbuf, "\n", sizeof(msgbuf));
424  conn->write_err_msg = strdup(msgbuf);
425  /* Now claim the write succeeded */
426  n = len;
427  break;
428  }
429  }
430 
431  RESTORE_SIGPIPE(conn, spinfo);
432 
433  /* ensure we return the intended errno to caller */
434  SOCK_ERRNO_SET(result_errno);
435 
436  return n;
437 }
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:77
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:66
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:64
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:83
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
char * write_err_msg
Definition: libpq-int.h:487
bool sigpipe_flag
Definition: libpq-int.h:485
bool write_failed
Definition: libpq-int.h:486
#define send(s, buf, len, flags)
Definition: win32_port.h:497

References conn, DECLARE_SIGPIPE_INFO, DISABLE_SIGPIPE, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_gettext, PG_STRERROR_R_BUFLEN, REMEMBER_EPIPE, RESTORE_SIGPIPE, send, pg_conn::sigpipe_flag, snprintf, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, strlcat(), pg_conn::write_err_msg, and pg_conn::write_failed.

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

◆ pqsecure_read()

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

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

183 {
184  ssize_t n;
185 
186 #ifdef USE_SSL
187  if (conn->ssl_in_use)
188  {
189  n = pgtls_read(conn, ptr, len);
190  }
191  else
192 #endif
193 #ifdef ENABLE_GSS
194  if (conn->gssenc)
195  {
196  n = pg_GSS_read(conn, ptr, len);
197  }
198  else
199 #endif
200  {
201  n = pqsecure_raw_read(conn, ptr, len);
202  }
203 
204  return n;
205 }
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:208

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

Referenced by pqReadData().

◆ pqsecure_write()

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

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

283 {
284  ssize_t n;
285 
286 #ifdef USE_SSL
287  if (conn->ssl_in_use)
288  {
289  n = pgtls_write(conn, ptr, len);
290  }
291  else
292 #endif
293 #ifdef ENABLE_GSS
294  if (conn->gssenc)
295  {
296  n = pg_GSS_write(conn, ptr, len);
297  }
298  else
299 #endif
300  {
301  n = pqsecure_raw_write(conn, ptr, len);
302  }
303 
304  return n;
305 }
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
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:331

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

Referenced by pqSendSome().

◆ PQsendQueryContinue()

int PQsendQueryContinue ( PGconn conn,
const char *  query 
)

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

1423 {
1424  return PQsendQueryInternal(conn, query, false);
1425 }
static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
Definition: fe-exec.c:1428

References conn, and PQsendQueryInternal().

Referenced by PQconnectPoll().

◆ pqSetResultError()

void pqSetResultError ( PGresult res,
PQExpBuffer  errorMessage,
int  offset 
)

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

693 {
694  char *msg;
695 
696  if (!res)
697  return;
698 
699  /*
700  * We handle two OOM scenarios here. The errorMessage buffer might be
701  * marked "broken" due to having previously failed to allocate enough
702  * memory for the message, or it might be fine but pqResultStrdup fails
703  * and returns NULL. In either case, just make res->errMsg point directly
704  * at a constant "out of memory" string.
705  */
706  if (!PQExpBufferBroken(errorMessage))
707  msg = pqResultStrdup(res, errorMessage->data + offset);
708  else
709  msg = NULL;
710  if (msg)
711  res->errMsg = msg;
712  else
713  res->errMsg = libpq_gettext("out of memory\n");
714 }

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

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

◆ pqSkipnchar()

int pqSkipnchar ( size_t  len,
PGconn conn 
)

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

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

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

Referenced by getAnotherTuple().

◆ pqTraceOutputMessage()

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

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

530 {
531  char id;
532  int length;
533  char *prefix = toServer ? "F" : "B";
534  int logCursor = 0;
535  bool regress;
536 
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 PqMsg_ParseComplete:
566  fprintf(conn->Pfdebug, "ParseComplete");
567  /* No message content */
568  break;
569  case PqMsg_BindComplete:
570  fprintf(conn->Pfdebug, "BindComplete");
571  /* No message content */
572  break;
573  case PqMsg_CloseComplete:
574  fprintf(conn->Pfdebug, "CloseComplete");
575  /* No message content */
576  break;
578  pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
579  break;
580  case PqMsg_Bind:
581  pqTraceOutputB(conn->Pfdebug, message, &logCursor);
582  break;
583  case PqMsg_CopyDone:
584  fprintf(conn->Pfdebug, "CopyDone");
585  /* No message content */
586  break;
588  /* Close(F) and CommandComplete(B) use the same identifier. */
590  pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor);
591  break;
592  case PqMsg_CopyData:
593  /* Drop COPY data to reduce the overhead of logging. */
594  break;
595  case PqMsg_Describe:
596  /* Describe(F) and DataRow(B) use the same identifier. */
598  pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor);
599  break;
600  case PqMsg_Execute:
601  /* Execute(F) and ErrorResponse(B) use the same identifier. */
603  pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor,
604  regress);
605  break;
606  case PqMsg_CopyFail:
607  pqTraceOutputf(conn->Pfdebug, message, &logCursor);
608  break;
609  case PqMsg_FunctionCall:
610  pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
611  break;
613  pqTraceOutputG(conn->Pfdebug, message, &logCursor);
614  break;
615  case PqMsg_Flush:
616  /* Flush(F) and CopyOutResponse(B) use the same identifier */
618  if (!toServer)
619  pqTraceOutputH(conn->Pfdebug, message, &logCursor);
620  else
621  fprintf(conn->Pfdebug, "Flush"); /* no message content */
622  break;
624  fprintf(conn->Pfdebug, "EmptyQueryResponse");
625  /* No message content */
626  break;
628  pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
629  break;
630  case PqMsg_NoData:
631  fprintf(conn->Pfdebug, "NoData");
632  /* No message content */
633  break;
635  pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
636  &logCursor, regress);
637  break;
638  case PqMsg_Parse:
639  pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
640  break;
641  case PqMsg_Query:
642  pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
643  break;
645  pqTraceOutputR(conn->Pfdebug, message, &logCursor);
646  break;
648  fprintf(conn->Pfdebug, "PortalSuspended");
649  /* No message content */
650  break;
651  case PqMsg_Sync:
652  /* Parameter Status(B) and Sync(F) use the same identifier */
654  if (!toServer)
655  pqTraceOutputS(conn->Pfdebug, message, &logCursor);
656  else
657  fprintf(conn->Pfdebug, "Sync"); /* no message content */
658  break;
660  pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
661  break;
663  pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
664  break;
666  pqTraceOutputv(conn->Pfdebug, message, &logCursor);
667  break;
669  pqTraceOutputV(conn->Pfdebug, message, &logCursor);
670  break;
672  pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
673  break;
674  case PqMsg_Terminate:
675  fprintf(conn->Pfdebug, "Terminate");
676  /* No message content */
677  break;
678  case PqMsg_ReadyForQuery:
679  pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
680  break;
681  default:
682  fprintf(conn->Pfdebug, "Unknown message: %02x", id);
683  break;
684  }
685 
686  fputc('\n', conn->Pfdebug);
687 
688  /*
689  * Verify the printing routine did it right. Note that the one-byte
690  * message identifier is not included in the length, but our cursor does
691  * include it.
692  */
693  if (logCursor - 1 != length)
695  "mismatched message length: consumed %d, expected %d\n",
696  logCursor - 1, length);
697 }
static void pqTraceOutputQ(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:428
static void pqTraceOutputS(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:444
static void pqTraceOutputH(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:390
static void pqTraceOutputZ(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:519
static void pqTraceOutputW(FILE *f, const char *message, int *cursor, int length)
Definition: fe-trace.c:508
static void pqTraceOutputE(FILE *f, bool toServer, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:327
static void pqTraceOutputV(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:496
static void pqTraceOutputK(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:404
static void pqTraceOutputF(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:349
static void pqTraceOutputP(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:413
static void pqTraceOutputT(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:466
static void pqTraceOutputA(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:220
static void pqTraceOutputD(FILE *f, bool toServer, const char *message, int *cursor)
Definition: fe-trace.c:278
static void pqTraceOutputG(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:376
static void pqTraceOutputf(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:341
static void pqTraceOutputNR(FILE *f, const char *type, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:306
static void pqTraceOutputR(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:436
static void pqTraceOutputt(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:453
static void pqTraceOutputB(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:230
static void pqTraceOutputv(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:487
static void pqTraceOutputC(FILE *f, bool toServer, const char *message, int *cursor)
Definition: fe-trace.c:261
static void pqTraceFormatTimestamp(char *timestr, size_t ts_len)
Definition: fe-trace.c:80
#define PQTRACE_SUPPRESS_TIMESTAMPS
Definition: libpq-fe.h:442
#define PQTRACE_REGRESS_MODE
Definition: libpq-fe.h:444
#define fprintf
Definition: port.h:242
#define PqMsg_Describe
Definition: protocol.h:21
#define PqMsg_FunctionCallResponse
Definition: protocol.h:53
#define PqMsg_AuthenticationRequest
Definition: protocol.h:50
#define PqMsg_NegotiateProtocolVersion
Definition: protocol.h:59
#define PqMsg_PortalSuspended
Definition: protocol.h:57
#define PqMsg_Parse
Definition: protocol.h:25
#define PqMsg_Bind
Definition: protocol.h:19
#define PqMsg_CopyFail
Definition: protocol.h:29
#define PqMsg_Flush
Definition: protocol.h:24
#define PqMsg_Query
Definition: protocol.h:26
#define PqMsg_Terminate
Definition: protocol.h:28
#define PqMsg_Execute
Definition: protocol.h:22
#define PqMsg_Close
Definition: protocol.h:20
int traceFlags
Definition: libpq-int.h:427

References Assert, conn, fprintf, pg_conn::Pfdebug, pg_ntoh32, PqMsg_AuthenticationRequest, PqMsg_BackendKeyData, PqMsg_Bind, PqMsg_BindComplete, PqMsg_Close, PqMsg_CloseComplete, PqMsg_CommandComplete, PqMsg_CopyBothResponse, PqMsg_CopyData, PqMsg_CopyDone, PqMsg_CopyFail, PqMsg_CopyInResponse, PqMsg_CopyOutResponse, PqMsg_DataRow, PqMsg_Describe, PqMsg_EmptyQueryResponse, PqMsg_ErrorResponse, PqMsg_Execute, PqMsg_Flush, PqMsg_FunctionCall, PqMsg_FunctionCallResponse, PqMsg_NegotiateProtocolVersion, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_Parse, PqMsg_ParseComplete, PqMsg_PortalSuspended, PqMsg_Query, PqMsg_ReadyForQuery, PqMsg_RowDescription, PqMsg_Sync, PqMsg_Terminate, 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().

◆ pqTraceOutputNoTypeByteMessage()

void pqTraceOutputNoTypeByteMessage ( PGconn conn,
const char *  message 
)

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

705 {
706  int length;
707  int logCursor = 0;
708 
710  {
711  char timestr[128];
712 
713  pqTraceFormatTimestamp(timestr, sizeof(timestr));
714  fprintf(conn->Pfdebug, "%s\t", timestr);
715  }
716 
717  memcpy(&length, message + logCursor, 4);
718  length = (int) pg_ntoh32(length);
719  logCursor += 4;
720 
721  fprintf(conn->Pfdebug, "F\t%d\t", length);
722 
723  switch (length)
724  {
725  case 16: /* CancelRequest */
726  fprintf(conn->Pfdebug, "CancelRequest\t");
727  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
728  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
729  pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
730  break;
731  case 8: /* GSSENCRequest or SSLRequest */
732  /* These messages do not reach here. */
733  default:
734  fprintf(conn->Pfdebug, "Unknown message: length is %d", length);
735  break;
736  }
737 
738  fputc('\n', conn->Pfdebug);
739 }
static int pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:144

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

Referenced by pqPutMsgEnd().

◆ pqWait()

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

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

979 {
980  return pqWaitTimed(forRead, forWrite, conn, (time_t) -1);
981 }

References conn, and pqWaitTimed().

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

◆ pqWaitTimed()

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

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

992 {
993  int result;
994 
995  result = pqSocketCheck(conn, forRead, forWrite, finish_time);
996 
997  if (result < 0)
998  return -1; /* errorMessage is already set */
999 
1000  if (result == 0)
1001  {
1002  libpq_append_conn_error(conn, "timeout expired");
1003  return 1;
1004  }
1005 
1006  return 0;
1007 }

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

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

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

1025 {
1026  return pqSocketCheck(conn, 0, 1, (time_t) 0);
1027 }

References conn, and pqSocketCheck().

Variable Documentation

◆ pg_g_threadlock

pgthreadlock_t pg_g_threadlock
extern

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

Referenced by PQregisterThreadLock().

◆ pgresStatus

char* const pgresStatus[]
extern

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

Referenced by PQresStatus().