Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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 "libpq/pg-gssapi.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_SSL   0x04
 
#define AUTH_RESPONSE_GSS   'G'
 
#define AUTH_RESPONSE_PASSWORD   'P'
 
#define AUTH_RESPONSE_SASL_INITIAL   'I'
 
#define AUTH_RESPONSE_SASL   'S'
 
#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 , 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)
 
int 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 PQsendCancelRequest (PGconn *cancelConn)
 
int pqCheckOutBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqCheckInBufferSpace (size_t bytes_needed, PGconn *conn)
 
void pqParseDone (PGconn *conn, int newInStart)
 
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 (void *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const void *s, size_t len, PGconn *conn)
 
int pqGetInt (int *result, size_t bytes, PGconn *conn)
 
int pqPutInt (int value, size_t bytes, PGconn *conn)
 
int pqPutMsgStart (char msg_type, PGconn *conn)
 
int pqPutMsgEnd (PGconn *conn)
 
int pqReadData (PGconn *conn)
 
int pqFlush (PGconn *conn)
 
int pqWait (int forRead, int forWrite, PGconn *conn)
 
int pqWaitTimed (int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
 
int pqReadReady (PGconn *conn)
 
int pqWriteReady (PGconn *conn)
 
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)
 
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 pqTraceOutputCharResponse (PGconn *conn, const char *responseType, char response)
 
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

◆ AUTH_RESPONSE_GSS

#define AUTH_RESPONSE_GSS   'G'

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

◆ AUTH_RESPONSE_PASSWORD

#define AUTH_RESPONSE_PASSWORD   'P'

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

◆ AUTH_RESPONSE_SASL

#define AUTH_RESPONSE_SASL   'S'

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

◆ AUTH_RESPONSE_SASL_INITIAL

#define AUTH_RESPONSE_SASL_INITIAL   'I'

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

◆ CMDSTATUS_LEN

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */

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

◆ ENC_ERROR

#define ENC_ERROR   0

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

◆ ENC_GSSAPI

#define ENC_GSSAPI   0x02

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

◆ ENC_PLAINTEXT

#define ENC_PLAINTEXT   0x01

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

◆ ENC_SSL

#define ENC_SSL   0x04

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

◆ libpq_gettext

#define libpq_gettext (   x)    (x)

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

◆ libpq_ngettext

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

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

◆ NULL_LEN

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

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

◆ OUTBUFFER_THRESHOLD

#define OUTBUFFER_THRESHOLD   65536

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

◆ pgHavePendingResult

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

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

◆ pglock_thread

#define pglock_thread ( )    pg_g_threadlock(true)

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

◆ pgunlock_thread

#define pgunlock_thread ( )    pg_g_threadlock(false)

Definition at line 736 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:52

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

◆ pqIsnonblocking

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

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

◆ SOCK_ERRNO

#define SOCK_ERRNO   errno

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

◆ SOCK_ERRNO_SET

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

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

◆ SOCK_STRERROR

#define SOCK_STRERROR   strerror_r

Definition at line 963 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 98 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 307 of file libpq-int.h.

308{
pg_conn_host_type
Definition: libpq-int.h:308
@ CHT_UNIX_SOCKET
Definition: libpq-int.h:311
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:310
@ CHT_HOST_NAME
Definition: libpq-int.h:309

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

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

◆ PGLoadBalanceType

Enumerator
LOAD_BALANCE_DISABLE 
LOAD_BALANCE_RANDOM 

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

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

◆ PGQueryClass

Enumerator
PGQUERY_SIMPLE 
PGQUERY_EXTENDED 
PGQUERY_PREPARE 
PGQUERY_DESCRIBE 
PGQUERY_SYNC 
PGQUERY_CLOSE 

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

319{
320 PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
321 PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
322 PGQUERY_PREPARE, /* Parse only (PQprepare) */
323 PGQUERY_DESCRIBE, /* Describe Statement or Portal */
324 PGQUERY_SYNC, /* Sync (at end of a pipeline) */
325 PGQUERY_CLOSE /* Close Statement or Portal */
PGQueryClass
Definition: libpq-int.h:319
@ PGQUERY_SIMPLE
Definition: libpq-int.h:320
@ PGQUERY_SYNC
Definition: libpq-int.h:324
@ PGQUERY_EXTENDED
Definition: libpq-int.h:321
@ PGQUERY_DESCRIBE
Definition: libpq-int.h:323
@ PGQUERY_CLOSE
Definition: libpq-int.h:325
@ PGQUERY_PREPARE
Definition: libpq-int.h:322

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

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

◆ PGTernaryBool

Enumerator
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 

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

255{
256 PG_BOOL_UNKNOWN = 0, /* Currently unknown */
257 PG_BOOL_YES, /* Yes (true) */
258 PG_BOOL_NO /* No (false) */
PGTernaryBool
Definition: libpq-int.h:255
@ PG_BOOL_YES
Definition: libpq-int.h:257
@ PG_BOOL_NO
Definition: libpq-int.h:258
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:256

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

1503{
1504 if (conn->ssl_in_use)
1505 {
1506 if (conn->ssl)
1507 {
1508 /*
1509 * We can't destroy everything SSL-related here due to the
1510 * possible later calls to OpenSSL routines which may need our
1511 * thread callbacks, so set a flag here and check at the end.
1512 */
1513
1514 SSL_shutdown(conn->ssl);
1515 SSL_free(conn->ssl);
1516 conn->ssl = NULL;
1517 conn->ssl_in_use = false;
1518 conn->ssl_handshake_started = false;
1519 }
1520
1521 if (conn->peer)
1522 {
1523 X509_free(conn->peer);
1524 conn->peer = NULL;
1525 }
1526
1527#ifdef USE_SSL_ENGINE
1528 if (conn->engine)
1529 {
1530 ENGINE_finish(conn->engine);
1531 ENGINE_free(conn->engine);
1532 conn->engine = NULL;
1533 }
1534#endif
1535 }
1536}
bool ssl_handshake_started
Definition: libpq-int.h:612
bool ssl_in_use
Definition: libpq-int.h:611

References conn, 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 340 of file fe-secure-openssl.c.

341{
342 X509 *peer_cert;
343 const EVP_MD *algo_type;
344 unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
345 unsigned int hash_size;
346 int algo_nid;
347 char *cert_hash;
348
349 *len = 0;
350
351 if (!conn->peer)
352 return NULL;
353
354 peer_cert = conn->peer;
355
356 /*
357 * Get the signature algorithm of the certificate to determine the hash
358 * algorithm to use for the result. Prefer X509_get_signature_info(),
359 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
360 */
361#if HAVE_X509_GET_SIGNATURE_INFO
362 if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
363#else
364 if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
365 &algo_nid, NULL))
366#endif
367 {
368 libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
369 return NULL;
370 }
371
372 /*
373 * The TLS server's certificate bytes need to be hashed with SHA-256 if
374 * its signature algorithm is MD5 or SHA-1 as per RFC 5929
375 * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
376 * is used, the same hash as the signature algorithm is used.
377 */
378 switch (algo_nid)
379 {
380 case NID_md5:
381 case NID_sha1:
382 algo_type = EVP_sha256();
383 break;
384 default:
385 algo_type = EVP_get_digestbynid(algo_nid);
386 if (algo_type == NULL)
387 {
388 libpq_append_conn_error(conn, "could not find digest for NID %s",
389 OBJ_nid2sn(algo_nid));
390 return NULL;
391 }
392 break;
393 }
394
395 if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
396 {
397 libpq_append_conn_error(conn, "could not generate peer certificate hash");
398 return NULL;
399 }
400
401 /* save result */
402 cert_hash = malloc(hash_size);
403 if (cert_hash == NULL)
404 {
405 libpq_append_conn_error(conn, "out of memory");
406 return NULL;
407 }
408 memcpy(cert_hash, hash, hash_size);
409 *len = hash_size;
410
411 return cert_hash;
412}
#define malloc(a)
Definition: header.h:50
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: oauth-utils.c:95
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_open_client()

PostgresPollingStatusType pgtls_open_client ( PGconn conn)

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

97{
98 /* First time through? */
99 if (conn->ssl == NULL)
100 {
101 /*
102 * Create a connection-specific SSL object, and load client
103 * certificate, private key, and trusted CA certs.
104 */
105 if (initialize_SSL(conn) != 0)
106 {
107 /* initialize_SSL already put a message in conn->errorMessage */
110 }
111 }
112
113 /* Begin or continue the actual handshake */
114 return open_client_SSL(conn);
115}
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:115

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

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

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

235{
236 return SSL_pending(conn->ssl) > 0;
237}

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

547{
548 STACK_OF(GENERAL_NAME) * peer_san;
549 int i;
550 int rc = 0;
551 char *host = conn->connhost[conn->whichhost].host;
552 int host_type;
553 bool check_cn = true;
554
555 Assert(host && host[0]); /* should be guaranteed by caller */
556
557 /*
558 * We try to match the NSS behavior here, which is a slight departure from
559 * the spec but seems to make more intuitive sense:
560 *
561 * If connhost contains a DNS name, and the certificate's SANs contain any
562 * dNSName entries, then we'll ignore the Subject Common Name entirely;
563 * otherwise, we fall back to checking the CN. (This behavior matches the
564 * RFC.)
565 *
566 * If connhost contains an IP address, and the SANs contain iPAddress
567 * entries, we again ignore the CN. Otherwise, we allow the CN to match,
568 * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A
569 * client MUST NOT seek a match for a reference identifier of CN-ID if the
570 * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any
571 * application-specific identifier types supported by the client.")
572 *
573 * NOTE: Prior versions of libpq did not consider iPAddress entries at
574 * all, so this new behavior might break a certificate that has different
575 * IP addresses in the Subject CN and the SANs.
576 */
577 if (is_ip_address(host))
578 host_type = GEN_IPADD;
579 else
580 host_type = GEN_DNS;
581
582 /*
583 * First, get the Subject Alternative Names (SANs) from the certificate,
584 * and compare them against the originally given hostname.
585 */
586 peer_san = (STACK_OF(GENERAL_NAME) *)
587 X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
588
589 if (peer_san)
590 {
591 int san_len = sk_GENERAL_NAME_num(peer_san);
592
593 for (i = 0; i < san_len; i++)
594 {
595 const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
596 char *alt_name = NULL;
597
598 if (name->type == host_type)
599 {
600 /*
601 * This SAN is of the same type (IP or DNS) as our host name,
602 * so don't allow a fallback check of the CN.
603 */
604 check_cn = false;
605 }
606
607 if (name->type == GEN_DNS)
608 {
609 (*names_examined)++;
611 name->d.dNSName,
612 &alt_name);
613 }
614 else if (name->type == GEN_IPADD)
615 {
616 (*names_examined)++;
618 name->d.iPAddress,
619 &alt_name);
620 }
621
622 if (alt_name)
623 {
624 if (!*first_name)
625 *first_name = alt_name;
626 else
627 free(alt_name);
628 }
629
630 if (rc != 0)
631 {
632 /*
633 * Either we hit an error or a match, and either way we should
634 * not fall back to the CN.
635 */
636 check_cn = false;
637 break;
638 }
639 }
640 sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
641 }
642
643 /*
644 * If there is no subjectAltName extension of the matching type, check the
645 * Common Name.
646 *
647 * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
648 * dNSName is present, the CN must be ignored. We break this rule if host
649 * is an IP address; see the comment above.)
650 */
651 if (check_cn)
652 {
653 X509_NAME *subject_name;
654
655 subject_name = X509_get_subject_name(conn->peer);
656 if (subject_name != NULL)
657 {
658 int cn_index;
659
660 cn_index = X509_NAME_get_index_by_NID(subject_name,
661 NID_commonName, -1);
662 if (cn_index >= 0)
663 {
664 char *common_name = NULL;
665
666 (*names_examined)++;
668 X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
669 &common_name);
670
671 if (common_name)
672 {
673 if (!*first_name)
674 *first_name = common_name;
675 else
676 free(common_name);
677 }
678 }
679 }
680 }
681
682 return rc;
683}
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)
Assert(PointerIsAligned(start, uint64))
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:77
char * host
Definition: libpq-int.h:358
int whichhost
Definition: libpq-int.h:481
pg_conn_host * connhost
Definition: libpq-int.h:482
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 240 of file fe-secure-openssl.c.

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

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 172 of file oauth-utils.c.

173{
174 sigset_t sigpipe_sigset;
175 sigset_t sigset;
176
177 sigemptyset(&sigpipe_sigset);
178 sigaddset(&sigpipe_sigset, SIGPIPE);
179
180 /* Block SIGPIPE and save previous mask for later reset */
181 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
182 if (SOCK_ERRNO)
183 return -1;
184
185 /* We can have a pending SIGPIPE only if it was blocked before */
186 if (sigismember(osigset, SIGPIPE))
187 {
188 /* Is there a pending SIGPIPE? */
189 if (sigpending(&sigset) != 0)
190 return -1;
191
192 if (sigismember(&sigset, SIGPIPE))
193 *sigpipe_pending = true;
194 else
195 *sigpipe_pending = false;
196 }
197 else
198 *sigpipe_pending = false;
199
200 return 0;
201}
#define SIGPIPE
Definition: win32_port.h:163

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by pg_fe_run_oauth_flow(), and PQprint().

◆ pq_reset_sigpipe()

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

Definition at line 208 of file oauth-utils.c.

209{
210 int save_errno = SOCK_ERRNO;
211 int signo;
212 sigset_t sigset;
213
214 /* Clear SIGPIPE only if none was pending */
215 if (got_epipe && !sigpipe_pending)
216 {
217 if (sigpending(&sigset) == 0 &&
218 sigismember(&sigset, SIGPIPE))
219 {
220 sigset_t sigpipe_sigset;
221
222 sigemptyset(&sigpipe_sigset);
223 sigaddset(&sigpipe_sigset, SIGPIPE);
224
225 sigwait(&sigpipe_sigset, &signo);
226 }
227 }
228
229 /* Restore saved block mask */
230 pthread_sigmask(SIG_SETMASK, osigset, NULL);
231
232 SOCK_ERRNO_SET(save_errno);
233}

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by pg_fe_run_oauth_flow(), and PQprint().

◆ pqBuildErrorMessage3()

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

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

1030{
1031 const char *val;
1032 const char *querytext = NULL;
1033 int querypos = 0;
1034
1035 /* If we couldn't allocate a PGresult, just say "out of memory" */
1036 if (res == NULL)
1037 {
1038 appendPQExpBufferStr(msg, libpq_gettext("out of memory\n"));
1039 return;
1040 }
1041
1042 /*
1043 * If we don't have any broken-down fields, just return the base message.
1044 * This mainly applies if we're given a libpq-generated error result.
1045 */
1046 if (res->errFields == NULL)
1047 {
1048 if (res->errMsg && res->errMsg[0])
1049 appendPQExpBufferStr(msg, res->errMsg);
1050 else
1051 appendPQExpBufferStr(msg, libpq_gettext("no error message available\n"));
1052 return;
1053 }
1054
1055 /* Else build error message from relevant fields */
1057 if (val)
1058 appendPQExpBuffer(msg, "%s: ", val);
1059
1060 if (verbosity == PQERRORS_SQLSTATE)
1061 {
1062 /*
1063 * If we have a SQLSTATE, print that and nothing else. If not (which
1064 * shouldn't happen for server-generated errors, but might possibly
1065 * happen for libpq-generated ones), fall back to TERSE format, as
1066 * that seems better than printing nothing at all.
1067 */
1069 if (val)
1070 {
1071 appendPQExpBuffer(msg, "%s\n", val);
1072 return;
1073 }
1074 verbosity = PQERRORS_TERSE;
1075 }
1076
1077 if (verbosity == PQERRORS_VERBOSE)
1078 {
1080 if (val)
1081 appendPQExpBuffer(msg, "%s: ", val);
1082 }
1084 if (val)
1087 if (val)
1088 {
1089 if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1090 {
1091 /* emit position as a syntax cursor display */
1092 querytext = res->errQuery;
1093 querypos = atoi(val);
1094 }
1095 else
1096 {
1097 /* emit position as text addition to primary message */
1098 /* translator: %s represents a digit string */
1099 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1100 val);
1101 }
1102 }
1103 else
1104 {
1106 if (val)
1107 {
1109 if (verbosity != PQERRORS_TERSE && querytext != NULL)
1110 {
1111 /* emit position as a syntax cursor display */
1112 querypos = atoi(val);
1113 }
1114 else
1115 {
1116 /* emit position as text addition to primary message */
1117 /* translator: %s represents a digit string */
1118 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1119 val);
1120 }
1121 }
1122 }
1123 appendPQExpBufferChar(msg, '\n');
1124 if (verbosity != PQERRORS_TERSE)
1125 {
1126 if (querytext && querypos > 0)
1127 reportErrorPosition(msg, querytext, querypos,
1128 res->client_encoding);
1130 if (val)
1131 appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1133 if (val)
1134 appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1136 if (val)
1137 appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1138 if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1139 (show_context == PQSHOW_CONTEXT_ERRORS &&
1141 {
1143 if (val)
1144 appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1145 val);
1146 }
1147 }
1148 if (verbosity == PQERRORS_VERBOSE)
1149 {
1151 if (val)
1153 libpq_gettext("SCHEMA NAME: %s\n"), val);
1155 if (val)
1157 libpq_gettext("TABLE NAME: %s\n"), val);
1159 if (val)
1161 libpq_gettext("COLUMN NAME: %s\n"), val);
1163 if (val)
1165 libpq_gettext("DATATYPE NAME: %s\n"), val);
1167 if (val)
1169 libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1170 }
1171 if (verbosity == PQERRORS_VERBOSE)
1172 {
1173 const char *valf;
1174 const char *vall;
1175
1179 if (val || valf || vall)
1180 {
1181 appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1182 if (val)
1183 appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1184 if (valf && vall) /* unlikely we'd have just one */
1185 appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1186 valf, vall);
1187 appendPQExpBufferChar(msg, '\n');
1188 }
1189 }
1190}
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
long val
Definition: informix.c:689
#define PQresultErrorField
Definition: libpq-be-fe.h:249
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:136
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:166
@ PQSHOW_CONTEXT_ERRORS
Definition: libpq-fe.h:165
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:158
@ PQERRORS_TERSE
Definition: libpq-fe.h:156
@ PQERRORS_SQLSTATE
Definition: libpq-fe.h:159
#define libpq_gettext(x)
Definition: oauth-utils.h:86
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:63
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:69
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:68
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:71
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:70
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:66
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:67
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:72
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:62
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:193
PGMessageField * errFields
Definition: libpq-int.h:194
ExecStatusType resultStatus
Definition: libpq-int.h:174
char * errQuery
Definition: libpq-int.h:195
int client_encoding
Definition: libpq-int.h:186

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

Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().

◆ pqBuildStartupPacket3()

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

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

2374{
2375 char *startpacket;
2376
2377 *packetlen = build_startup_packet(conn, NULL, options);
2378 startpacket = (char *) malloc(*packetlen);
2379 if (!startpacket)
2380 return NULL;
2381 *packetlen = build_startup_packet(conn, startpacket, options);
2382 return startpacket;
2383}
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;
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:567
int inCursor
Definition: libpq-int.h:570
int inEnd
Definition: libpq-int.h:571
int inBufSize
Definition: libpq-int.h:568
int inStart
Definition: libpq-int.h:569

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:575
char * outBuffer
Definition: libpq-int.h:574

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{
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:597
PGresult * saved_result
Definition: libpq-int.h:599
bool error_result
Definition: libpq-int.h:598

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 5258 of file fe-connect.c.

5259{
5260 /*
5261 * If possible, send Terminate message to close the connection politely.
5262 */
5264
5265 /*
5266 * Must reset the blocking status so a possible reconnect will work.
5267 *
5268 * Don't call PQsetnonblocking() because it will fail if it's unable to
5269 * flush the connection.
5270 */
5271 conn->nonblocking = false;
5272
5273 /*
5274 * Close the connection, reset all transient state, flush I/O buffers.
5275 * Note that this includes clearing conn's error state; we're no longer
5276 * interested in any failures associated with the old connection, and we
5277 * want a clean slate for any new connection attempt.
5278 */
5279 pqDropConnection(conn, true);
5280 conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
5285 pqClearAsyncResult(conn); /* deallocate result */
5287
5288 /*
5289 * Release addrinfo, but since cancel requests never change their addrinfo
5290 * we don't do that. Otherwise we would have to rebuild it during a
5291 * PQcancelReset.
5292 */
5293 if (!conn->cancelRequest)
5295
5296 /* Reset all state obtained from server, too */
5298}
void pqClearOAuthToken(PGconn *conn)
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:530
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:5224
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:5210
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:656
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:779
@ CONNECTION_BAD
Definition: libpq-fe.h:85
@ PQTRANS_IDLE
Definition: libpq-fe.h:147
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:187
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:914
PGTransactionStatusType xactStatus
Definition: libpq-int.h:464
bool cancelRequest
Definition: libpq-int.h:434
bool nonblocking
Definition: libpq-int.h:467
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:463
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:469
ConnStatusType status
Definition: libpq-int.h:462

References pg_conn::asyncStatus, pg_conn::cancelRequest, conn, CONNECTION_BAD, pg_conn::nonblocking, PGASYNC_IDLE, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqClearAsyncResult(), pqClearConnErrorState, pqClearOAuthToken(), 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 3153 of file fe-exec.c.

3154{
3155 PGcmdQueueEntry *prevquery;
3156
3157 if (conn->cmd_queue_head == NULL)
3158 return;
3159
3160 /*
3161 * If processing a query of simple query protocol, we only advance the
3162 * queue when we receive the ReadyForQuery message for it.
3163 */
3164 if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
3165 return;
3166
3167 /*
3168 * If we're waiting for a SYNC, don't advance the queue until we get one.
3169 */
3170 if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
3171 return;
3172
3173 /* delink element from queue */
3174 prevquery = conn->cmd_queue_head;
3176
3177 /* If the queue is now empty, reset the tail too */
3178 if (conn->cmd_queue_head == NULL)
3179 conn->cmd_queue_tail = NULL;
3180
3181 /* and make the queue element recyclable */
3182 prevquery->next = NULL;
3183 pqRecycleCmdQueueEntry(conn, prevquery);
3184}
static void pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
Definition: fe-exec.c:1397
PGQueryClass queryclass
Definition: libpq-int.h:345
struct PGcmdQueueEntry * next
Definition: libpq-int.h:347
PGcmdQueueEntry * cmd_queue_tail
Definition: libpq-int.h:490
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:489

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 2785 of file fe-connect.c.

2786{
2789 int timeout = 0;
2790 int last_whichhost = -2; /* certainly different from whichhost */
2791 int last_whichaddr = -2; /* certainly different from whichaddr */
2792
2793 if (conn == NULL || conn->status == CONNECTION_BAD)
2794 return 0;
2795
2796 /*
2797 * Set up a time limit, if connect_timeout is greater than zero.
2798 */
2799 if (conn->connect_timeout != NULL)
2800 {
2801 if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
2802 "connect_timeout"))
2803 {
2804 /* mark the connection as bad to report the parsing failure */
2806 return 0;
2807 }
2808 }
2809
2810 for (;;)
2811 {
2812 int ret = 0;
2813
2814 /*
2815 * (Re)start the connect_timeout timer if it's active and we are
2816 * considering a different host than we were last time through. If
2817 * we've already succeeded, though, needn't recalculate.
2818 */
2819 if (flag != PGRES_POLLING_OK &&
2820 timeout > 0 &&
2821 (conn->whichhost != last_whichhost ||
2822 conn->whichaddr != last_whichaddr))
2823 {
2824 end_time = PQgetCurrentTimeUSec() + (pg_usec_time_t) timeout * 1000000;
2825 last_whichhost = conn->whichhost;
2826 last_whichaddr = conn->whichaddr;
2827 }
2828
2829 /*
2830 * Wait, if necessary. Note that the initial state (just after
2831 * PQconnectStart) is to wait for the socket to select for writing.
2832 */
2833 switch (flag)
2834 {
2835 case PGRES_POLLING_OK:
2836 return 1; /* success! */
2837
2839 ret = pqWaitTimed(1, 0, conn, end_time);
2840 if (ret == -1)
2841 {
2842 /* hard failure, eg select() problem, aborts everything */
2844 return 0;
2845 }
2846 break;
2847
2849 ret = pqWaitTimed(0, 1, conn, end_time);
2850 if (ret == -1)
2851 {
2852 /* hard failure, eg select() problem, aborts everything */
2854 return 0;
2855 }
2856 break;
2857
2858 default:
2859 /* Just in case we failed to set it in PQconnectPoll */
2861 return 0;
2862 }
2863
2864 if (ret == 1) /* connect_timeout elapsed */
2865 {
2866 /*
2867 * Give up on current server/address, try the next one.
2868 */
2869 conn->try_next_addr = true;
2871 }
2872
2873 /*
2874 * Now try to advance the state machine.
2875 */
2876 if (conn->cancelRequest)
2878 else
2880 }
2881}
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition: fe-cancel.c:226
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2911
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:8237
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition: fe-misc.c:1235
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
Definition: fe-misc.c:1035
@ CONNECTION_NEEDED
Definition: libpq-fe.h:100
int64_t pg_usec_time_t
Definition: libpq-fe.h:238
PostgresPollingStatusType
Definition: libpq-fe.h:114
@ PGRES_POLLING_OK
Definition: libpq-fe.h:118
@ PGRES_POLLING_READING
Definition: libpq-fe.h:116
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:117
static int64 end_time
Definition: pgbench.c:176
int whichaddr
Definition: libpq-int.h:540
char * connect_timeout
Definition: libpq-int.h:384
bool try_next_addr
Definition: libpq-int.h:537
char * flag(int b)
Definition: test-ctype.c:33

References pg_conn::cancelRequest, conn, pg_conn::connect_timeout, CONNECTION_BAD, CONNECTION_NEEDED, end_time, flag(), PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQcancelPoll(), PQconnectPoll(), PQgetCurrentTimeUSec(), 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 2707 of file fe-connect.c.

2708{
2709 if (!conn)
2710 return 0;
2711
2712 if (!conn->options_valid)
2713 goto connect_errReturn;
2714
2715 /*
2716 * Check for bad linking to backend-internal versions of src/common
2717 * functions (see comments in link-canary.c for the reason we need this).
2718 * Nobody but developers should see this message, so we don't bother
2719 * translating it.
2720 */
2722 {
2724 "libpq is incorrectly linked to backend functions\n");
2725 goto connect_errReturn;
2726 }
2727
2728 /* Ensure our buffers are empty */
2729 conn->inStart = conn->inCursor = conn->inEnd = 0;
2730 conn->outCount = 0;
2731
2732 /*
2733 * Set up to try to connect to the first host. (Setting whichhost = -1 is
2734 * a bit of a cheat, but PQconnectPoll will advance it to 0 before
2735 * anything else looks at it.)
2736 *
2737 * Cancel requests are special though, they should only try one host and
2738 * address, and these fields have already been set up in PQcancelCreate,
2739 * so leave these fields alone for cancel requests.
2740 */
2741 if (!conn->cancelRequest)
2742 {
2743 conn->whichhost = -1;
2744 conn->try_next_host = true;
2745 conn->try_next_addr = false;
2746 }
2747
2749
2750 /* Also reset the target_server_type state if needed */
2753
2754 /*
2755 * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
2756 * so that it can easily be re-executed if needed again during the
2757 * asynchronous startup process. However, we must run it once here,
2758 * because callers expect a success return from this routine to mean that
2759 * we are in PGRES_POLLING_WRITING connection state.
2760 */
2762 return 1;
2763
2764connect_errReturn:
2765
2766 /*
2767 * If we managed to open a socket, close it immediately rather than
2768 * waiting till PQfinish. (The application cannot have gotten the socket
2769 * from PQsocket yet, so this doesn't risk breaking anything.)
2770 */
2771 pqDropConnection(conn, true);
2773 return 0;
2774}
bool try_next_host
Definition: libpq-int.h:538
bool options_valid
Definition: libpq-int.h:466
PGTargetServerType target_server_type
Definition: libpq-int.h:534
int outCount
Definition: libpq-int.h:576

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 1250 of file fe-connect.c.

1251{
1252 int i;
1253
1254 /*
1255 * Allocate memory for details about each host to which we might possibly
1256 * try to connect. For that, count the number of elements in the hostaddr
1257 * or host options. If neither is given, assume one host.
1258 */
1259 conn->whichhost = 0;
1260 if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
1262 else if (conn->pghost && conn->pghost[0] != '\0')
1264 else
1265 conn->nconnhost = 1;
1267 calloc(conn->nconnhost, sizeof(pg_conn_host));
1268 if (conn->connhost == NULL)
1269 goto oom_error;
1270
1271 /*
1272 * We now have one pg_conn_host structure per possible host. Fill in the
1273 * host and hostaddr fields for each, by splitting the parameter strings.
1274 */
1275 if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
1276 {
1277 char *s = conn->pghostaddr;
1278 bool more = true;
1279
1280 for (i = 0; i < conn->nconnhost && more; i++)
1281 {
1283 if (conn->connhost[i].hostaddr == NULL)
1284 goto oom_error;
1285 }
1286
1287 /*
1288 * If hostaddr was given, the array was allocated according to the
1289 * number of elements in the hostaddr list, so it really should be the
1290 * right size.
1291 */
1292 Assert(!more);
1293 Assert(i == conn->nconnhost);
1294 }
1295
1296 if (conn->pghost != NULL && conn->pghost[0] != '\0')
1297 {
1298 char *s = conn->pghost;
1299 bool more = true;
1300
1301 for (i = 0; i < conn->nconnhost && more; i++)
1302 {
1304 if (conn->connhost[i].host == NULL)
1305 goto oom_error;
1306 }
1307
1308 /* Check for wrong number of host items. */
1309 if (more || i != conn->nconnhost)
1310 {
1312 libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
1314 return false;
1315 }
1316 }
1317
1318 /*
1319 * Now, for each host slot, identify the type of address spec, and fill in
1320 * the default address if nothing was given.
1321 */
1322 for (i = 0; i < conn->nconnhost; i++)
1323 {
1324 pg_conn_host *ch = &conn->connhost[i];
1325
1326 if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1327 ch->type = CHT_HOST_ADDRESS;
1328 else if (ch->host != NULL && ch->host[0] != '\0')
1329 {
1330 ch->type = CHT_HOST_NAME;
1331 if (is_unixsock_path(ch->host))
1332 ch->type = CHT_UNIX_SOCKET;
1333 }
1334 else
1335 {
1336 free(ch->host);
1337
1338 /*
1339 * This bit selects the default host location. If you change
1340 * this, see also pg_regress.
1341 */
1342 if (DEFAULT_PGSOCKET_DIR[0])
1343 {
1344 ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1345 ch->type = CHT_UNIX_SOCKET;
1346 }
1347 else
1348 {
1349 ch->host = strdup(DefaultHost);
1350 ch->type = CHT_HOST_NAME;
1351 }
1352 if (ch->host == NULL)
1353 goto oom_error;
1354 }
1355 }
1356
1357 /*
1358 * Next, work out the port number corresponding to each host name.
1359 *
1360 * Note: unlike the above for host names, this could leave the port fields
1361 * as null or empty strings. We will substitute DEF_PGPORT whenever we
1362 * read such a port field.
1363 */
1364 if (conn->pgport != NULL && conn->pgport[0] != '\0')
1365 {
1366 char *s = conn->pgport;
1367 bool more = true;
1368
1369 for (i = 0; i < conn->nconnhost && more; i++)
1370 {
1372 if (conn->connhost[i].port == NULL)
1373 goto oom_error;
1374 }
1375
1376 /*
1377 * If exactly one port was given, use it for every host. Otherwise,
1378 * there must be exactly as many ports as there were hosts.
1379 */
1380 if (i == 1 && !more)
1381 {
1382 for (i = 1; i < conn->nconnhost; i++)
1383 {
1384 conn->connhost[i].port = strdup(conn->connhost[0].port);
1385 if (conn->connhost[i].port == NULL)
1386 goto oom_error;
1387 }
1388 }
1389 else if (more || i != conn->nconnhost)
1390 {
1392 libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
1394 return false;
1395 }
1396 }
1397
1398 /*
1399 * If user name was not given, fetch it. (Most likely, the fetch will
1400 * fail, since the only way we get here is if pg_fe_getauthname() failed
1401 * during conninfo_add_defaults(). But now we want an error message.)
1402 */
1403 if (conn->pguser == NULL || conn->pguser[0] == '\0')
1404 {
1405 free(conn->pguser);
1407 if (!conn->pguser)
1408 {
1410 return false;
1411 }
1412 }
1413
1414 /*
1415 * If database name was not given, default it to equal user name
1416 */
1417 if (conn->dbName == NULL || conn->dbName[0] == '\0')
1418 {
1419 free(conn->dbName);
1420 conn->dbName = strdup(conn->pguser);
1421 if (!conn->dbName)
1422 goto oom_error;
1423 }
1424
1425 /*
1426 * If password was not given, try to look it up in password file. Note
1427 * that the result might be different for each host/port pair.
1428 */
1429 if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1430 {
1431 /* If password file wasn't specified, use ~/PGPASSFILE */
1432 if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1433 {
1434 char homedir[MAXPGPATH];
1435
1436 if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1437 {
1440 if (!conn->pgpassfile)
1441 goto oom_error;
1442 snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1443 homedir, PGPASSFILE);
1444 }
1445 }
1446
1447 if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1448 {
1449 for (i = 0; i < conn->nconnhost; i++)
1450 {
1451 /*
1452 * Try to get a password for this host from file. We use host
1453 * for the hostname search key if given, else hostaddr (at
1454 * least one of them is guaranteed nonempty by now).
1455 */
1456 const char *pwhost = conn->connhost[i].host;
1457
1458 if (pwhost == NULL || pwhost[0] == '\0')
1459 pwhost = conn->connhost[i].hostaddr;
1460
1462 passwordFromFile(pwhost,
1463 conn->connhost[i].port,
1464 conn->dbName,
1465 conn->pguser,
1466 conn->pgpassfile);
1467 }
1468 }
1469 }
1470
1471 /*
1472 * parse and validate require_auth option
1473 */
1474 if (conn->require_auth && conn->require_auth[0])
1475 {
1476 char *s = conn->require_auth;
1477 bool first,
1478 more;
1479 bool negated = false;
1480
1481 /*
1482 * By default, start from an empty set of allowed methods and
1483 * mechanisms, and add to it.
1484 */
1485 conn->auth_required = true;
1488
1489 for (first = true, more = true; more; first = false)
1490 {
1491 char *method,
1492 *part;
1493 uint32 bits = 0;
1494 const pg_fe_sasl_mech *mech = NULL;
1495
1496 part = parse_comma_separated_list(&s, &more);
1497 if (part == NULL)
1498 goto oom_error;
1499
1500 /*
1501 * Check for negation, e.g. '!password'. If one element is
1502 * negated, they all have to be.
1503 */
1504 method = part;
1505 if (*method == '!')
1506 {
1507 if (first)
1508 {
1509 /*
1510 * Switch to a permissive set of allowed methods and
1511 * mechanisms, and subtract from it.
1512 */
1513 conn->auth_required = false;
1516 }
1517 else if (!negated)
1518 {
1520 libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
1521 method);
1522
1523 free(part);
1524 return false;
1525 }
1526
1527 negated = true;
1528 method++;
1529 }
1530 else if (negated)
1531 {
1533 libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
1534 method);
1535
1536 free(part);
1537 return false;
1538 }
1539
1540 /*
1541 * First group: methods that can be handled solely with the
1542 * authentication request codes.
1543 */
1544 if (strcmp(method, "password") == 0)
1545 {
1546 bits = (1 << AUTH_REQ_PASSWORD);
1547 }
1548 else if (strcmp(method, "md5") == 0)
1549 {
1550 bits = (1 << AUTH_REQ_MD5);
1551 }
1552 else if (strcmp(method, "gss") == 0)
1553 {
1554 bits = (1 << AUTH_REQ_GSS);
1555 bits |= (1 << AUTH_REQ_GSS_CONT);
1556 }
1557 else if (strcmp(method, "sspi") == 0)
1558 {
1559 bits = (1 << AUTH_REQ_SSPI);
1560 bits |= (1 << AUTH_REQ_GSS_CONT);
1561 }
1562
1563 /*
1564 * Next group: SASL mechanisms. All of these use the same request
1565 * codes, so the list of allowed mechanisms is tracked separately.
1566 *
1567 * supported_sasl_mechs must contain all mechanisms handled here.
1568 */
1569 else if (strcmp(method, "scram-sha-256") == 0)
1570 {
1571 mech = &pg_scram_mech;
1572 }
1573 else if (strcmp(method, "oauth") == 0)
1574 {
1575 mech = &pg_oauth_mech;
1576 }
1577
1578 /*
1579 * Final group: meta-options.
1580 */
1581 else if (strcmp(method, "none") == 0)
1582 {
1583 /*
1584 * Special case: let the user explicitly allow (or disallow)
1585 * connections where the server does not send an explicit
1586 * authentication challenge, such as "trust" and "cert" auth.
1587 */
1588 if (negated) /* "!none" */
1589 {
1590 if (conn->auth_required)
1591 goto duplicate;
1592
1593 conn->auth_required = true;
1594 }
1595 else /* "none" */
1596 {
1597 if (!conn->auth_required)
1598 goto duplicate;
1599
1600 conn->auth_required = false;
1601 }
1602
1603 free(part);
1604 continue; /* avoid the bitmask manipulation below */
1605 }
1606 else
1607 {
1609 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1610 "require_auth", method);
1611
1612 free(part);
1613 return false;
1614 }
1615
1616 if (mech)
1617 {
1618 /*
1619 * Update the mechanism set only. The method bitmask will be
1620 * updated for SASL further down.
1621 */
1622 Assert(!bits);
1623
1624 if (negated)
1625 {
1626 /* Remove the existing mechanism from the list. */
1628 if (i < 0)
1629 goto duplicate;
1630
1631 conn->allowed_sasl_mechs[i] = NULL;
1632 }
1633 else
1634 {
1635 /*
1636 * Find a space to put the new mechanism (after making
1637 * sure it's not already there).
1638 */
1640 if (i >= 0)
1641 goto duplicate;
1642
1644 if (i < 0)
1645 {
1646 /* Should not happen; the pointer list is corrupted. */
1647 Assert(false);
1648
1651 "internal error: no space in allowed_sasl_mechs");
1652 free(part);
1653 return false;
1654 }
1655
1656 conn->allowed_sasl_mechs[i] = mech;
1657 }
1658 }
1659 else
1660 {
1661 /* Update the method bitmask. */
1662 Assert(bits);
1663
1664 if (negated)
1665 {
1666 if ((conn->allowed_auth_methods & bits) == 0)
1667 goto duplicate;
1668
1669 conn->allowed_auth_methods &= ~bits;
1670 }
1671 else
1672 {
1673 if ((conn->allowed_auth_methods & bits) == bits)
1674 goto duplicate;
1675
1676 conn->allowed_auth_methods |= bits;
1677 }
1678 }
1679
1680 free(part);
1681 continue;
1682
1683 duplicate:
1684
1685 /*
1686 * A duplicated method probably indicates a typo in a setting
1687 * where typos are extremely risky.
1688 */
1690 libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
1691 part);
1692
1693 free(part);
1694 return false;
1695 }
1696
1697 /*
1698 * Finally, allow SASL authentication requests if (and only if) we've
1699 * allowed any mechanisms.
1700 */
1701 {
1702 bool allowed = false;
1703 const uint32 sasl_bits =
1704 (1 << AUTH_REQ_SASL)
1705 | (1 << AUTH_REQ_SASL_CONT)
1706 | (1 << AUTH_REQ_SASL_FIN);
1707
1708 for (i = 0; i < lengthof(conn->allowed_sasl_mechs); i++)
1709 {
1711 {
1712 allowed = true;
1713 break;
1714 }
1715 }
1716
1717 /*
1718 * For the standard case, add the SASL bits to the (default-empty)
1719 * set if needed. For the negated case, remove them.
1720 */
1721 if (!negated && allowed)
1722 conn->allowed_auth_methods |= sasl_bits;
1723 else if (negated && !allowed)
1724 conn->allowed_auth_methods &= ~sasl_bits;
1725 }
1726 }
1727
1728 /*
1729 * validate channel_binding option
1730 */
1731 if (conn->channel_binding)
1732 {
1733 if (strcmp(conn->channel_binding, "disable") != 0
1734 && strcmp(conn->channel_binding, "prefer") != 0
1735 && strcmp(conn->channel_binding, "require") != 0)
1736 {
1738 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1739 "channel_binding", conn->channel_binding);
1740 return false;
1741 }
1742 }
1743 else
1744 {
1746 if (!conn->channel_binding)
1747 goto oom_error;
1748 }
1749
1750#ifndef USE_SSL
1751
1752 /*
1753 * sslrootcert=system is not supported. Since setting this changes the
1754 * default sslmode, check this _before_ we validate sslmode, to avoid
1755 * confusing the user with errors for an option they may not have set.
1756 */
1757 if (conn->sslrootcert
1758 && strcmp(conn->sslrootcert, "system") == 0)
1759 {
1761 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1762 "sslrootcert", conn->sslrootcert);
1763 return false;
1764 }
1765#endif
1766
1767 /*
1768 * validate sslmode option
1769 */
1770 if (conn->sslmode)
1771 {
1772 if (strcmp(conn->sslmode, "disable") != 0
1773 && strcmp(conn->sslmode, "allow") != 0
1774 && strcmp(conn->sslmode, "prefer") != 0
1775 && strcmp(conn->sslmode, "require") != 0
1776 && strcmp(conn->sslmode, "verify-ca") != 0
1777 && strcmp(conn->sslmode, "verify-full") != 0)
1778 {
1780 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1781 "sslmode", conn->sslmode);
1782 return false;
1783 }
1784
1785#ifndef USE_SSL
1786 switch (conn->sslmode[0])
1787 {
1788 case 'a': /* "allow" */
1789 case 'p': /* "prefer" */
1790
1791 /*
1792 * warn user that an SSL connection will never be negotiated
1793 * since SSL was not compiled in?
1794 */
1795 break;
1796
1797 case 'r': /* "require" */
1798 case 'v': /* "verify-ca" or "verify-full" */
1800 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1801 "sslmode", conn->sslmode);
1802 return false;
1803 }
1804#endif
1805 }
1806 else
1807 {
1808 conn->sslmode = strdup(DefaultSSLMode);
1809 if (!conn->sslmode)
1810 goto oom_error;
1811 }
1812
1813 /*
1814 * validate sslnegotiation option, default is "postgres" for the postgres
1815 * style negotiated connection with an extra round trip but more options.
1816 */
1817 if (conn->sslnegotiation)
1818 {
1819 if (strcmp(conn->sslnegotiation, "postgres") != 0
1820 && strcmp(conn->sslnegotiation, "direct") != 0)
1821 {
1823 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1824 "sslnegotiation", conn->sslnegotiation);
1825 return false;
1826 }
1827
1828#ifndef USE_SSL
1829 if (conn->sslnegotiation[0] != 'p')
1830 {
1832 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1833 "sslnegotiation", conn->sslnegotiation);
1834 return false;
1835 }
1836#endif
1837
1838 /*
1839 * Don't allow direct SSL negotiation with sslmode='prefer', because
1840 * that poses a risk of unintentional fallback to plaintext connection
1841 * when connecting to a pre-v17 server that does not support direct
1842 * SSL connections. To keep things simple, don't allow it with
1843 * sslmode='allow' or sslmode='disable' either. If a user goes through
1844 * the trouble of setting sslnegotiation='direct', they probably
1845 * intend to use SSL, and sslmode=disable or allow is probably a user
1846 * mistake anyway.
1847 */
1848 if (conn->sslnegotiation[0] == 'd' &&
1849 conn->sslmode[0] != 'r' && conn->sslmode[0] != 'v')
1850 {
1852 libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
1853 conn->sslmode);
1854 return false;
1855 }
1856 }
1857 else
1858 {
1860 if (!conn->sslnegotiation)
1861 goto oom_error;
1862 }
1863
1864#ifdef USE_SSL
1865
1866 /*
1867 * If sslrootcert=system, make sure our chosen sslmode is compatible.
1868 */
1869 if (conn->sslrootcert
1870 && strcmp(conn->sslrootcert, "system") == 0
1871 && strcmp(conn->sslmode, "verify-full") != 0)
1872 {
1874 libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")",
1875 conn->sslmode);
1876 return false;
1877 }
1878#endif
1879
1880 /*
1881 * Validate TLS protocol versions for ssl_min_protocol_version and
1882 * ssl_max_protocol_version.
1883 */
1885 {
1887 libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
1888 "ssl_min_protocol_version",
1890 return false;
1891 }
1893 {
1895 libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
1896 "ssl_max_protocol_version",
1898 return false;
1899 }
1900
1901 /*
1902 * Check if the range of SSL protocols defined is correct. This is done
1903 * at this early step because this is independent of the SSL
1904 * implementation used, and this avoids unnecessary cycles with an
1905 * already-built SSL context when the connection is being established, as
1906 * it would be doomed anyway.
1907 */
1910 {
1912 libpq_append_conn_error(conn, "invalid SSL protocol version range");
1913 return false;
1914 }
1915
1916 /*
1917 * validate sslcertmode option
1918 */
1919 if (conn->sslcertmode)
1920 {
1921 if (strcmp(conn->sslcertmode, "disable") != 0 &&
1922 strcmp(conn->sslcertmode, "allow") != 0 &&
1923 strcmp(conn->sslcertmode, "require") != 0)
1924 {
1926 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1927 "sslcertmode", conn->sslcertmode);
1928 return false;
1929 }
1930#ifndef USE_SSL
1931 if (strcmp(conn->sslcertmode, "require") == 0)
1932 {
1934 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1935 "sslcertmode", conn->sslcertmode);
1936 return false;
1937 }
1938#endif
1939#ifndef HAVE_SSL_CTX_SET_CERT_CB
1940
1941 /*
1942 * Without a certificate callback, the current implementation can't
1943 * figure out if a certificate was actually requested, so "require" is
1944 * useless.
1945 */
1946 if (strcmp(conn->sslcertmode, "require") == 0)
1947 {
1949 libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
1950 "sslcertmode", conn->sslcertmode);
1951 return false;
1952 }
1953#endif
1954 }
1955 else
1956 {
1958 if (!conn->sslcertmode)
1959 goto oom_error;
1960 }
1961
1962 /*
1963 * validate gssencmode option
1964 */
1965 if (conn->gssencmode)
1966 {
1967 if (strcmp(conn->gssencmode, "disable") != 0 &&
1968 strcmp(conn->gssencmode, "prefer") != 0 &&
1969 strcmp(conn->gssencmode, "require") != 0)
1970 {
1972 libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
1973 return false;
1974 }
1975#ifndef ENABLE_GSS
1976 if (strcmp(conn->gssencmode, "require") == 0)
1977 {
1979 libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
1980 conn->gssencmode);
1981 return false;
1982 }
1983#endif
1984 }
1985 else
1986 {
1987 conn->gssencmode = strdup(DefaultGSSMode);
1988 if (!conn->gssencmode)
1989 goto oom_error;
1990 }
1991
1992 /*
1993 * validate target_session_attrs option, and set target_server_type
1994 */
1996 {
1997 if (strcmp(conn->target_session_attrs, "any") == 0)
1999 else if (strcmp(conn->target_session_attrs, "read-write") == 0)
2001 else if (strcmp(conn->target_session_attrs, "read-only") == 0)
2003 else if (strcmp(conn->target_session_attrs, "primary") == 0)
2005 else if (strcmp(conn->target_session_attrs, "standby") == 0)
2007 else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
2009 else
2010 {
2012 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
2013 "target_session_attrs",
2015 return false;
2016 }
2017 }
2018 else
2020
2022 {
2023 int len;
2024
2028 goto oom_error;
2031 if (len < 0)
2032 {
2033 libpq_append_conn_error(conn, "invalid SCRAM client key");
2034 return false;
2035 }
2036 if (len != SCRAM_MAX_KEY_LEN)
2037 {
2038 libpq_append_conn_error(conn, "invalid SCRAM client key length: %d", len);
2039 return false;
2040 }
2042 }
2043
2045 {
2046 int len;
2047
2051 goto oom_error;
2054 if (len < 0)
2055 {
2056 libpq_append_conn_error(conn, "invalid SCRAM server key");
2057 return false;
2058 }
2059 if (len != SCRAM_MAX_KEY_LEN)
2060 {
2061 libpq_append_conn_error(conn, "invalid SCRAM server key length: %d", len);
2062 return false;
2063 }
2065 }
2066
2067 /*
2068 * validate load_balance_hosts option, and set load_balance_type
2069 */
2071 {
2072 if (strcmp(conn->load_balance_hosts, "disable") == 0)
2074 else if (strcmp(conn->load_balance_hosts, "random") == 0)
2076 else
2077 {
2079 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
2080 "load_balance_hosts",
2082 return false;
2083 }
2084 }
2085 else
2087
2089 {
2091
2092 /*
2093 * This is the "inside-out" variant of the Fisher-Yates shuffle
2094 * algorithm. Notionally, we append each new value to the array and
2095 * then swap it with a randomly-chosen array element (possibly
2096 * including itself, else we fail to generate permutations with the
2097 * last integer last). The swap step can be optimized by combining it
2098 * with the insertion.
2099 */
2100 for (i = 1; i < conn->nconnhost; i++)
2101 {
2102 int j = pg_prng_uint64_range(&conn->prng_state, 0, i);
2103 pg_conn_host temp = conn->connhost[j];
2104
2105 conn->connhost[j] = conn->connhost[i];
2106 conn->connhost[i] = temp;
2107 }
2108 }
2109
2111 {
2112 if (!pqParseProtocolVersion(conn->min_protocol_version, &conn->min_pversion, conn, "min_protocol_version"))
2113 {
2115 return false;
2116 }
2117 }
2118 else
2119 {
2121 }
2122
2124 {
2125 if (!pqParseProtocolVersion(conn->max_protocol_version, &conn->max_pversion, conn, "max_protocol_version"))
2126 {
2128 return false;
2129 }
2130 }
2131 else
2132 {
2133 /*
2134 * To not break connecting to older servers/poolers that do not yet
2135 * support NegotiateProtocolVersion, default to the 3.0 protocol at
2136 * least for a while longer. Except when min_protocol_version is set
2137 * to something larger, then we might as well default to the latest.
2138 */
2139 if (conn->min_pversion > PG_PROTOCOL(3, 0))
2141 else
2142 conn->max_pversion = PG_PROTOCOL(3, 0);
2143 }
2144
2146 {
2148 libpq_append_conn_error(conn, "\"%s\" is greater than \"%s\"", "min_protocol_version", "max_protocol_version");
2149 return false;
2150 }
2151
2152 /*
2153 * Resolve special "auto" client_encoding from the locale
2154 */
2156 strcmp(conn->client_encoding_initial, "auto") == 0)
2157 {
2161 goto oom_error;
2162 }
2163
2164 /*
2165 * Only if we get this far is it appropriate to try to connect. (We need a
2166 * state flag, rather than just the boolean result of this function, in
2167 * case someone tries to PQreset() the PGconn.)
2168 */
2169 conn->options_valid = true;
2170
2171 return true;
2172
2173oom_error:
2175 libpq_append_conn_error(conn, "out of memory");
2176 return false;
2177}
int pg_b64_dec_len(int srclen)
Definition: base64.c:239
int pg_b64_decode(const char *src, int len, uint8 *dst, int dstlen)
Definition: base64.c:116
uint32_t uint32
Definition: c.h:539
#define lengthof(array)
Definition: c.h:788
const pg_fe_sasl_mech pg_oauth_mech
Definition: fe-auth-oauth.c:40
const pg_fe_sasl_mech pg_scram_mech
Definition: fe-auth-scram.c:33
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1344
static bool pqParseProtocolVersion(const char *value, ProtocolVersion *result, PGconn *conn, const char *context)
Definition: fe-connect.c:8282
#define DefaultHost
Definition: fe-connect.c:119
static char * passwordFromFile(const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile)
Definition: fe-connect.c:7947
static bool sslVerifyProtocolRange(const char *min, const char *max)
Definition: fe-connect.c:8143
static void libpq_prng_init(PGconn *conn)
Definition: fe-connect.c:1172
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:8196
#define DefaultSSLMode
Definition: fe-connect.c:132
#define DefaultGSSMode
Definition: fe-connect.c:140
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:1113
static void clear_allowed_sasl_mechs(PGconn *conn)
Definition: fe-connect.c:1219
static void fill_allowed_sasl_mechs(PGconn *conn)
Definition: fe-connect.c:1195
#define DefaultChannelBinding
Definition: fe-connect.c:124
static int index_of_allowed_sasl_mech(PGconn *conn, const pg_fe_sasl_mech *mech)
Definition: fe-connect.c:1230
static bool sslVerifyProtocolVersion(const char *version)
Definition: fe-connect.c:8117
#define DefaultSSLNegotiation
Definition: fe-connect.c:135
#define PGPASSFILE
Definition: fe-connect.c:78
#define DefaultSSLCertMode
Definition: fe-connect.c:133
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:1137
#define calloc(a, b)
Definition: header.h:55
int j
Definition: isn.c:78
#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:239
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:301
#define PG_PROTOCOL_EARLIEST
Definition: pqcomm.h:96
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:67
#define PG_PROTOCOL_LATEST
Definition: pqcomm.h:97
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:90
#define AUTH_REQ_SSPI
Definition: protocol.h:105
#define AUTH_REQ_SASL_CONT
Definition: protocol.h:107
#define AUTH_REQ_GSS
Definition: protocol.h:103
#define AUTH_REQ_MD5
Definition: protocol.h:101
#define AUTH_REQ_PASSWORD
Definition: protocol.h:99
#define AUTH_REQ_GSS_CONT
Definition: protocol.h:104
#define AUTH_REQ_SASL
Definition: protocol.h:106
#define AUTH_REQ_SASL_FIN
Definition: protocol.h:108
#define SCRAM_MAX_KEY_LEN
Definition: scram-common.h:30
char * password
Definition: libpq-int.h:362
char * port
Definition: libpq-int.h:360
char * hostaddr
Definition: libpq-int.h:359
pg_conn_host_type type
Definition: libpq-int.h:357
uint8 * scram_client_key_binary
Definition: libpq-int.h:545
char * sslrootcert
Definition: libpq-int.h:413
char * sslnegotiation
Definition: libpq-int.h:407
int nconnhost
Definition: libpq-int.h:480
char * require_auth
Definition: libpq-int.h:428
char * channel_binding
Definition: libpq-int.h:398
char * pghost
Definition: libpq-int.h:374
size_t scram_client_key_len
Definition: libpq-int.h:544
char * ssl_max_protocol_version
Definition: libpq-int.h:426
uint8 * scram_server_key_binary
Definition: libpq-int.h:547
char * pgpass
Definition: libpq-int.h:396
ProtocolVersion min_pversion
Definition: libpq-int.h:548
char * dbName
Definition: libpq-int.h:390
char * sslcertmode
Definition: libpq-int.h:412
uint32 allowed_auth_methods
Definition: libpq-int.h:517
char * target_session_attrs
Definition: libpq-int.h:427
bool auth_required
Definition: libpq-int.h:515
char * max_protocol_version
Definition: libpq-int.h:424
char * load_balance_hosts
Definition: libpq-int.h:429
char * pguser
Definition: libpq-int.h:395
char * min_protocol_version
Definition: libpq-int.h:423
char * client_encoding_initial
Definition: libpq-int.h:386
char * sslmode
Definition: libpq-int.h:406
pg_prng_state prng_state
Definition: libpq-int.h:563
char * ssl_min_protocol_version
Definition: libpq-int.h:425
char * gssencmode
Definition: libpq-int.h:418
char * scram_server_key
Definition: libpq-int.h:431
char * pghostaddr
Definition: libpq-int.h:378
char * scram_client_key
Definition: libpq-int.h:430
ProtocolVersion max_pversion
Definition: libpq-int.h:549
char * pgpassfile
Definition: libpq-int.h:397
PGLoadBalanceType load_balance_type
Definition: libpq-int.h:535
size_t scram_server_key_len
Definition: libpq-int.h:546
char * pgport
Definition: libpq-int.h:382
const pg_fe_sasl_mech * allowed_sasl_mechs[2]
Definition: libpq-int.h:519

References pg_conn::allowed_auth_methods, pg_conn::allowed_sasl_mechs, 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, clear_allowed_sasl_mechs(), 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, fill_allowed_sasl_mechs(), free, pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, index_of_allowed_sasl_mech(), is_unixsock_path(), j, len, lengthof, libpq_append_conn_error(), libpq_prng_init(), LOAD_BALANCE_DISABLE, pg_conn::load_balance_hosts, LOAD_BALANCE_RANDOM, pg_conn::load_balance_type, malloc, pg_conn::max_protocol_version, pg_conn::max_pversion, MAXPGPATH, pg_conn::min_protocol_version, pg_conn::min_pversion, pg_conn::nconnhost, pg_conn::options_valid, parse_comma_separated_list(), pg_conn_host::password, passwordFromFile(), pg_b64_dec_len(), pg_b64_decode(), pg_encoding_to_char, pg_fe_getauthname(), pg_get_encoding_from_locale(), pg_oauth_mech, pg_prng_uint64_range(), PG_PROTOCOL, PG_PROTOCOL_EARLIEST, PG_PROTOCOL_LATEST, pg_scram_mech, pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgpass, PGPASSFILE, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pguser, pg_conn_host::port, pqGetHomeDirectory(), pqParseProtocolVersion(), pg_conn::prng_state, pg_conn::require_auth, pg_conn::scram_client_key, pg_conn::scram_client_key_binary, pg_conn::scram_client_key_len, SCRAM_MAX_KEY_LEN, pg_conn::scram_server_key, pg_conn::scram_server_key_binary, pg_conn::scram_server_key_len, 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 1035 of file fe-connect.c.

1036{
1038
1039 /* copy over connection options */
1040 for (option = PQconninfoOptions; option->keyword; option++)
1041 {
1042 if (option->connofs >= 0)
1043 {
1044 const char **tmp = (const char **) ((char *) srcConn + option->connofs);
1045
1046 if (*tmp)
1047 {
1048 char **dstConnmember = (char **) ((char *) dstConn + option->connofs);
1049
1050 if (*dstConnmember)
1051 free(*dstConnmember);
1052 *dstConnmember = strdup(*tmp);
1053 if (*dstConnmember == NULL)
1054 {
1055 libpq_append_conn_error(dstConn, "out of memory");
1056 return false;
1057 }
1058 }
1059 }
1060 }
1061 return true;
1062}
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:199

References free, libpq_append_conn_error(), and PQconninfoOptions.

Referenced by PQcancelCreate().

◆ pqDropConnection()

void pqDropConnection ( PGconn conn,
bool  flushInput 
)

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

531{
532 /* Drop any SSL state */
534
535 /* Close the socket itself */
536 if (conn->sock != PGINVALID_SOCKET)
539
540 /* Optionally discard any unread data */
541 if (flushInput)
542 conn->inStart = conn->inCursor = conn->inEnd = 0;
543
544 /* Always discard any unsent data */
545 conn->outCount = 0;
546
547 /* Likewise, discard any pending pipelined commands */
551 conn->cmd_queue_recycle = NULL;
552
553 /* Free authentication/encryption state */
555 {
556 /*
557 * Any in-progress async authentication should be torn down first so
558 * that cleanup_async_auth() can depend on the other authentication
559 * state if necessary.
560 */
562 conn->cleanup_async_auth = NULL;
563 }
564 conn->async_auth = NULL;
565 /* cleanup_async_auth() should have done this, but make sure */
567#ifdef ENABLE_GSS
568 {
569 OM_uint32 min_s;
570
571 if (conn->gcred != GSS_C_NO_CREDENTIAL)
572 {
573 gss_release_cred(&min_s, &conn->gcred);
574 conn->gcred = GSS_C_NO_CREDENTIAL;
575 }
576 if (conn->gctx)
577 gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
578 if (conn->gtarg_nam)
579 gss_release_name(&min_s, &conn->gtarg_nam);
580 if (conn->gss_SendBuffer)
581 {
582 free(conn->gss_SendBuffer);
583 conn->gss_SendBuffer = NULL;
584 }
585 if (conn->gss_RecvBuffer)
586 {
587 free(conn->gss_RecvBuffer);
588 conn->gss_RecvBuffer = NULL;
589 }
590 if (conn->gss_ResultBuffer)
591 {
592 free(conn->gss_ResultBuffer);
593 conn->gss_ResultBuffer = NULL;
594 }
595 conn->gssenc = false;
596 }
597#endif
598#ifdef ENABLE_SSPI
599 if (conn->sspitarget)
600 {
601 free(conn->sspitarget);
602 conn->sspitarget = NULL;
603 }
604 if (conn->sspicred)
605 {
606 FreeCredentialsHandle(conn->sspicred);
607 free(conn->sspicred);
608 conn->sspicred = NULL;
609 }
610 if (conn->sspictx)
611 {
612 DeleteSecurityContext(conn->sspictx);
613 free(conn->sspictx);
614 conn->sspictx = NULL;
615 }
616 conn->usesspi = 0;
617#endif
618 if (conn->sasl_state)
619 {
621 conn->sasl_state = NULL;
622 }
623}
static void pqFreeCommandQueue(PGcmdQueueEntry *queue)
Definition: fe-connect.c:630
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:152
#define PGINVALID_SOCKET
Definition: port.h:31
#define closesocket
Definition: port.h:377
pgsocket sock
Definition: libpq-int.h:499
const pg_fe_sasl_mech * sasl
Definition: libpq-int.h:602
void(* cleanup_async_auth)(PGconn *conn)
Definition: libpq-int.h:529
PGcmdQueueEntry * cmd_queue_recycle
Definition: libpq-int.h:496
pgsocket altsock
Definition: libpq-int.h:530
PostgresPollingStatusType(* async_auth)(PGconn *conn)
Definition: libpq-int.h:528
void * sasl_state
Definition: libpq-int.h:603
void(* free)(void *state)
Definition: fe-auth-sasl.h:149

References pg_conn::altsock, pg_conn::async_auth, pg_conn::cleanup_async_auth, 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 handleFatalError(), pqClosePGconn(), pqConnectDBStart(), PQconnectPoll(), and pqReadData().

◆ pqEndcopy3()

int pqEndcopy3 ( PGconn conn)

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

2050{
2051 PGresult *result;
2052
2056 {
2057 libpq_append_conn_error(conn, "no COPY in progress");
2058 return 1;
2059 }
2060
2061 /* Send the CopyDone message if needed */
2064 {
2065 if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
2066 pqPutMsgEnd(conn) < 0)
2067 return 1;
2068
2069 /*
2070 * If we sent the COPY command in extended-query mode, we must issue a
2071 * Sync as well.
2072 */
2073 if (conn->cmd_queue_head &&
2075 {
2076 if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
2077 pqPutMsgEnd(conn) < 0)
2078 return 1;
2079 }
2080 }
2081
2082 /*
2083 * make sure no data is waiting to be sent, abort if we are non-blocking
2084 * and the flush fails
2085 */
2087 return 1;
2088
2089 /* Return to active duty */
2091
2092 /*
2093 * Non blocking connections may have to abort at this point. If everyone
2094 * played the game there should be no problem, but in error scenarios the
2095 * expected messages may not have arrived yet. (We are assuming that the
2096 * backend's packetizing will ensure that CommandComplete arrives along
2097 * with the CopyDone; are there corner cases where that doesn't happen?)
2098 */
2100 return 1;
2101
2102 /* Wait for the completion response */
2103 result = PQgetResult(conn);
2104
2105 /* Expecting a successful result */
2106 if (result && result->resultStatus == PGRES_COMMAND_OK)
2107 {
2108 PQclear(result);
2109 return 0;
2110 }
2111
2112 /*
2113 * Trouble. For backwards-compatibility reasons, we issue the error
2114 * message as if it were a notice (would be nice to get rid of this
2115 * silliness, but too many apps probably don't handle errors from
2116 * PQendcopy reasonably). Note that the app can still obtain the error
2117 * status from the PGconn object.
2118 */
2119 if (conn->errorMessage.len > 0)
2120 {
2121 /* We have to strip the trailing newline ... pain in neck... */
2122 char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
2123
2124 if (svLast == '\n')
2125 conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
2127 conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
2128 }
2129
2130 PQclear(result);
2131
2132 return 1;
2133}
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:938
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2042
int pqFlush(PGconn *conn)
Definition: fe-misc.c:994
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:473
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:532
#define PQgetResult
Definition: libpq-be-fe.h:246
#define PQclear
Definition: libpq-be-fe.h:245
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
#define pqIsnonblocking(conn)
Definition: libpq-int.h:930
#define PqMsg_CopyDone
Definition: protocol.h:64
#define PqMsg_Sync
Definition: protocol.h:27
PGNoticeHooks noticeHooks
Definition: libpq-int.h:454

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

995{
996 if (conn->outCount > 0)
997 {
998 if (conn->Pfdebug)
999 fflush(conn->Pfdebug);
1000
1001 return pqSendSome(conn, conn->outCount);
1002 }
1003
1004 return 0;
1005}
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:825
FILE * Pfdebug
Definition: libpq-int.h:450

References conn, 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(), PQsendCancelRequest(), 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 2142 of file fe-protocol3.c.

2146{
2147 bool needInput = false;
2149 char id;
2150 int msgLength;
2151 int avail;
2152 int i;
2153
2154 /* already validated by PQfn */
2156
2157 /* PQfn already validated connection state */
2158
2160 pqPutInt(fnid, 4, conn) < 0 || /* function id */
2161 pqPutInt(1, 2, conn) < 0 || /* # of format codes */
2162 pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
2163 pqPutInt(nargs, 2, conn) < 0) /* # of args */
2164 {
2165 /* error message should be set up already */
2166 return NULL;
2167 }
2168
2169 for (i = 0; i < nargs; ++i)
2170 { /* len.int4 + contents */
2171 if (pqPutInt(args[i].len, 4, conn))
2172 return NULL;
2173 if (args[i].len == -1)
2174 continue; /* it's NULL */
2175
2176 if (args[i].isint)
2177 {
2178 if (pqPutInt(args[i].u.integer, args[i].len, conn))
2179 return NULL;
2180 }
2181 else
2182 {
2183 if (pqPutnchar(args[i].u.ptr, args[i].len, conn))
2184 return NULL;
2185 }
2186 }
2187
2188 if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
2189 return NULL;
2190
2191 if (pqPutMsgEnd(conn) < 0 ||
2192 pqFlush(conn))
2193 return NULL;
2194
2195 for (;;)
2196 {
2197 if (needInput)
2198 {
2199 /* Wait for some data to arrive (or for the channel to close) */
2200 if (pqWait(true, false, conn) ||
2201 pqReadData(conn) < 0)
2202 break;
2203 }
2204
2205 /*
2206 * Scan the message. If we run out of data, loop around to try again.
2207 */
2208 needInput = true;
2209
2211 if (pqGetc(&id, conn))
2212 continue;
2213 if (pqGetInt(&msgLength, 4, conn))
2214 continue;
2215
2216 /*
2217 * Try to validate message type/length here. A length less than 4 is
2218 * definitely broken. Large lengths should only be believed for a few
2219 * message types.
2220 */
2221 if (msgLength < 4)
2222 {
2223 handleSyncLoss(conn, id, msgLength);
2224 break;
2225 }
2226 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
2227 {
2228 handleSyncLoss(conn, id, msgLength);
2229 break;
2230 }
2231
2232 /*
2233 * Can't process if message body isn't all here yet.
2234 */
2235 msgLength -= 4;
2236 avail = conn->inEnd - conn->inCursor;
2237 if (avail < msgLength)
2238 {
2239 /*
2240 * Before looping, enlarge the input buffer if needed to hold the
2241 * whole message. See notes in parseInput.
2242 */
2243 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2244 conn))
2245 {
2246 /*
2247 * Abandon the connection. There's not much else we can
2248 * safely do; we can't just ignore the message or we could
2249 * miss important changes to the connection state.
2250 * pqCheckInBufferSpace() already reported the error.
2251 */
2253 break;
2254 }
2255 continue;
2256 }
2257
2258 /*
2259 * We should see V or E response to the command, but might get N
2260 * and/or A notices first. We also need to swallow the final Z before
2261 * returning.
2262 */
2263 switch (id)
2264 {
2266 if (pqGetInt(actual_result_len, 4, conn))
2267 continue;
2268 if (*actual_result_len != -1)
2269 {
2270 if (result_is_int)
2271 {
2272 if (pqGetInt(result_buf, *actual_result_len, conn))
2273 continue;
2274 }
2275 else
2276 {
2277 if (pqGetnchar(result_buf,
2278 *actual_result_len,
2279 conn))
2280 continue;
2281 }
2282 }
2283 /* correctly finished function result message */
2284 status = PGRES_COMMAND_OK;
2285 break;
2287 if (pqGetErrorNotice3(conn, true))
2288 continue;
2289 status = PGRES_FATAL_ERROR;
2290 break;
2292 /* handle notify and go back to processing return values */
2293 if (getNotify(conn))
2294 continue;
2295 break;
2297 /* handle notice and go back to processing return values */
2298 if (pqGetErrorNotice3(conn, false))
2299 continue;
2300 break;
2303 continue;
2304
2305 /* consume the message */
2306 pqParseDone(conn, conn->inStart + 5 + msgLength);
2307
2308 /*
2309 * If we already have a result object (probably an error), use
2310 * that. Otherwise, if we saw a function result message,
2311 * report COMMAND_OK. Otherwise, the backend violated the
2312 * protocol, so complain.
2313 */
2315 {
2316 if (status == PGRES_COMMAND_OK)
2317 {
2318 conn->result = PQmakeEmptyPGresult(conn, status);
2319 if (!conn->result)
2320 {
2321 libpq_append_conn_error(conn, "out of memory");
2323 }
2324 }
2325 else
2326 {
2327 libpq_append_conn_error(conn, "protocol error: no function result");
2329 }
2330 }
2331 /* and we're out */
2332 return pqPrepareAsyncResult(conn);
2335 continue;
2336 break;
2337 default:
2338 /* The backend violates the protocol. */
2339 libpq_append_conn_error(conn, "protocol error: id=0x%x", id);
2341
2342 /*
2343 * We can't call parsing done due to the protocol violation
2344 * (so message tracing wouldn't work), but trust the specified
2345 * message length as what to skip.
2346 */
2347 conn->inStart += 5 + msgLength;
2348 return pqPrepareAsyncResult(conn);
2349 }
2350
2351 /* Completed parsing this message, keep going */
2352 pqParseDone(conn, conn->inStart + 5 + msgLength);
2353 needInput = false;
2354 }
2355
2356 /*
2357 * We fall out of the loop only upon failing to read data.
2358 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2359 * append it to any already-received error message.
2360 */
2362 return pqPrepareAsyncResult(conn);
2363}
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:851
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:803
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:159
int pqReadData(PGconn *conn)
Definition: fe-misc.c:606
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:253
void pqParseDone(PGconn *conn, int newInStart)
Definition: fe-misc.c:443
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 pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:1019
int pqPutnchar(const void *s, size_t len, PGconn *conn)
Definition: fe-misc.c:202
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:351
int pqGetnchar(void *s, size_t len, PGconn *conn)
Definition: fe-misc.c:165
static int getNotify(PGconn *conn)
static int getParameterStatus(PGconn *conn)
static void handleFatalError(PGconn *conn)
Definition: fe-protocol3.c:485
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:36
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:501
static int getReadyForQuery(PGconn *conn)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:896
ExecStatusType
Definition: libpq-fe.h:123
#define pgHavePendingResult(conn)
Definition: libpq-int.h:923
#define PqMsg_NotificationResponse
Definition: protocol.h:41
#define PqMsg_FunctionCall
Definition: protocol.h:23
#define PqMsg_FunctionCallResponse
Definition: protocol.h:53
#define PqMsg_ReadyForQuery
Definition: protocol.h:55
#define PqMsg_ParameterStatus
Definition: protocol.h:51
#define PqMsg_ErrorResponse
Definition: protocol.h:44
#define PqMsg_NoticeResponse
Definition: protocol.h:49

References generate_unaccent_rules::args, Assert(), conn, getNotify(), getParameterStatus(), getReadyForQuery(), handleFatalError(), handleSyncLoss(), i, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, len, libpq_append_conn_error(), pgHavePendingResult, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), PQmakeEmptyPGresult(), PqMsg_ErrorResponse, PqMsg_FunctionCall, PqMsg_FunctionCallResponse, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterStatus, PqMsg_ReadyForQuery, pqParseDone(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), 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 1884 of file fe-protocol3.c.

1885{
1886 int msgLength;
1887
1888 for (;;)
1889 {
1890 /*
1891 * Collect the next input message. To make life simpler for async
1892 * callers, we keep returning 0 until the next message is fully
1893 * available, even if it is not Copy Data.
1894 */
1895 msgLength = getCopyDataMessage(conn);
1896 if (msgLength < 0)
1897 return msgLength; /* end-of-copy or error */
1898 if (msgLength == 0)
1899 {
1900 /* Don't block if async read requested */
1901 if (async)
1902 return 0;
1903 /* Need to load more data */
1904 if (pqWait(true, false, conn) ||
1905 pqReadData(conn) < 0)
1906 return -2;
1907 continue;
1908 }
1909
1910 /*
1911 * Drop zero-length messages (shouldn't happen anyway). Otherwise
1912 * pass the data back to the caller.
1913 */
1914 msgLength -= 4;
1915 if (msgLength > 0)
1916 {
1917 *buffer = (char *) malloc(msgLength + 1);
1918 if (*buffer == NULL)
1919 {
1920 libpq_append_conn_error(conn, "out of memory");
1921 return -2;
1922 }
1923 memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1924 (*buffer)[msgLength] = '\0'; /* Add terminating null */
1925
1926 /* Mark message consumed */
1927 pqParseDone(conn, conn->inCursor + msgLength);
1928
1929 return msgLength;
1930 }
1931
1932 /* Empty, so drop it and loop around for another */
1934 }
1935}
static int getCopyDataMessage(PGconn *conn)

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

Referenced by PQgetCopyData().

◆ pqGetErrorNotice3()

int pqGetErrorNotice3 ( PGconn conn,
bool  isError 
)

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

897{
898 PGresult *res = NULL;
899 bool have_position = false;
900 PQExpBufferData workBuf;
901 char id;
902
903 /* If in pipeline mode, set error indicator for it */
904 if (isError && conn->pipelineStatus != PQ_PIPELINE_OFF)
906
907 /*
908 * If this is an error message, pre-emptively clear any incomplete query
909 * result we may have. We'd just throw it away below anyway, and
910 * releasing it before collecting the error might avoid out-of-memory.
911 */
912 if (isError)
914
915 /*
916 * Since the fields might be pretty long, we create a temporary
917 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
918 * for stuff that is expected to be short. We shouldn't use
919 * conn->errorMessage either, since this might be only a notice.
920 */
921 initPQExpBuffer(&workBuf);
922
923 /*
924 * Make a PGresult to hold the accumulated fields. We temporarily lie
925 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
926 * copy conn->errorMessage.
927 *
928 * NB: This allocation can fail, if you run out of memory. The rest of the
929 * function handles that gracefully, and we still try to set the error
930 * message as the connection's error message.
931 */
933 if (res)
935
936 /*
937 * Read the fields and save into res.
938 *
939 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
940 * we saw a PG_DIAG_STATEMENT_POSITION field.
941 */
942 for (;;)
943 {
944 if (pqGetc(&id, conn))
945 goto fail;
946 if (id == '\0')
947 break; /* terminator found */
948 if (pqGets(&workBuf, conn))
949 goto fail;
950 pqSaveMessageField(res, id, workBuf.data);
951 if (id == PG_DIAG_SQLSTATE)
952 strlcpy(conn->last_sqlstate, workBuf.data,
953 sizeof(conn->last_sqlstate));
954 else if (id == PG_DIAG_STATEMENT_POSITION)
955 have_position = true;
956 }
957
958 /*
959 * Save the active query text, if any, into res as well; but only if we
960 * might need it for an error cursor display, which is only true if there
961 * is a PG_DIAG_STATEMENT_POSITION field.
962 */
963 if (have_position && res && conn->cmd_queue_head && conn->cmd_queue_head->query)
965
966 /*
967 * Now build the "overall" error message for PQresultErrorMessage.
968 */
969 resetPQExpBuffer(&workBuf);
971
972 /*
973 * Either save error as current async result, or just emit the notice.
974 */
975 if (isError)
976 {
977 pqClearAsyncResult(conn); /* redundant, but be safe */
978 if (res)
979 {
980 pqSetResultError(res, &workBuf, 0);
981 conn->result = res;
982 }
983 else
984 {
985 /* Fall back to using the internal-error processing paths */
986 conn->error_result = true;
987 }
988
989 if (PQExpBufferDataBroken(workBuf))
990 libpq_append_conn_error(conn, "out of memory");
991 else
993 }
994 else
995 {
996 /* if we couldn't allocate the result set, just discard the NOTICE */
997 if (res)
998 {
999 /*
1000 * We can cheat a little here and not copy the message. But if we
1001 * were unlucky enough to run out of memory while filling workBuf,
1002 * insert "out of memory", as in pqSetResultError.
1003 */
1004 if (PQExpBufferDataBroken(workBuf))
1005 res->errMsg = libpq_gettext("out of memory\n");
1006 else
1007 res->errMsg = workBuf.data;
1008 if (res->noticeHooks.noticeRec != NULL)
1010 PQclear(res);
1011 }
1012 }
1013
1014 termPQExpBuffer(&workBuf);
1015 return 0;
1016
1017fail:
1018 PQclear(res);
1019 termPQExpBuffer(&workBuf);
1020 return EOF;
1021}
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:124
@ PGRES_NONFATAL_ERROR
Definition: libpq-fe.h:135
@ PQ_PIPELINE_ABORTED
Definition: libpq-fe.h:189
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:149
void * noticeRecArg
Definition: libpq-int.h:150
PGVerbosity verbosity
Definition: libpq-int.h:560
char last_sqlstate[6]
Definition: libpq-int.h:465
PGContextVisibility show_context
Definition: libpq-int.h:561
PGNoticeHooks noticeHooks
Definition: libpq-int.h:183

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, 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 8196 of file fe-connect.c.

8197{
8198#ifndef WIN32
8199 const char *home;
8200
8201 home = getenv("HOME");
8202 if (home && home[0])
8203 {
8204 strlcpy(buf, home, bufsize);
8205 return true;
8206 }
8207 else
8208 {
8209 struct passwd pwbuf;
8210 struct passwd *pw;
8211 char tmpbuf[1024];
8212 int rc;
8213
8214 rc = getpwuid_r(geteuid(), &pwbuf, tmpbuf, sizeof tmpbuf, &pw);
8215 if (rc != 0 || !pw)
8216 return false;
8217 strlcpy(buf, pw->pw_dir, bufsize);
8218 return true;
8219 }
8220#else
8221 char tmppath[MAX_PATH];
8222
8223 ZeroMemory(tmppath, sizeof(tmppath));
8224 if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
8225 return false;
8226 snprintf(buf, bufsize, "%s/postgresql", tmppath);
8227 return true;
8228#endif
8229}
#define bufsize
Definition: indent_globs.h:36
static char * buf
Definition: pg_test_fsync.c:72
static StringInfoData tmpbuf
Definition: walsender.c:178

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

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}
uint16_t uint16
Definition: c.h:538
#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(), getBackendKeyData(), getCopyDataMessage(), getCopyStart(), getNotify(), getParamDescriptions(), getRowDescriptions(), PQconnectPoll(), pqFunctionCall3(), pqGetNegotiateProtocolVersion3(), and pqParseInput3().

◆ pqGetline3()

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

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

1944{
1945 int status;
1946
1947 if (conn->sock == PGINVALID_SOCKET ||
1951 {
1952 libpq_append_conn_error(conn, "PQgetline: not doing text COPY OUT");
1953 *s = '\0';
1954 return EOF;
1955 }
1956
1957 while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1958 {
1959 /* need to load more data */
1960 if (pqWait(true, false, conn) ||
1961 pqReadData(conn) < 0)
1962 {
1963 *s = '\0';
1964 return EOF;
1965 }
1966 }
1967
1968 if (status < 0)
1969 {
1970 /* End of copy detected; gin up old-style terminator */
1971 strcpy(s, "\\.");
1972 return 0;
1973 }
1974
1975 /* Add null terminator, and strip trailing \n if present */
1976 if (s[status - 1] == '\n')
1977 {
1978 s[status - 1] = '\0';
1979 return 0;
1980 }
1981 else
1982 {
1983 s[status] = '\0';
1984 return 1;
1985 }
1986}
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2912
char copy_is_binary
Definition: libpq-int.h:474

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

1995{
1996 int msgLength;
1997 int avail;
1998
2001 return -1; /* we are not doing a copy... */
2002
2003 /*
2004 * Recognize the next input message. To make life simpler for async
2005 * callers, we keep returning 0 until the next message is fully available
2006 * even if it is not Copy Data. This should keep PQendcopy from blocking.
2007 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
2008 */
2009 msgLength = getCopyDataMessage(conn);
2010 if (msgLength < 0)
2011 return -1; /* end-of-copy or error */
2012 if (msgLength == 0)
2013 return 0; /* no data yet */
2014
2015 /*
2016 * Move data from libpq's buffer to the caller's. In the case where a
2017 * prior call found the caller's buffer too small, we use
2018 * conn->copy_already_done to remember how much of the row was already
2019 * returned to the caller.
2020 */
2022 avail = msgLength - 4 - conn->copy_already_done;
2023 if (avail <= bufsize)
2024 {
2025 /* Able to consume the whole message */
2026 memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
2027 /* Mark message consumed */
2028 conn->inStart = conn->inCursor + avail;
2029 /* Reset state for next time */
2031 return avail;
2032 }
2033 else
2034 {
2035 /* We must return a partial message */
2036 memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
2037 /* The message is NOT consumed from libpq's buffer */
2039 return bufsize;
2040 }
2041}
int copy_already_done
Definition: libpq-int.h:475

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 ( void *  s,
size_t  len,
PGconn conn 
)

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

166{
167 if (len > (size_t) (conn->inEnd - conn->inCursor))
168 return EOF;
169
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 getBackendKeyData(), pg_password_sendauth(), pg_SASL_continue(), and pqFunctionCall3().

◆ pqGetNegotiateProtocolVersion3()

int pqGetNegotiateProtocolVersion3 ( PGconn conn)

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

1429{
1430 int their_version;
1431 int num;
1432
1433 if (pqGetInt(&their_version, 4, conn) != 0)
1434 goto eof;
1435
1436 if (pqGetInt(&num, 4, conn) != 0)
1437 goto eof;
1438
1439 /* Check the protocol version */
1440 if (their_version > conn->pversion)
1441 {
1442 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");
1443 goto failure;
1444 }
1445
1446 if (their_version < PG_PROTOCOL(3, 0))
1447 {
1448 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version");
1449 goto failure;
1450 }
1451
1452 /* 3.1 never existed, we went straight from 3.0 to 3.2 */
1453 if (their_version == PG_PROTOCOL(3, 1))
1454 {
1455 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version");
1456 goto failure;
1457 }
1458
1459 if (num < 0)
1460 {
1461 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported negative number of unsupported parameters");
1462 goto failure;
1463 }
1464
1465 if (their_version == conn->pversion && num == 0)
1466 {
1467 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server negotiated but asks for no changes");
1468 goto failure;
1469 }
1470
1471 if (their_version < conn->min_pversion)
1472 {
1473 libpq_append_conn_error(conn, "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d",
1474 PG_PROTOCOL_MAJOR(their_version),
1475 PG_PROTOCOL_MINOR(their_version),
1476 "min_protocol_version",
1479
1480 goto failure;
1481 }
1482
1483 /* the version is acceptable */
1484 conn->pversion = their_version;
1485
1486 /*
1487 * We don't currently request any protocol extensions, so we don't expect
1488 * the server to reply with any either.
1489 */
1490 for (int i = 0; i < num; i++)
1491 {
1492 if (pqGets(&conn->workBuffer, conn))
1493 {
1494 goto eof;
1495 }
1496 if (strncmp(conn->workBuffer.data, "_pq_.", 5) != 0)
1497 {
1498 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported unsupported parameter name without a \"%s\" prefix (\"%s\")", "_pq_.", conn->workBuffer.data);
1499 goto failure;
1500 }
1501 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")", conn->workBuffer.data);
1502 goto failure;
1503 }
1504
1505 return 0;
1506
1507eof:
1508 libpq_append_conn_error(conn, "received invalid protocol negotiation message: message too short");
1509failure:
1512 return 1;
1513}
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:87
#define PG_PROTOCOL_MINOR(v)
Definition: pqcomm.h:88
ProtocolVersion pversion
Definition: libpq-int.h:503
PQExpBufferData workBuffer
Definition: libpq-int.h:678

References pg_conn::asyncStatus, conn, PQExpBufferData::data, i, libpq_append_conn_error(), pg_conn::min_pversion, PG_PROTOCOL, PG_PROTOCOL_MAJOR, PG_PROTOCOL_MINOR, PGASYNC_READY, pqGetInt(), pqGets(), pqSaveErrorResult(), pg_conn::pversion, 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 4943 of file fe-connect.c.

4944{
4945 PGconn *conn;
4946
4947#ifdef WIN32
4948
4949 /*
4950 * Make sure socket support is up and running in this process.
4951 *
4952 * Note: the Windows documentation says that we should eventually do a
4953 * matching WSACleanup() call, but experience suggests that that is at
4954 * least as likely to cause problems as fix them. So we don't.
4955 */
4956 static bool wsastartup_done = false;
4957
4958 if (!wsastartup_done)
4959 {
4960 WSADATA wsaData;
4961
4962 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4963 return NULL;
4964 wsastartup_done = true;
4965 }
4966
4967 /* Forget any earlier error */
4968 WSASetLastError(0);
4969#endif /* WIN32 */
4970
4971 conn = (PGconn *) malloc(sizeof(PGconn));
4972 if (conn == NULL)
4973 return conn;
4974
4975 /* Zero all pointers and booleans */
4976 MemSet(conn, 0, sizeof(PGconn));
4977
4978 /* install default notice hooks */
4981
4986 conn->options_valid = false;
4987 conn->nonblocking = false;
4989 conn->std_strings = false; /* unless server says differently */
4997 conn->Pfdebug = NULL;
4998
4999 /*
5000 * We try to send at least 8K at a time, which is the usual size of pipe
5001 * buffers on Unix systems. That way, when we are sending a large amount
5002 * of data, we avoid incurring extra kernel context swaps for partial
5003 * bufferloads. The output buffer is initially made 16K in size, and we
5004 * try to dump it after accumulating 8K.
5005 *
5006 * With the same goal of minimizing context swaps, the input buffer will
5007 * be enlarged anytime it has less than 8K free, so we initially allocate
5008 * twice that.
5009 */
5010 conn->inBufSize = 16 * 1024;
5011 conn->inBuffer = (char *) malloc(conn->inBufSize);
5012 conn->outBufSize = 16 * 1024;
5013 conn->outBuffer = (char *) malloc(conn->outBufSize);
5014 conn->rowBufLen = 32;
5018
5019 if (conn->inBuffer == NULL ||
5020 conn->outBuffer == NULL ||
5021 conn->rowBuf == NULL ||
5024 {
5025 /* out of memory already :-( */
5027 conn = NULL;
5028 }
5029
5030 return conn;
5031}
#define MemSet(start, val, len)
Definition: c.h:1020
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7883
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7898
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:5043
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:157
@ PG_BOOL_UNKNOWN
Definition: oauth-utils.h:73
@ 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:151
PGdataValue * rowBuf
Definition: libpq-int.h:584
bool std_strings
Definition: libpq-int.h:557
PGTernaryBool in_hot_standby
Definition: libpq-int.h:559
int client_encoding
Definition: libpq-int.h:556
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:558
int rowBufLen
Definition: libpq-int.h:585
int scram_sha_256_iterations
Definition: libpq-int.h:604

References pg_conn::altsock, 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 5413 of file fe-connect.c.

5415{
5416 /* Start the message. */
5417 if (pqPutMsgStart(pack_type, conn))
5418 return STATUS_ERROR;
5419
5420 /* Send the message body. */
5421 if (pqPutnchar(buf, buf_len, conn))
5422 return STATUS_ERROR;
5423
5424 /* Finish the message. */
5425 if (pqPutMsgEnd(conn))
5426 return STATUS_ERROR;
5427
5428 /* Flush to ensure backend gets it. */
5429 if (pqFlush(conn))
5430 return STATUS_ERROR;
5431
5432 return STATUS_OK;
5433}
#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().

◆ pqParseDone()

void pqParseDone ( PGconn conn,
int  newInStart 
)

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

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

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

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

◆ pqParseInput3()

void pqParseInput3 ( PGconn conn)

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

69{
70 char id;
71 int msgLength;
72 int avail;
73
74 /*
75 * Loop to parse successive complete messages available in the buffer.
76 */
77 for (;;)
78 {
79 /*
80 * Try to read a message. First get the type code and length. Return
81 * if not enough data.
82 */
84 if (pqGetc(&id, conn))
85 return;
86 if (pqGetInt(&msgLength, 4, conn))
87 return;
88
89 /*
90 * Try to validate message type/length here. A length less than 4 is
91 * definitely broken. Large lengths should only be believed for a few
92 * message types.
93 */
94 if (msgLength < 4)
95 {
96 handleSyncLoss(conn, id, msgLength);
97 return;
98 }
99 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
100 {
101 handleSyncLoss(conn, id, msgLength);
102 return;
103 }
104
105 /*
106 * Can't process if message body isn't all here yet.
107 */
108 msgLength -= 4;
109 avail = conn->inEnd - conn->inCursor;
110 if (avail < msgLength)
111 {
112 /*
113 * Before returning, enlarge the input buffer if needed to hold
114 * the whole message. This is better than leaving it to
115 * pqReadData because we can avoid multiple cycles of realloc()
116 * when the message is large; also, we can implement a reasonable
117 * recovery strategy if we are unable to make the buffer big
118 * enough.
119 */
120 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
121 conn))
122 {
123 /*
124 * Abandon the connection. There's not much else we can
125 * safely do; we can't just ignore the message or we could
126 * miss important changes to the connection state.
127 * pqCheckInBufferSpace() already reported the error.
128 */
130 }
131 return;
132 }
133
134 /*
135 * NOTIFY and NOTICE messages can happen in any state; always process
136 * them right away.
137 *
138 * Most other messages should only be processed while in BUSY state.
139 * (In particular, in READY state we hold off further parsing until
140 * the application collects the current PGresult.)
141 *
142 * However, if the state is IDLE then we got trouble; we need to deal
143 * with the unexpected message somehow.
144 *
145 * ParameterStatus ('S') messages are a special case: in IDLE state we
146 * must process 'em (this case could happen if a new value was adopted
147 * from config file due to SIGHUP), but otherwise we hold off until
148 * BUSY state.
149 */
151 {
152 if (getNotify(conn))
153 return;
154 }
155 else if (id == PqMsg_NoticeResponse)
156 {
157 if (pqGetErrorNotice3(conn, false))
158 return;
159 }
160 else if (conn->asyncStatus != PGASYNC_BUSY)
161 {
162 /* If not IDLE state, just wait ... */
164 return;
165
166 /*
167 * Unexpected message in IDLE state; need to recover somehow.
168 * ERROR messages are handled using the notice processor;
169 * ParameterStatus is handled normally; anything else is just
170 * dropped on the floor after displaying a suitable warning
171 * notice. (An ERROR is very possibly the backend telling us why
172 * it is about to close the connection, so we don't want to just
173 * discard it...)
174 */
175 if (id == PqMsg_ErrorResponse)
176 {
177 if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
178 return;
179 }
180 else if (id == PqMsg_ParameterStatus)
181 {
183 return;
184 }
185 else
186 {
187 /* Any other case is unexpected and we summarily skip it */
189 "message type 0x%02x arrived from server while idle",
190 id);
191 /* Discard the unexpected message */
192 conn->inCursor += msgLength;
193 }
194 }
195 else
196 {
197 /*
198 * In BUSY state, we can process everything.
199 */
200 switch (id)
201 {
203 if (pqGets(&conn->workBuffer, conn))
204 return;
206 {
209 if (!conn->result)
210 {
211 libpq_append_conn_error(conn, "out of memory");
213 }
214 }
215 if (conn->result)
219 break;
221 if (pqGetErrorNotice3(conn, true))
222 return;
224 break;
227 return;
229 {
232 if (!conn->result)
233 {
234 libpq_append_conn_error(conn, "out of memory");
236 }
237 else
238 {
241 }
242 }
243 else
244 {
245 /* Advance the command queue and set us idle */
246 pqCommandQueueAdvance(conn, true, false);
248 }
249 break;
252 {
255 if (!conn->result)
256 {
257 libpq_append_conn_error(conn, "out of memory");
259 }
260 }
262 break;
264 /* If we're doing PQprepare, we're done; else ignore */
265 if (conn->cmd_queue_head &&
267 {
269 {
272 if (!conn->result)
273 {
274 libpq_append_conn_error(conn, "out of memory");
276 }
277 }
279 }
280 break;
282 /* Nothing to do for this message type */
283 break;
285 /* If we're doing PQsendClose, we're done; else ignore */
286 if (conn->cmd_queue_head &&
288 {
290 {
293 if (!conn->result)
294 {
295 libpq_append_conn_error(conn, "out of memory");
297 }
298 }
300 }
301 break;
304 return;
305 break;
307
308 /*
309 * This is expected only during backend startup, but it's
310 * just as easy to handle it as part of the main loop.
311 * Save the data and continue processing.
312 */
313 if (getBackendKeyData(conn, msgLength))
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 ||
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;
418 break;
421 return;
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 /* Normal case: parsing agrees with specified length */
459 }
460 else if (conn->error_result && conn->status == CONNECTION_BAD)
461 {
462 /* The connection was abandoned and we already reported it */
463 return;
464 }
465 else
466 {
467 /* Trouble --- report it */
468 libpq_append_conn_error(conn, "message contents do not agree with length in message type \"%c\"", id);
469 /* build an error result holding the error message */
472 /* trust the specified message length as what to skip */
473 conn->inStart += 5 + msgLength;
474 }
475 }
476}
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
Definition: fe-exec.c:3153
static int getAnotherTuple(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:775
static int getRowDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:516
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
static int getBackendKeyData(PGconn *conn, int msgLength)
static int getParamDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:687
@ PGRES_COPY_IN
Definition: libpq-fe.h:132
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:137
@ PGRES_TUPLES_CHUNK
Definition: libpq-fe.h:142
@ PGRES_COPY_OUT
Definition: libpq-fe.h:131
@ PGRES_PIPELINE_SYNC
Definition: libpq-fe.h:139
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
@ PQ_PIPELINE_ON
Definition: libpq-fe.h:188
#define CMDSTATUS_LEN
Definition: libpq-int.h:83
#define PqMsg_CloseComplete
Definition: protocol.h:40
#define PqMsg_BindComplete
Definition: protocol.h:39
#define PqMsg_CopyData
Definition: protocol.h:65
#define PqMsg_ParameterDescription
Definition: protocol.h:58
#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_NoData
Definition: protocol.h:56
#define PqMsg_BackendKeyData
Definition: protocol.h:48
#define PqMsg_CommandComplete
Definition: protocol.h:42
#define PqMsg_DataRow
Definition: protocol.h:43
#define PqMsg_CopyOutResponse
Definition: protocol.h:46
#define PqMsg_ParseComplete
Definition: protocol.h:38
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:175

References pg_conn::asyncStatus, pg_conn::cmd_queue_head, pg_result::cmdStatus, CMDSTATUS_LEN, conn, CONNECTION_BAD, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::error_result, getAnotherTuple(), getBackendKeyData(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), handleFatalError(), handleSyncLoss(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), pg_conn::noticeHooks, 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, pqParseDone(), pqSaveErrorResult(), PGcmdQueueEntry::queryclass, pg_conn::result, pg_result::resultStatus, pg_conn::status, 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 8237 of file fe-connect.c.

8239{
8240 char *end;
8241 long numval;
8242
8243 Assert(value != NULL);
8244
8245 *result = 0;
8246
8247 /* strtol(3) skips leading whitespaces */
8248 errno = 0;
8249 numval = strtol(value, &end, 10);
8250
8251 /*
8252 * If no progress was done during the parsing or an error happened, fail.
8253 * This tests properly for overflows of the result.
8254 */
8255 if (value == end || errno != 0 || numval != (int) numval)
8256 goto error;
8257
8258 /*
8259 * Skip any trailing whitespace; if anything but whitespace remains before
8260 * the terminating character, fail
8261 */
8262 while (*end != '\0' && isspace((unsigned char) *end))
8263 end++;
8264
8265 if (*end != '\0')
8266 goto error;
8267
8268 *result = numval;
8269 return true;
8270
8271error:
8272 libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
8273 value, context);
8274 return false;
8275}
static struct @166 value
static void error(void)
Definition: sql-dyntest.c:147

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

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

◆ 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 */
906 res = unconstify(PGresult *, &OOM_result);
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:675

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(), 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:509
char * c

References conn, and pqPutMsgBytes().

Referenced by PQsendQueryGuts(), and PQsendTypedCommand().

◆ pqPutInt()

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

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

254{
255 uint16 tmp2;
256 uint32 tmp4;
257
258 switch (bytes)
259 {
260 case 2:
261 tmp2 = pg_hton16((uint16) value);
262 if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
263 return EOF;
264 break;
265 case 4:
266 tmp4 = pg_hton32((uint32) value);
267 if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
268 return EOF;
269 break;
270 default:
272 "integer of size %lu not supported by pqPutInt",
273 (unsigned long) bytes);
274 return EOF;
275 }
276
277 return 0;
278}
#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 532 of file fe-misc.c.

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

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

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

◆ pqPutMsgStart()

int pqPutMsgStart ( char  msg_type,
PGconn conn 
)

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

474{
475 int lenPos;
476 int endPos;
477
478 /* allow room for message type byte */
479 if (msg_type)
480 endPos = conn->outCount + 1;
481 else
482 endPos = conn->outCount;
483
484 /* do we want a length word? */
485 lenPos = endPos;
486 /* allow room for message length */
487 endPos += 4;
488
489 /* make sure there is room for message header */
490 if (pqCheckOutBufferSpace(endPos, conn))
491 return EOF;
492 /* okay, save the message type byte if any */
493 if (msg_type)
494 conn->outBuffer[conn->outCount] = msg_type;
495 /* set up the message pointers */
496 conn->outMsgStart = lenPos;
497 conn->outMsgEnd = endPos;
498 /* length word, if needed, will be filled in by pqPutMsgEnd */
499
500 return 0;
501}
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(), PQsendCancelRequest(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutnchar()

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

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

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

References conn, len, and pqPutMsgBytes().

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

◆ pqPuts()

int pqPuts ( const char *  s,
PGconn conn 
)

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

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

References conn, and pqPutMsgBytes().

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

◆ pqReadData()

int pqReadData ( PGconn conn)

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

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

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

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

◆ pqReadReady()

int pqReadReady ( PGconn conn)

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

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

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqReleaseConnHosts()

void pqReleaseConnHosts ( PGconn conn)

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

5142{
5143 if (conn->connhost)
5144 {
5145 for (int i = 0; i < conn->nconnhost; ++i)
5146 {
5147 free(conn->connhost[i].host);
5149 free(conn->connhost[i].port);
5150 if (conn->connhost[i].password != NULL)
5151 {
5153 strlen(conn->connhost[i].password));
5155 }
5156 }
5157 free(conn->connhost);
5158 conn->connhost = NULL;
5159 }
5160}
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 {
584 res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
585 res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
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:98
size_t memorySize
Definition: libpq-int.h:209
int curOffset
Definition: libpq-int.h:206
char null_field[1]
Definition: libpq-int.h:198
int spaceLeft
Definition: libpq-int.h:207
PGresult_data * curBlock
Definition: libpq-int.h:205
PGresult_data * next
Definition: libpq-int.h:102
char space[1]
Definition: libpq-int.h:103

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

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

◆ 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(), and str.

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

◆ pqRowProcessor()

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

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

1218{
1219 PGresult *res = conn->result;
1220 int nfields = res->numAttributes;
1221 const PGdataValue *columns = conn->rowBuf;
1222 PGresAttValue *tup;
1223 int i;
1224
1225 /*
1226 * In partial-result mode, if we don't already have a partial PGresult
1227 * then make one by cloning conn->result (which should hold the correct
1228 * result metadata by now). Then the original conn->result is moved over
1229 * to saved_result so that we can re-use it as a reference for future
1230 * partial results. The saved result will become active again after
1231 * pqPrepareAsyncResult() returns the partial result to the application.
1232 */
1233 if (conn->partialResMode && conn->saved_result == NULL)
1234 {
1235 /* Copy everything that should be in the result at this point */
1236 res = PQcopyResult(res,
1239 if (!res)
1240 return 0;
1241 /* Change result status to appropriate special value */
1243 /* And stash it as the active result */
1245 conn->result = res;
1246 }
1247
1248 /*
1249 * Basically we just allocate space in the PGresult for each field and
1250 * copy the data over.
1251 *
1252 * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1253 * caller will take to mean "out of memory". This is preferable to trying
1254 * to set up such a message here, because evidently there's not enough
1255 * memory for gettext() to do anything.
1256 */
1257 tup = (PGresAttValue *)
1258 pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
1259 if (tup == NULL)
1260 return 0;
1261
1262 for (i = 0; i < nfields; i++)
1263 {
1264 int clen = columns[i].len;
1265
1266 if (clen < 0)
1267 {
1268 /* null field */
1269 tup[i].len = NULL_LEN;
1270 tup[i].value = res->null_field;
1271 }
1272 else
1273 {
1274 bool isbinary = (res->attDescs[i].format != 0);
1275 char *val;
1276
1277 val = (char *) pqResultAlloc(res, clen + 1, isbinary);
1278 if (val == NULL)
1279 return 0;
1280
1281 /* copy and zero-terminate the data (even if it's binary) */
1282 memcpy(val, columns[i].value, clen);
1283 val[clen] = '\0';
1284
1285 tup[i].len = clen;
1286 tup[i].value = val;
1287 }
1288 }
1289
1290 /* And add the tuple to the PGresult's tuple array */
1291 if (!pqAddTuple(res, tup, errmsgp))
1292 return 0;
1293
1294 /*
1295 * Success. In partial-result mode, if we have enough rows then make the
1296 * result available to the client immediately.
1297 */
1298 if (conn->partialResMode && res->ntups >= conn->maxChunkSize)
1300
1301 return 1;
1302}
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:138
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:69
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:71
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:72
#define NULL_LEN
Definition: libpq-int.h:130
int maxChunkSize
Definition: libpq-int.h:472
bool singleRowMode
Definition: libpq-int.h:471
bool partialResMode
Definition: libpq-int.h:470
int ntups
Definition: libpq-int.h:166
PGresAttDesc * attDescs
Definition: libpq-int.h:168
int numAttributes
Definition: libpq-int.h:167
char * value
Definition: libpq-int.h:135

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(), 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(), handleFatalError(), pqFunctionCall3(), pqGetNegotiateProtocolVersion3(), 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 *)
1065 pqResultAlloc(res,
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:141
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:143

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

Referenced by pqGetErrorNotice3(), and pqInternalNotice().

◆ pqSaveParameterStatus()

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

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

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

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 152 of file fe-secure.c.

153{
154#ifdef USE_SSL
156#endif
157}

References conn, and pgtls_close().

Referenced by pqDropConnection().

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn conn)

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

139{
140#ifdef USE_SSL
141 return pgtls_open_client(conn);
142#else
143 /* shouldn't get here */
145#endif
146}
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 193 of file fe-secure.c.

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

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(), pg_GSS_read(), pgconn_bio_read(), and pqsecure_read().

◆ pqsecure_raw_write()

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

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

317{
318 ssize_t n;
319 int flags = 0;
320 int result_errno = 0;
321 char msgbuf[1024];
322 char sebuf[PG_STRERROR_R_BUFLEN];
323
324 DECLARE_SIGPIPE_INFO(spinfo);
325
326 /*
327 * If we already had a write failure, we will never again try to send data
328 * on that connection. Even if the kernel would let us, we've probably
329 * lost message boundary sync with the server. conn->write_failed
330 * therefore persists until the connection is reset, and we just discard
331 * all data presented to be written.
332 */
333 if (conn->write_failed)
334 return len;
335
336#ifdef MSG_NOSIGNAL
337 if (conn->sigpipe_flag)
338 flags |= MSG_NOSIGNAL;
339
340retry_masked:
341#endif /* MSG_NOSIGNAL */
342
343 DISABLE_SIGPIPE(conn, spinfo, return -1);
344
345 n = send(conn->sock, ptr, len, flags);
346
347 if (n < 0)
348 {
349 result_errno = SOCK_ERRNO;
350
351 /*
352 * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
353 * on this machine. So, clear sigpipe_flag so we don't try the flag
354 * again, and retry the send().
355 */
356#ifdef MSG_NOSIGNAL
357 if (flags != 0 && result_errno == EINVAL)
358 {
359 conn->sigpipe_flag = false;
360 flags = 0;
361 goto retry_masked;
362 }
363#endif /* MSG_NOSIGNAL */
364
365 /* Set error message if appropriate */
366 switch (result_errno)
367 {
368#ifdef EAGAIN
369 case EAGAIN:
370#endif
371#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
372 case EWOULDBLOCK:
373#endif
374 case EINTR:
375 /* no error message, caller is expected to retry */
376 break;
377
378 case EPIPE:
379 /* Set flag for EPIPE */
380 REMEMBER_EPIPE(spinfo, true);
381
382 /* FALL THRU */
383
384 case ECONNRESET:
385 conn->write_failed = true;
386 /* Store error message in conn->write_err_msg, if possible */
387 /* (strdup failure is OK, we'll cope later) */
388 snprintf(msgbuf, sizeof(msgbuf),
389 libpq_gettext("server closed the connection unexpectedly\n"
390 "\tThis probably means the server terminated abnormally\n"
391 "\tbefore or while processing the request."));
392 /* keep newline out of translated string */
393 strlcat(msgbuf, "\n", sizeof(msgbuf));
394 conn->write_err_msg = strdup(msgbuf);
395 /* Now claim the write succeeded */
396 n = len;
397 break;
398
399 default:
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("could not send data to server: %s"),
405 SOCK_STRERROR(result_errno,
406 sebuf, sizeof(sebuf)));
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 }
415
416 RESTORE_SIGPIPE(conn, spinfo);
417
418 /* ensure we return the intended errno to caller */
419 SOCK_ERRNO_SET(result_errno);
420
421 return n;
422}
#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:513
bool sigpipe_flag
Definition: libpq-int.h:511
bool write_failed
Definition: libpq-int.h:512
#define send(s, buf, len, flags)
Definition: win32_port.h:505

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 pg_GSS_write(), pgconn_bio_write(), pqsecure_open_gss(), and pqsecure_write().

◆ pqsecure_read()

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

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

168{
169 ssize_t n;
170
171#ifdef USE_SSL
172 if (conn->ssl_in_use)
173 {
174 n = pgtls_read(conn, ptr, len);
175 }
176 else
177#endif
178#ifdef ENABLE_GSS
179 if (conn->gssenc)
180 {
181 n = pg_GSS_read(conn, ptr, len);
182 }
183 else
184#endif
185 {
186 n = pqsecure_raw_read(conn, ptr, len);
187 }
188
189 return n;
190}
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:193

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 267 of file fe-secure.c.

268{
269 ssize_t n;
270
271#ifdef USE_SSL
272 if (conn->ssl_in_use)
273 {
274 n = pgtls_write(conn, ptr, len);
275 }
276 else
277#endif
278#ifdef ENABLE_GSS
279 if (conn->gssenc)
280 {
281 n = pg_GSS_write(conn, ptr, len);
282 }
283 else
284#endif
285 {
286 n = pqsecure_raw_write(conn, ptr, len);
287 }
288
289 return n;
290}
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:316

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

Referenced by pqSendSome().

◆ PQsendCancelRequest()

int PQsendCancelRequest ( PGconn cancelConn)

Definition at line 472 of file fe-cancel.c.

473{
475
476 /* Start the message. */
478 return STATUS_ERROR;
479
480 /* Send the message body. */
481 memset(&req, 0, offsetof(CancelRequestPacket, cancelAuthCode));
484 if (pqPutnchar(&req, offsetof(CancelRequestPacket, cancelAuthCode), cancelConn))
485 return STATUS_ERROR;
486 if (pqPutnchar(cancelConn->be_cancel_key, cancelConn->be_cancel_key_len, cancelConn))
487 return STATUS_ERROR;
488
489 /* Finish the message. */
491 return STATUS_ERROR;
492
493 /* Flush to ensure backend gets it. */
494 if (pqFlush(cancelConn))
495 return STATUS_ERROR;
496
497 return STATUS_OK;
498}
static PGcancel *volatile cancelConn
Definition: cancel.c:43
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:137
ProtocolVersion MsgType
Definition: pqcomm.h:101
MsgType cancelRequestCode
Definition: pqcomm.h:142
uint32 backendPID
Definition: pqcomm.h:143
int be_pid
Definition: fe-cancel.c:43

References CancelRequestPacket::backendPID, pg_cancel::be_pid, CANCEL_REQUEST_CODE, cancelConn, CancelRequestPacket::cancelRequestCode, pg_hton32, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), STATUS_ERROR, and STATUS_OK.

Referenced by PQconnectPoll().

◆ PQsendQueryContinue()

int PQsendQueryContinue ( PGconn conn,
const char *  query 
)

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

1434{
1435 return PQsendQueryInternal(conn, query, false);
1436}
static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
Definition: fe-exec.c:1439

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

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

◆ pqTraceOutputCharResponse()

void pqTraceOutputCharResponse ( PGconn conn,
const char *  responseType,
char  response 
)

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

917{
919 {
920 char timestr[128];
921
922 pqTraceFormatTimestamp(timestr, sizeof(timestr));
923 fprintf(conn->Pfdebug, "%s\t", timestr);
924 }
925
926 fprintf(conn->Pfdebug, "B\t1\t%s\t %c\n", responseType, response);
927}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
static void pqTraceFormatTimestamp(char *timestr, size_t ts_len)
Definition: fe-trace.c:80
#define PQTRACE_SUPPRESS_TIMESTAMPS
Definition: libpq-fe.h:478
int traceFlags
Definition: libpq-int.h:451

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

Referenced by PQconnectPoll().

◆ pqTraceOutputMessage()

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

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

625{
626 char id;
627 int length;
628 char *prefix = toServer ? "F" : "B";
629 int logCursor = 0;
630 bool regress;
631
633 {
634 char timestr[128];
635
636 pqTraceFormatTimestamp(timestr, sizeof(timestr));
637 fprintf(conn->Pfdebug, "%s\t", timestr);
638 }
639 regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
640
641 id = message[logCursor++];
642
643 memcpy(&length, message + logCursor, 4);
644 length = (int) pg_ntoh32(length);
645 logCursor += 4;
646
647 /*
648 * In regress mode, suppress the length of ErrorResponse and
649 * NoticeResponse. The F (file name), L (line number) and R (routine
650 * name) fields can change as server code is modified, and if their
651 * lengths differ from the originals, that would break tests.
652 */
653 if (regress && !toServer && (id == PqMsg_ErrorResponse || id == PqMsg_NoticeResponse))
654 fprintf(conn->Pfdebug, "%s\tNN\t", prefix);
655 else
656 fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length);
657
658 switch (id)
659 {
661 fprintf(conn->Pfdebug, "ParseComplete");
662 /* No message content */
663 break;
665 fprintf(conn->Pfdebug, "BindComplete");
666 /* No message content */
667 break;
669 fprintf(conn->Pfdebug, "CloseComplete");
670 /* No message content */
671 break;
673 pqTraceOutput_NotificationResponse(conn->Pfdebug, message, &logCursor, regress);
674 break;
675 case PqMsg_Bind:
676 pqTraceOutput_Bind(conn->Pfdebug, message, &logCursor);
677 break;
678 case PqMsg_CopyDone:
679 fprintf(conn->Pfdebug, "CopyDone");
680 /* No message content */
681 break;
683 /* Close(F) and CommandComplete(B) use the same identifier. */
685 if (toServer)
686 pqTraceOutput_Close(conn->Pfdebug, message, &logCursor);
687 else
688 pqTraceOutput_CommandComplete(conn->Pfdebug, message, &logCursor);
689 break;
690 case PqMsg_CopyData:
691 pqTraceOutput_CopyData(conn->Pfdebug, message, &logCursor,
692 length, regress);
693 break;
694 case PqMsg_Describe:
695 /* Describe(F) and DataRow(B) use the same identifier. */
697 if (toServer)
698 pqTraceOutput_Describe(conn->Pfdebug, message, &logCursor);
699 else
700 pqTraceOutput_DataRow(conn->Pfdebug, message, &logCursor);
701 break;
702 case PqMsg_Execute:
703 /* Execute(F) and ErrorResponse(B) use the same identifier. */
705 if (toServer)
706 pqTraceOutput_Execute(conn->Pfdebug, message, &logCursor, regress);
707 else
708 pqTraceOutput_ErrorResponse(conn->Pfdebug, message, &logCursor, regress);
709 break;
710 case PqMsg_CopyFail:
711 pqTraceOutput_CopyFail(conn->Pfdebug, message, &logCursor);
712 break;
717
718 /*
719 * These messages share a common type byte, so we discriminate by
720 * having the code store the auth type separately.
721 */
723 {
726 &logCursor, length, regress);
727 break;
730 &logCursor);
731 break;
734 &logCursor, regress);
735 break;
738 &logCursor, length, regress);
739 break;
740 default:
741 fprintf(conn->Pfdebug, "UnknownAuthenticationResponse");
742 break;
743 }
745 break;
747 pqTraceOutput_FunctionCall(conn->Pfdebug, message, &logCursor, regress);
748 break;
750 pqTraceOutput_CopyInResponse(conn->Pfdebug, message, &logCursor);
751 break;
752 case PqMsg_Flush:
753 /* Flush(F) and CopyOutResponse(B) use the same identifier */
755 if (toServer)
756 fprintf(conn->Pfdebug, "Flush"); /* no message content */
757 else
758 pqTraceOutput_CopyOutResponse(conn->Pfdebug, message, &logCursor);
759 break;
761 fprintf(conn->Pfdebug, "EmptyQueryResponse");
762 /* No message content */
763 break;
765 pqTraceOutput_BackendKeyData(conn->Pfdebug, message, &logCursor, regress);
766 break;
767 case PqMsg_NoData:
768 fprintf(conn->Pfdebug, "NoData");
769 /* No message content */
770 break;
772 pqTraceOutput_NoticeResponse(conn->Pfdebug, message, &logCursor, regress);
773 break;
774 case PqMsg_Parse:
775 pqTraceOutput_Parse(conn->Pfdebug, message, &logCursor, regress);
776 break;
777 case PqMsg_Query:
778 pqTraceOutput_Query(conn->Pfdebug, message, &logCursor);
779 break;
781 pqTraceOutput_Authentication(conn->Pfdebug, message, &logCursor,
782 length, regress);
783 break;
785 fprintf(conn->Pfdebug, "PortalSuspended");
786 /* No message content */
787 break;
788 case PqMsg_Sync:
789 /* ParameterStatus(B) and Sync(F) use the same identifier */
791 if (toServer)
792 fprintf(conn->Pfdebug, "Sync"); /* no message content */
793 else
794 pqTraceOutput_ParameterStatus(conn->Pfdebug, message, &logCursor);
795 break;
797 pqTraceOutput_ParameterDescription(conn->Pfdebug, message, &logCursor, regress);
798 break;
800 pqTraceOutput_RowDescription(conn->Pfdebug, message, &logCursor, regress);
801 break;
804 break;
806 pqTraceOutput_FunctionCallResponse(conn->Pfdebug, message, &logCursor);
807 break;
809 pqTraceOutput_CopyBothResponse(conn->Pfdebug, message, &logCursor, length);
810 break;
811 case PqMsg_Terminate:
812 fprintf(conn->Pfdebug, "Terminate");
813 /* No message content */
814 break;
816 pqTraceOutput_ReadyForQuery(conn->Pfdebug, message, &logCursor);
817 break;
818 default:
819 fprintf(conn->Pfdebug, "Unknown message: %02x", id);
820 break;
821 }
822
823 fputc('\n', conn->Pfdebug);
824
825 /*
826 * Verify the printing routine did it right. Note that the one-byte
827 * message identifier is not included in the length, but our cursor does
828 * include it.
829 */
830 if (logCursor - 1 != length)
832 "mismatched message length: consumed %d, expected %d\n",
833 logCursor - 1, length);
834}
static void pqTraceOutput_RowDescription(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:559
static void pqTraceOutput_GSSResponse(FILE *f, const char *message, int *cursor, int length, bool regress)
Definition: fe-trace.c:367
static void pqTraceOutput_FunctionCall(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:403
static void pqTraceOutput_CopyInResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:429
static void pqTraceOutput_BackendKeyData(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:455
static void pqTraceOutput_Authentication(FILE *f, const char *message, int *cursor, int length, bool suppress)
Definition: fe-trace.c:484
static void pqTraceOutput_Parse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:463
static void pqTraceOutput_NoticeResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:346
static void pqTraceOutput_ParameterDescription(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:547
static void pqTraceOutput_DataRow(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:293
static void pqTraceOutput_SASLResponse(FILE *f, const char *message, int *cursor, int length, bool regress)
Definition: fe-trace.c:395
static void pqTraceOutput_Query(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:477
static void pqTraceOutput_CopyData(FILE *f, const char *message, int *cursor, int length, bool suppress)
Definition: fe-trace.c:285
static void pqTraceOutput_SASLInitialResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:382
static void pqTraceOutput_NegotiateProtocolVersion(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:579
static void pqTraceOutput_CopyBothResponse(FILE *f, const char *message, int *cursor, int length)
Definition: fe-trace.c:604
static void pqTraceOutput_Bind(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:240
static void pqTraceOutput_ErrorResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:340
static void pqTraceOutput_Close(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:270
static void pqTraceOutput_Describe(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:311
static void pqTraceOutput_NotificationResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:231
static void pqTraceOutput_CommandComplete(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:278
static void pqTraceOutput_ParameterStatus(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:539
static void pqTraceOutput_Execute(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:352
static void pqTraceOutput_CopyOutResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:442
static void pqTraceOutput_ReadyForQuery(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:614
static void pqTraceOutput_CopyFail(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:360
static void pqTraceOutput_PasswordMessage(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:375
static void pqTraceOutput_FunctionCallResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:593
#define PQTRACE_REGRESS_MODE
Definition: libpq-fe.h:480
#define AUTH_RESPONSE_PASSWORD
Definition: libpq-int.h:336
#define AUTH_RESPONSE_SASL
Definition: libpq-int.h:338
#define AUTH_RESPONSE_SASL_INITIAL
Definition: libpq-int.h:337
#define AUTH_RESPONSE_GSS
Definition: libpq-int.h:335
#define PqMsg_GSSResponse
Definition: protocol.h:30
#define PqMsg_SASLResponse
Definition: protocol.h:33
#define PqMsg_Describe
Definition: protocol.h:21
#define PqMsg_SASLInitialResponse
Definition: protocol.h:32
#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_PasswordMessage
Definition: protocol.h:31
#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
char current_auth_response
Definition: libpq-int.h:523

References Assert(), AUTH_RESPONSE_GSS, AUTH_RESPONSE_PASSWORD, AUTH_RESPONSE_SASL, AUTH_RESPONSE_SASL_INITIAL, conn, pg_conn::current_auth_response, 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_GSSResponse, PqMsg_NegotiateProtocolVersion, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_Parse, PqMsg_ParseComplete, PqMsg_PasswordMessage, PqMsg_PortalSuspended, PqMsg_Query, PqMsg_ReadyForQuery, PqMsg_RowDescription, PqMsg_SASLInitialResponse, PqMsg_SASLResponse, PqMsg_Sync, PqMsg_Terminate, PQTRACE_REGRESS_MODE, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutput_Authentication(), pqTraceOutput_BackendKeyData(), pqTraceOutput_Bind(), pqTraceOutput_Close(), pqTraceOutput_CommandComplete(), pqTraceOutput_CopyBothResponse(), pqTraceOutput_CopyData(), pqTraceOutput_CopyFail(), pqTraceOutput_CopyInResponse(), pqTraceOutput_CopyOutResponse(), pqTraceOutput_DataRow(), pqTraceOutput_Describe(), pqTraceOutput_ErrorResponse(), pqTraceOutput_Execute(), pqTraceOutput_FunctionCall(), pqTraceOutput_FunctionCallResponse(), pqTraceOutput_GSSResponse(), pqTraceOutput_NegotiateProtocolVersion(), pqTraceOutput_NoticeResponse(), pqTraceOutput_NotificationResponse(), pqTraceOutput_ParameterDescription(), pqTraceOutput_ParameterStatus(), pqTraceOutput_Parse(), pqTraceOutput_PasswordMessage(), pqTraceOutput_Query(), pqTraceOutput_ReadyForQuery(), pqTraceOutput_RowDescription(), pqTraceOutput_SASLInitialResponse(), pqTraceOutput_SASLResponse(), and pg_conn::traceFlags.

Referenced by pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pqParseDone(), and pqPutMsgEnd().

◆ pqTraceOutputNoTypeByteMessage()

void pqTraceOutputNoTypeByteMessage ( PGconn conn,
const char *  message 
)

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

842{
843 int length;
844 int version;
845 bool regress;
846 int logCursor = 0;
847
848 regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
849
851 {
852 char timestr[128];
853
854 pqTraceFormatTimestamp(timestr, sizeof(timestr));
855 fprintf(conn->Pfdebug, "%s\t", timestr);
856 }
857
858 memcpy(&length, message + logCursor, 4);
859 length = (int) pg_ntoh32(length);
860 logCursor += 4;
861
862 fprintf(conn->Pfdebug, "F\t%d\t", length);
863
864 if (length < 8)
865 {
866 fprintf(conn->Pfdebug, "Unknown message\n");
867 return;
868 }
869
870 memcpy(&version, message + logCursor, 4);
871 version = (int) pg_ntoh32(version);
872
873 if (version == CANCEL_REQUEST_CODE && length >= 16)
874 {
875 fprintf(conn->Pfdebug, "CancelRequest\t");
876 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
877 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
878 pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
879 pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
880 }
881 else if (version == NEGOTIATE_SSL_CODE)
882 {
883 fprintf(conn->Pfdebug, "SSLRequest\t");
884 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
885 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
886 }
887 else if (version == NEGOTIATE_GSS_CODE)
888 {
889 fprintf(conn->Pfdebug, "GSSENCRequest\t");
890 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
891 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
892 }
893 else
894 {
895 fprintf(conn->Pfdebug, "StartupMessage\t");
896 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
897 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
898 while (message[logCursor] != '\0')
899 {
900 /* XXX should we suppress anything in regress mode? */
901 pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
902 pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
903 }
904 }
905
906 fputc('\n', conn->Pfdebug);
907}
static void pqTraceOutputString(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:166
static int pqTraceOutputInt16(FILE *pfdebug, const char *data, int *cursor)
Definition: fe-trace.c:126
static int pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:145
#define NEGOTIATE_GSS_CODE
Definition: pqcomm.h:173
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:172

References CANCEL_REQUEST_CODE, conn, fprintf, NEGOTIATE_GSS_CODE, NEGOTIATE_SSL_CODE, pg_conn::Pfdebug, pg_ntoh32, PQTRACE_REGRESS_MODE, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutputInt16(), pqTraceOutputInt32(), pqTraceOutputString(), and pg_conn::traceFlags.

Referenced by pqPutMsgEnd().

◆ pqWait()

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

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

1020{
1021 return pqWaitTimed(forRead, forWrite, conn, -1);
1022}

References conn, and pqWaitTimed().

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

◆ pqWaitTimed()

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

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

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

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

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

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

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

References conn, and pqSocketCheck().

Variable Documentation

◆ pg_g_threadlock

pgthreadlock_t pg_g_threadlock
extern

Definition at line 35 of file oauth-utils.c.

Referenced by libpq_oauth_init(), and PQregisterThreadLock().

◆ pgresStatus

char* const pgresStatus[]
extern

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

Referenced by PQresStatus().