PostgreSQL Source Code  git master
libpq-fe.h File Reference
#include <stdio.h>
#include "postgres_ext.h"
Include dependency graph for libpq-fe.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pgNotify
 
struct  _PQprintOpt
 
struct  _PQconninfoOption
 
struct  PQArgBlock
 
struct  pgresAttDesc
 

Macros

#define LIBPQ_HAS_PIPELINING   1
 
#define LIBPQ_HAS_TRACE_FLAGS   1
 
#define LIBPQ_HAS_SSL_LIBRARY_DETECTION   1
 
#define LIBPQ_HAS_ASYNC_CANCEL   1
 
#define LIBPQ_HAS_CHANGE_PASSWORD   1
 
#define LIBPQ_HAS_CHUNK_MODE   1
 
#define LIBPQ_HAS_CLOSE_PREPARED   1
 
#define LIBPQ_HAS_SEND_PIPELINE_SYNC   1
 
#define LIBPQ_HAS_SOCKET_POLL   1
 
#define LIBPQ_HAS_FULL_PROTOCOL_VERSION   1
 
#define PG_COPYRES_ATTRS   0x01
 
#define PG_COPYRES_TUPLES   0x02 /* Implies PG_COPYRES_ATTRS */
 
#define PG_COPYRES_EVENTS   0x04
 
#define PG_COPYRES_NOTICEHOOKS   0x08
 
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)    PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
 
#define PQTRACE_SUPPRESS_TIMESTAMPS   (1<<0)
 
#define PQTRACE_REGRESS_MODE   (1<<1)
 
#define PQ_QUERY_PARAM_MAX_LIMIT   65535
 
#define PQfreeNotify(ptr)   PQfreemem(ptr)
 
#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"
 

Typedefs

typedef struct pg_conn PGconn
 
typedef struct pg_cancel_conn PGcancelConn
 
typedef struct pg_result PGresult
 
typedef struct pg_cancel PGcancel
 
typedef struct pgNotify PGnotify
 
typedef pg_int64 pg_usec_time_t
 
typedef void(* PQnoticeReceiver) (void *arg, const PGresult *res)
 
typedef void(* PQnoticeProcessor) (void *arg, const char *message)
 
typedef char pqbool
 
typedef struct _PQprintOpt PQprintOpt
 
typedef struct _PQconninfoOption PQconninfoOption
 
typedef struct pgresAttDesc PGresAttDesc
 
typedef void(* pgthreadlock_t) (int acquire)
 
typedef int(* PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn)
 

Enumerations

enum  ConnStatusType {
  CONNECTION_OK , CONNECTION_BAD , CONNECTION_STARTED , CONNECTION_MADE ,
  CONNECTION_AWAITING_RESPONSE , CONNECTION_AUTH_OK , CONNECTION_SETENV , CONNECTION_SSL_STARTUP ,
  CONNECTION_NEEDED , CONNECTION_CHECK_WRITABLE , CONNECTION_CONSUME , CONNECTION_GSS_STARTUP ,
  CONNECTION_CHECK_TARGET , CONNECTION_CHECK_STANDBY , CONNECTION_ALLOCATED
}
 
enum  PostgresPollingStatusType {
  PGRES_POLLING_FAILED = 0 , PGRES_POLLING_READING , PGRES_POLLING_WRITING , PGRES_POLLING_OK ,
  PGRES_POLLING_ACTIVE
}
 
enum  ExecStatusType {
  PGRES_EMPTY_QUERY = 0 , PGRES_COMMAND_OK , PGRES_TUPLES_OK , PGRES_COPY_OUT ,
  PGRES_COPY_IN , PGRES_BAD_RESPONSE , PGRES_NONFATAL_ERROR , PGRES_FATAL_ERROR ,
  PGRES_COPY_BOTH , PGRES_SINGLE_TUPLE , PGRES_PIPELINE_SYNC , PGRES_PIPELINE_ABORTED ,
  PGRES_TUPLES_CHUNK
}
 
enum  PGTransactionStatusType {
  PQTRANS_IDLE , PQTRANS_ACTIVE , PQTRANS_INTRANS , PQTRANS_INERROR ,
  PQTRANS_UNKNOWN
}
 
enum  PGVerbosity { PQERRORS_TERSE , PQERRORS_DEFAULT , PQERRORS_VERBOSE , PQERRORS_SQLSTATE }
 
enum  PGContextVisibility { PQSHOW_CONTEXT_NEVER , PQSHOW_CONTEXT_ERRORS , PQSHOW_CONTEXT_ALWAYS }
 
enum  PGPing { PQPING_OK , PQPING_REJECT , PQPING_NO_RESPONSE , PQPING_NO_ATTEMPT }
 
enum  PGpipelineStatus { PQ_PIPELINE_OFF , PQ_PIPELINE_ON , PQ_PIPELINE_ABORTED }
 

Functions

PGconnPQconnectStart (const char *conninfo)
 
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PostgresPollingStatusType PQconnectPoll (PGconn *conn)
 
PGconnPQconnectdb (const char *conninfo)
 
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQsetdbLogin (const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
 
void PQfinish (PGconn *conn)
 
PQconninfoOptionPQconndefaults (void)
 
PQconninfoOptionPQconninfoParse (const char *conninfo, char **errmsg)
 
PQconninfoOptionPQconninfo (PGconn *conn)
 
void PQconninfoFree (PQconninfoOption *connOptions)
 
int PQresetStart (PGconn *conn)
 
PostgresPollingStatusType PQresetPoll (PGconn *conn)
 
void PQreset (PGconn *conn)
 
PGcancelConnPQcancelCreate (PGconn *conn)
 
int PQcancelStart (PGcancelConn *cancelConn)
 
int PQcancelBlocking (PGcancelConn *cancelConn)
 
PostgresPollingStatusType PQcancelPoll (PGcancelConn *cancelConn)
 
ConnStatusType PQcancelStatus (const PGcancelConn *cancelConn)
 
int PQcancelSocket (const PGcancelConn *cancelConn)
 
char * PQcancelErrorMessage (const PGcancelConn *cancelConn)
 
void PQcancelReset (PGcancelConn *cancelConn)
 
void PQcancelFinish (PGcancelConn *cancelConn)
 
PGcancelPQgetCancel (PGconn *conn)
 
void PQfreeCancel (PGcancel *cancel)
 
int PQcancel (PGcancel *cancel, char *errbuf, int errbufsize)
 
int PQrequestCancel (PGconn *conn)
 
char * PQdb (const PGconn *conn)
 
char * PQuser (const PGconn *conn)
 
char * PQpass (const PGconn *conn)
 
char * PQhost (const PGconn *conn)
 
char * PQhostaddr (const PGconn *conn)
 
char * PQport (const PGconn *conn)
 
char * PQtty (const PGconn *conn)
 
char * PQoptions (const PGconn *conn)
 
ConnStatusType PQstatus (const PGconn *conn)
 
PGTransactionStatusType PQtransactionStatus (const PGconn *conn)
 
const char * PQparameterStatus (const PGconn *conn, const char *paramName)
 
int PQprotocolVersion (const PGconn *conn)
 
int PQfullProtocolVersion (const PGconn *conn)
 
int PQserverVersion (const PGconn *conn)
 
char * PQerrorMessage (const PGconn *conn)
 
int PQsocket (const PGconn *conn)
 
int PQbackendPID (const PGconn *conn)
 
PGpipelineStatus PQpipelineStatus (const PGconn *conn)
 
int PQconnectionNeedsPassword (const PGconn *conn)
 
int PQconnectionUsedPassword (const PGconn *conn)
 
int PQconnectionUsedGSSAPI (const PGconn *conn)
 
int PQclientEncoding (const PGconn *conn)
 
int PQsetClientEncoding (PGconn *conn, const char *encoding)
 
int PQsslInUse (PGconn *conn)
 
void * PQsslStruct (PGconn *conn, const char *struct_name)
 
const char * PQsslAttribute (PGconn *conn, const char *attribute_name)
 
const char *const * PQsslAttributeNames (PGconn *conn)
 
void * PQgetssl (PGconn *conn)
 
void PQinitSSL (int do_init)
 
void PQinitOpenSSL (int do_ssl, int do_crypto)
 
int PQgssEncInUse (PGconn *conn)
 
void * PQgetgssctx (PGconn *conn)
 
PGVerbosity PQsetErrorVerbosity (PGconn *conn, PGVerbosity verbosity)
 
PGContextVisibility PQsetErrorContextVisibility (PGconn *conn, PGContextVisibility show_context)
 
PQnoticeReceiver PQsetNoticeReceiver (PGconn *conn, PQnoticeReceiver proc, void *arg)
 
PQnoticeProcessor PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
 
pgthreadlock_t PQregisterThreadLock (pgthreadlock_t newhandler)
 
void PQtrace (PGconn *conn, FILE *debug_port)
 
void PQuntrace (PGconn *conn)
 
void PQsetTraceFlags (PGconn *conn, int flags)
 
PGresultPQexec (PGconn *conn, const char *query)
 
PGresultPQexecParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
PGresultPQprepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
 
PGresultPQexecPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsendQuery (PGconn *conn, const char *query)
 
int PQsendQueryParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsendPrepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
 
int PQsendQueryPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsetSingleRowMode (PGconn *conn)
 
int PQsetChunkedRowsMode (PGconn *conn, int chunkSize)
 
PGresultPQgetResult (PGconn *conn)
 
int PQisBusy (PGconn *conn)
 
int PQconsumeInput (PGconn *conn)
 
int PQenterPipelineMode (PGconn *conn)
 
int PQexitPipelineMode (PGconn *conn)
 
int PQpipelineSync (PGconn *conn)
 
int PQsendFlushRequest (PGconn *conn)
 
int PQsendPipelineSync (PGconn *conn)
 
PGnotifyPQnotifies (PGconn *conn)
 
int PQputCopyData (PGconn *conn, const char *buffer, int nbytes)
 
int PQputCopyEnd (PGconn *conn, const char *errormsg)
 
int PQgetCopyData (PGconn *conn, char **buffer, int async)
 
int PQgetline (PGconn *conn, char *buffer, int length)
 
int PQputline (PGconn *conn, const char *string)
 
int PQgetlineAsync (PGconn *conn, char *buffer, int bufsize)
 
int PQputnbytes (PGconn *conn, const char *buffer, int nbytes)
 
int PQendcopy (PGconn *conn)
 
int PQsetnonblocking (PGconn *conn, int arg)
 
int PQisnonblocking (const PGconn *conn)
 
int PQisthreadsafe (void)
 
PGPing PQping (const char *conninfo)
 
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
int PQflush (PGconn *conn)
 
PGresultPQfn (PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
ExecStatusType PQresultStatus (const PGresult *res)
 
char * PQresStatus (ExecStatusType status)
 
char * PQresultErrorMessage (const PGresult *res)
 
char * PQresultVerboseErrorMessage (const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
 
char * PQresultErrorField (const PGresult *res, int fieldcode)
 
int PQntuples (const PGresult *res)
 
int PQnfields (const PGresult *res)
 
int PQbinaryTuples (const PGresult *res)
 
char * PQfname (const PGresult *res, int field_num)
 
int PQfnumber (const PGresult *res, const char *field_name)
 
Oid PQftable (const PGresult *res, int field_num)
 
int PQftablecol (const PGresult *res, int field_num)
 
int PQfformat (const PGresult *res, int field_num)
 
Oid PQftype (const PGresult *res, int field_num)
 
int PQfsize (const PGresult *res, int field_num)
 
int PQfmod (const PGresult *res, int field_num)
 
char * PQcmdStatus (PGresult *res)
 
char * PQoidStatus (const PGresult *res)
 
Oid PQoidValue (const PGresult *res)
 
char * PQcmdTuples (PGresult *res)
 
char * PQgetvalue (const PGresult *res, int tup_num, int field_num)
 
int PQgetlength (const PGresult *res, int tup_num, int field_num)
 
int PQgetisnull (const PGresult *res, int tup_num, int field_num)
 
int PQnparams (const PGresult *res)
 
Oid PQparamtype (const PGresult *res, int param_num)
 
PGresultPQdescribePrepared (PGconn *conn, const char *stmt)
 
PGresultPQdescribePortal (PGconn *conn, const char *portal)
 
int PQsendDescribePrepared (PGconn *conn, const char *stmt)
 
int PQsendDescribePortal (PGconn *conn, const char *portal)
 
PGresultPQclosePrepared (PGconn *conn, const char *stmt)
 
PGresultPQclosePortal (PGconn *conn, const char *portal)
 
int PQsendClosePrepared (PGconn *conn, const char *stmt)
 
int PQsendClosePortal (PGconn *conn, const char *portal)
 
void PQclear (PGresult *res)
 
void PQfreemem (void *ptr)
 
PGresultPQmakeEmptyPGresult (PGconn *conn, ExecStatusType status)
 
PGresultPQcopyResult (const PGresult *src, int flags)
 
int PQsetResultAttrs (PGresult *res, int numAttributes, PGresAttDesc *attDescs)
 
void * PQresultAlloc (PGresult *res, size_t nBytes)
 
size_t PQresultMemorySize (const PGresult *res)
 
int PQsetvalue (PGresult *res, int tup_num, int field_num, char *value, int len)
 
size_t PQescapeStringConn (PGconn *conn, char *to, const char *from, size_t length, int *error)
 
char * PQescapeLiteral (PGconn *conn, const char *str, size_t len)
 
char * PQescapeIdentifier (PGconn *conn, const char *str, size_t len)
 
unsigned char * PQescapeByteaConn (PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length)
 
unsigned char * PQunescapeBytea (const unsigned char *strtext, size_t *retbuflen)
 
size_t PQescapeString (char *to, const char *from, size_t length)
 
unsigned char * PQescapeBytea (const unsigned char *from, size_t from_length, size_t *to_length)
 
void PQprint (FILE *fout, const PGresult *res, const PQprintOpt *po)
 
void PQdisplayTuples (const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
 
void PQprintTuples (const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
 
int lo_open (PGconn *conn, Oid lobjId, int mode)
 
int lo_close (PGconn *conn, int fd)
 
int lo_read (PGconn *conn, int fd, char *buf, size_t len)
 
int lo_write (PGconn *conn, int fd, const char *buf, size_t len)
 
int lo_lseek (PGconn *conn, int fd, int offset, int whence)
 
pg_int64 lo_lseek64 (PGconn *conn, int fd, pg_int64 offset, int whence)
 
Oid lo_creat (PGconn *conn, int mode)
 
Oid lo_create (PGconn *conn, Oid lobjId)
 
int lo_tell (PGconn *conn, int fd)
 
pg_int64 lo_tell64 (PGconn *conn, int fd)
 
int lo_truncate (PGconn *conn, int fd, size_t len)
 
int lo_truncate64 (PGconn *conn, int fd, pg_int64 len)
 
int lo_unlink (PGconn *conn, Oid lobjId)
 
Oid lo_import (PGconn *conn, const char *filename)
 
Oid lo_import_with_oid (PGconn *conn, const char *filename, Oid lobjId)
 
int lo_export (PGconn *conn, Oid lobjId, const char *filename)
 
int PQlibVersion (void)
 
int PQsocketPoll (int sock, int forRead, int forWrite, pg_usec_time_t end_time)
 
pg_usec_time_t PQgetCurrentTimeUSec (void)
 
int PQmblen (const char *s, int encoding)
 
int PQmblenBounded (const char *s, int encoding)
 
int PQdsplen (const char *s, int encoding)
 
int PQenv2encoding (void)
 
char * PQencryptPassword (const char *passwd, const char *user)
 
char * PQencryptPasswordConn (PGconn *conn, const char *passwd, const char *user, const char *algorithm)
 
PGresultPQchangePassword (PGconn *conn, const char *user, const char *passwd)
 
int pg_char_to_encoding (const char *name)
 
const char * pg_encoding_to_char (int encoding)
 
int pg_valid_server_encoding_id (int encoding)
 
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL (void)
 
void PQsetSSLKeyPassHook_OpenSSL (PQsslKeyPassHook_OpenSSL_type hook)
 
int PQdefaultSSLKeyPassHook_OpenSSL (char *buf, int size, PGconn *conn)
 

Macro Definition Documentation

◆ LIBPQ_HAS_ASYNC_CANCEL

#define LIBPQ_HAS_ASYNC_CANCEL   1

Definition at line 47 of file libpq-fe.h.

◆ LIBPQ_HAS_CHANGE_PASSWORD

#define LIBPQ_HAS_CHANGE_PASSWORD   1

Definition at line 49 of file libpq-fe.h.

◆ LIBPQ_HAS_CHUNK_MODE

#define LIBPQ_HAS_CHUNK_MODE   1

Definition at line 51 of file libpq-fe.h.

◆ LIBPQ_HAS_CLOSE_PREPARED

#define LIBPQ_HAS_CLOSE_PREPARED   1

Definition at line 53 of file libpq-fe.h.

◆ LIBPQ_HAS_FULL_PROTOCOL_VERSION

#define LIBPQ_HAS_FULL_PROTOCOL_VERSION   1

Definition at line 61 of file libpq-fe.h.

◆ LIBPQ_HAS_PIPELINING

#define LIBPQ_HAS_PIPELINING   1

Definition at line 37 of file libpq-fe.h.

◆ LIBPQ_HAS_SEND_PIPELINE_SYNC

#define LIBPQ_HAS_SEND_PIPELINE_SYNC   1

Definition at line 55 of file libpq-fe.h.

◆ LIBPQ_HAS_SOCKET_POLL

#define LIBPQ_HAS_SOCKET_POLL   1

Definition at line 57 of file libpq-fe.h.

◆ LIBPQ_HAS_SSL_LIBRARY_DETECTION

#define LIBPQ_HAS_SSL_LIBRARY_DETECTION   1

Definition at line 43 of file libpq-fe.h.

◆ LIBPQ_HAS_TRACE_FLAGS

#define LIBPQ_HAS_TRACE_FLAGS   1

Definition at line 39 of file libpq-fe.h.

◆ PG_COPYRES_ATTRS

#define PG_COPYRES_ATTRS   0x01

Definition at line 66 of file libpq-fe.h.

◆ PG_COPYRES_EVENTS

#define PG_COPYRES_EVENTS   0x04

Definition at line 68 of file libpq-fe.h.

◆ PG_COPYRES_NOTICEHOOKS

#define PG_COPYRES_NOTICEHOOKS   0x08

Definition at line 69 of file libpq-fe.h.

◆ PG_COPYRES_TUPLES

#define PG_COPYRES_TUPLES   0x02 /* Implies PG_COPYRES_ATTRS */

Definition at line 67 of file libpq-fe.h.

◆ PQ_QUERY_PARAM_MAX_LIMIT

#define PQ_QUERY_PARAM_MAX_LIMIT   65535

Definition at line 495 of file libpq-fe.h.

◆ PQfreeNotify

#define PQfreeNotify (   ptr)    PQfreemem(ptr)

Definition at line 617 of file libpq-fe.h.

◆ PQnoPasswordSupplied

#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"

Definition at line 621 of file libpq-fe.h.

◆ PQsetdb

#define PQsetdb (   M_PGHOST,
  M_PGPORT,
  M_PGOPT,
  M_PGTTY,
  M_DBNAME 
)     PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)

Definition at line 327 of file libpq-fe.h.

◆ PQTRACE_REGRESS_MODE

#define PQTRACE_REGRESS_MODE   (1<<1)

Definition at line 468 of file libpq-fe.h.

◆ PQTRACE_SUPPRESS_TIMESTAMPS

#define PQTRACE_SUPPRESS_TIMESTAMPS   (1<<0)

Definition at line 466 of file libpq-fe.h.

Typedef Documentation

◆ pg_usec_time_t

Definition at line 226 of file libpq-fe.h.

◆ PGcancel

typedef struct pg_cancel PGcancel

Definition at line 1 of file libpq-fe.h.

◆ PGcancelConn

typedef struct pg_cancel_conn PGcancelConn

Definition at line 1 of file libpq-fe.h.

◆ PGconn

typedef struct pg_conn PGconn

Definition at line 1 of file libpq-fe.h.

◆ PGnotify

typedef struct pgNotify PGnotify

◆ PGresAttDesc

typedef struct pgresAttDesc PGresAttDesc

◆ PGresult

typedef struct pg_result PGresult

Definition at line 1 of file libpq-fe.h.

◆ pgthreadlock_t

typedef void(* pgthreadlock_t) (int acquire)

Definition at line 456 of file libpq-fe.h.

◆ pqbool

typedef char pqbool

Definition at line 233 of file libpq-fe.h.

◆ PQconninfoOption

◆ PQnoticeProcessor

typedef void(* PQnoticeProcessor) (void *arg, const char *message)

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

◆ PQnoticeReceiver

typedef void(* PQnoticeReceiver) (void *arg, const PGresult *res)

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

◆ PQprintOpt

typedef struct _PQprintOpt PQprintOpt

◆ PQsslKeyPassHook_OpenSSL_type

typedef int(* PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn)

Definition at line 733 of file libpq-fe.h.

Enumeration Type Documentation

◆ ConnStatusType

Enumerator
CONNECTION_OK 
CONNECTION_BAD 
CONNECTION_STARTED 
CONNECTION_MADE 
CONNECTION_AWAITING_RESPONSE 
CONNECTION_AUTH_OK 
CONNECTION_SETENV 
CONNECTION_SSL_STARTUP 
CONNECTION_NEEDED 
CONNECTION_CHECK_WRITABLE 
CONNECTION_CONSUME 
CONNECTION_GSS_STARTUP 
CONNECTION_CHECK_TARGET 
CONNECTION_CHECK_STANDBY 
CONNECTION_ALLOCATED 

Definition at line 79 of file libpq-fe.h.

80 {
83  /* Non-blocking mode only below here */
84 
85  /*
86  * The existence of these should never be relied upon - they should only
87  * be used for user feedback or similar purposes.
88  */
89  CONNECTION_STARTED, /* Waiting for connection to be made. */
90  CONNECTION_MADE, /* Connection OK; waiting to send. */
91  CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the
92  * postmaster. */
93  CONNECTION_AUTH_OK, /* Received authentication; waiting for
94  * backend startup. */
95  CONNECTION_SETENV, /* This state is no longer used. */
96  CONNECTION_SSL_STARTUP, /* Performing SSL handshake. */
97  CONNECTION_NEEDED, /* Internal state: connect() needed. */
98  CONNECTION_CHECK_WRITABLE, /* Checking if session is read-write. */
99  CONNECTION_CONSUME, /* Consuming any extra messages. */
100  CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */
101  CONNECTION_CHECK_TARGET, /* Internal state: checking target server
102  * properties. */
103  CONNECTION_CHECK_STANDBY, /* Checking if server is in standby mode. */
104  CONNECTION_ALLOCATED, /* Waiting for connection attempt to be
105  * started. */
ConnStatusType
Definition: libpq-fe.h:80
@ CONNECTION_CONSUME
Definition: libpq-fe.h:99
@ CONNECTION_CHECK_STANDBY
Definition: libpq-fe.h:103
@ CONNECTION_STARTED
Definition: libpq-fe.h:89
@ CONNECTION_AWAITING_RESPONSE
Definition: libpq-fe.h:91
@ CONNECTION_MADE
Definition: libpq-fe.h:90
@ CONNECTION_CHECK_WRITABLE
Definition: libpq-fe.h:98
@ CONNECTION_BAD
Definition: libpq-fe.h:82
@ CONNECTION_OK
Definition: libpq-fe.h:81
@ CONNECTION_GSS_STARTUP
Definition: libpq-fe.h:100
@ CONNECTION_ALLOCATED
Definition: libpq-fe.h:104
@ CONNECTION_SSL_STARTUP
Definition: libpq-fe.h:96
@ CONNECTION_AUTH_OK
Definition: libpq-fe.h:93
@ CONNECTION_CHECK_TARGET
Definition: libpq-fe.h:101
@ CONNECTION_NEEDED
Definition: libpq-fe.h:97
@ CONNECTION_SETENV
Definition: libpq-fe.h:95

◆ ExecStatusType

Enumerator
PGRES_EMPTY_QUERY 
PGRES_COMMAND_OK 
PGRES_TUPLES_OK 
PGRES_COPY_OUT 
PGRES_COPY_IN 
PGRES_BAD_RESPONSE 
PGRES_NONFATAL_ERROR 
PGRES_FATAL_ERROR 
PGRES_COPY_BOTH 
PGRES_SINGLE_TUPLE 
PGRES_PIPELINE_SYNC 
PGRES_PIPELINE_ABORTED 
PGRES_TUPLES_CHUNK 

Definition at line 117 of file libpq-fe.h.

118 {
119  PGRES_EMPTY_QUERY = 0, /* empty query string was executed */
120  PGRES_COMMAND_OK, /* a query command that doesn't return
121  * anything was executed properly by the
122  * backend */
123  PGRES_TUPLES_OK, /* a query command that returns tuples was
124  * executed properly by the backend, PGresult
125  * contains the result tuples */
126  PGRES_COPY_OUT, /* Copy Out data transfer in progress */
127  PGRES_COPY_IN, /* Copy In data transfer in progress */
128  PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the
129  * backend */
130  PGRES_NONFATAL_ERROR, /* notice or warning message */
131  PGRES_FATAL_ERROR, /* query failed */
132  PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */
133  PGRES_SINGLE_TUPLE, /* single tuple from larger resultset */
134  PGRES_PIPELINE_SYNC, /* pipeline synchronization point */
135  PGRES_PIPELINE_ABORTED, /* Command didn't run because of an abort
136  * earlier in a pipeline */
137  PGRES_TUPLES_CHUNK /* chunk of tuples from larger resultset */
ExecStatusType
Definition: libpq-fe.h:118
@ PGRES_COPY_IN
Definition: libpq-fe.h:127
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:132
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:120
@ PGRES_TUPLES_CHUNK
Definition: libpq-fe.h:137
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:131
@ PGRES_SINGLE_TUPLE
Definition: libpq-fe.h:133
@ PGRES_COPY_OUT
Definition: libpq-fe.h:126
@ PGRES_EMPTY_QUERY
Definition: libpq-fe.h:119
@ PGRES_PIPELINE_SYNC
Definition: libpq-fe.h:134
@ PGRES_BAD_RESPONSE
Definition: libpq-fe.h:128
@ PGRES_PIPELINE_ABORTED
Definition: libpq-fe.h:135
@ PGRES_NONFATAL_ERROR
Definition: libpq-fe.h:130
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:123

◆ PGContextVisibility

Enumerator
PQSHOW_CONTEXT_NEVER 
PQSHOW_CONTEXT_ERRORS 
PQSHOW_CONTEXT_ALWAYS 

Definition at line 157 of file libpq-fe.h.

158 {
159  PQSHOW_CONTEXT_NEVER, /* never show CONTEXT field */
160  PQSHOW_CONTEXT_ERRORS, /* show CONTEXT for errors only (default) */
161  PQSHOW_CONTEXT_ALWAYS /* always show CONTEXT field */
PGContextVisibility
Definition: libpq-fe.h:158
@ PQSHOW_CONTEXT_NEVER
Definition: libpq-fe.h:159
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:161
@ PQSHOW_CONTEXT_ERRORS
Definition: libpq-fe.h:160

◆ PGPing

enum PGPing
Enumerator
PQPING_OK 
PQPING_REJECT 
PQPING_NO_RESPONSE 
PQPING_NO_ATTEMPT 

Definition at line 169 of file libpq-fe.h.

170 {
171  PQPING_OK, /* server is accepting connections */
172  PQPING_REJECT, /* server is alive but rejecting connections */
173  PQPING_NO_RESPONSE, /* could not establish connection */
174  PQPING_NO_ATTEMPT /* connection not attempted (bad params) */
175 } PGPing;
PGPing
Definition: libpq-fe.h:170
@ PQPING_OK
Definition: libpq-fe.h:171
@ PQPING_REJECT
Definition: libpq-fe.h:172
@ PQPING_NO_RESPONSE
Definition: libpq-fe.h:173
@ PQPING_NO_ATTEMPT
Definition: libpq-fe.h:174

◆ PGpipelineStatus

Enumerator
PQ_PIPELINE_OFF 
PQ_PIPELINE_ON 
PQ_PIPELINE_ABORTED 

Definition at line 180 of file libpq-fe.h.

181 {
PGpipelineStatus
Definition: libpq-fe.h:181
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:182
@ PQ_PIPELINE_ABORTED
Definition: libpq-fe.h:184
@ PQ_PIPELINE_ON
Definition: libpq-fe.h:183

◆ PGTransactionStatusType

Enumerator
PQTRANS_IDLE 
PQTRANS_ACTIVE 
PQTRANS_INTRANS 
PQTRANS_INERROR 
PQTRANS_UNKNOWN 

Definition at line 140 of file libpq-fe.h.

141 {
142  PQTRANS_IDLE, /* connection idle */
143  PQTRANS_ACTIVE, /* command in progress */
144  PQTRANS_INTRANS, /* idle, within transaction block */
145  PQTRANS_INERROR, /* idle, within failed transaction */
146  PQTRANS_UNKNOWN /* cannot determine status */
PGTransactionStatusType
Definition: libpq-fe.h:141
@ PQTRANS_INTRANS
Definition: libpq-fe.h:144
@ PQTRANS_IDLE
Definition: libpq-fe.h:142
@ PQTRANS_ACTIVE
Definition: libpq-fe.h:143
@ PQTRANS_UNKNOWN
Definition: libpq-fe.h:146
@ PQTRANS_INERROR
Definition: libpq-fe.h:145

◆ PGVerbosity

Enumerator
PQERRORS_TERSE 
PQERRORS_DEFAULT 
PQERRORS_VERBOSE 
PQERRORS_SQLSTATE 

Definition at line 149 of file libpq-fe.h.

150 {
151  PQERRORS_TERSE, /* single-line error messages */
152  PQERRORS_DEFAULT, /* recommended style */
153  PQERRORS_VERBOSE, /* all the facts, ma'am */
154  PQERRORS_SQLSTATE /* only error severity and SQLSTATE code */
155 } PGVerbosity;
PGVerbosity
Definition: libpq-fe.h:150
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:153
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:152
@ PQERRORS_TERSE
Definition: libpq-fe.h:151
@ PQERRORS_SQLSTATE
Definition: libpq-fe.h:154

◆ PostgresPollingStatusType

Enumerator
PGRES_POLLING_FAILED 
PGRES_POLLING_READING 
PGRES_POLLING_WRITING 
PGRES_POLLING_OK 
PGRES_POLLING_ACTIVE 

Definition at line 108 of file libpq-fe.h.

109 {
111  PGRES_POLLING_READING, /* These two indicate that one may */
112  PGRES_POLLING_WRITING, /* use select before polling again. */
114  PGRES_POLLING_ACTIVE /* unused; keep for backwards compatibility */
PostgresPollingStatusType
Definition: libpq-fe.h:109
@ PGRES_POLLING_ACTIVE
Definition: libpq-fe.h:114
@ PGRES_POLLING_OK
Definition: libpq-fe.h:113
@ PGRES_POLLING_READING
Definition: libpq-fe.h:111
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:112
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:110

Function Documentation

◆ lo_close()

int lo_close ( PGconn conn,
int  fd 
)

Definition at line 96 of file fe-lobj.c.

97 {
98  PQArgBlock argv[1];
99  PGresult *res;
100  int retval;
101  int result_len;
102 
103  if (lo_initialize(conn) < 0)
104  return -1;
105 
106  argv[0].isint = 1;
107  argv[0].len = 4;
108  argv[0].u.integer = fd;
110  &retval, &result_len, 1, argv, 1);
112  {
113  PQclear(res);
114  return retval;
115  }
116  else
117  {
118  PQclear(res);
119  return -1;
120  }
121 }
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2980
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:843
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PGconn * conn
Definition: streamutil.c:55
int isint
Definition: libpq-fe.h:281
int integer
Definition: libpq-fe.h:285
union PQArgBlock::@180 u
Oid fn_lo_close
Definition: libpq-int.h:287
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:531

References conn, fd(), pgLobjfuncs::fn_lo_close, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by dumpLOs(), EndRestoreLO(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

Definition at line 438 of file fe-lobj.c.

439 {
440  PQArgBlock argv[1];
441  PGresult *res;
442  int retval;
443  int result_len;
444 
445  if (lo_initialize(conn) < 0)
446  return InvalidOid;
447 
448  argv[0].isint = 1;
449  argv[0].len = 4;
450  argv[0].u.integer = mode;
452  &retval, &result_len, 1, argv, 1);
454  {
455  PQclear(res);
456  return (Oid) retval;
457  }
458  else
459  {
460  PQclear(res);
461  return InvalidOid;
462  }
463 }
static PgChecksumMode mode
Definition: pg_checksums.c:56
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
Oid fn_lo_creat
Definition: libpq-int.h:288

References conn, pgLobjfuncs::fn_lo_creat, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by importFile(), and lo_import_internal().

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

Definition at line 474 of file fe-lobj.c.

475 {
476  PQArgBlock argv[1];
477  PGresult *res;
478  int retval;
479  int result_len;
480 
481  if (lo_initialize(conn) < 0)
482  return InvalidOid;
483 
484  /* Must check this on-the-fly because it's not there pre-8.1 */
485  if (conn->lobjfuncs->fn_lo_create == 0)
486  {
487  libpq_append_conn_error(conn, "cannot determine OID of function %s",
488  "lo_create");
489  return InvalidOid;
490  }
491 
492  argv[0].isint = 1;
493  argv[0].len = 4;
494  argv[0].u.integer = lobjId;
496  &retval, &result_len, 1, argv, 1);
498  {
499  PQclear(res);
500  return (Oid) retval;
501  }
502  else
503  {
504  PQclear(res);
505  return InvalidOid;
506  }
507 }
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1372
Oid fn_lo_create
Definition: libpq-int.h:289

References conn, pgLobjfuncs::fn_lo_create, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by lo_import_internal(), and StartRestoreLO().

◆ lo_export()

int lo_export ( PGconn conn,
Oid  lobjId,
const char *  filename 
)

Definition at line 748 of file fe-lobj.c.

749 {
750  int result = 1;
751  int fd;
752  int nbytes,
753  tmp;
754  char buf[LO_BUFSIZE];
755  int lobj;
756  char sebuf[PG_STRERROR_R_BUFLEN];
757 
758  /*
759  * open the large object.
760  */
761  lobj = lo_open(conn, lobjId, INV_READ);
762  if (lobj == -1)
763  {
764  /* we assume lo_open() already set a suitable error message */
765  return -1;
766  }
767 
768  /*
769  * create the file to be written to
770  */
771  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
772  if (fd < 0)
773  {
774  /* We must do lo_close before setting the errorMessage */
775  int save_errno = errno;
776 
777  (void) lo_close(conn, lobj);
778  /* deliberately overwrite any error from lo_close */
780  libpq_append_conn_error(conn, "could not open file \"%s\": %s",
781  filename,
782  strerror_r(save_errno, sebuf, sizeof(sebuf)));
783  return -1;
784  }
785 
786  /*
787  * read in from the large object and write to the file
788  */
789  while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
790  {
791  tmp = write(fd, buf, nbytes);
792  if (tmp != nbytes)
793  {
794  /* We must do lo_close before setting the errorMessage */
795  int save_errno = errno;
796 
797  (void) lo_close(conn, lobj);
798  (void) close(fd);
799  /* deliberately overwrite any error from lo_close */
801  libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
802  filename,
803  strerror_r(save_errno, sebuf, sizeof(sebuf)));
804  return -1;
805  }
806  }
807 
808  /*
809  * If lo_read() failed, we are now in an aborted transaction so there's no
810  * need for lo_close(); furthermore, if we tried it we'd overwrite the
811  * useful error result with a useless one. So skip lo_close() if we got a
812  * failure result.
813  */
814  if (nbytes < 0 ||
815  lo_close(conn, lobj) != 0)
816  {
817  /* assume lo_read() or lo_close() left a suitable error message */
818  result = -1;
819  }
820 
821  /* if we already failed, don't overwrite that msg with a close error */
822  if (close(fd) != 0 && result >= 0)
823  {
824  libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
825  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
826  result = -1;
827  }
828 
829  return result;
830 }
#define PG_BINARY
Definition: c.h:1273
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
#define LO_BUFSIZE
Definition: fe-lobj.c:42
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:245
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
#define INV_READ
Definition: libpq-fs.h:22
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:878
static char * filename
Definition: pg_dumpall.c:119
static char * buf
Definition: pg_test_fsync.c:73
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
#define strerror_r
Definition: port.h:255

References buf, close, conn, fd(), filename, INV_READ, libpq_append_conn_error(), LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, PG_STRERROR_R_BUFLEN, pqClearConnErrorState, strerror_r, and write.

Referenced by do_lo_export(), and main().

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

Definition at line 626 of file fe-lobj.c.

627 {
629 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:647

References conn, filename, InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

◆ lo_import_with_oid()

Oid lo_import_with_oid ( PGconn conn,
const char *  filename,
Oid  lobjId 
)

Definition at line 641 of file fe-lobj.c.

642 {
643  return lo_import_internal(conn, filename, lobjId);
644 }

References conn, filename, and lo_import_internal().

◆ lo_lseek()

int lo_lseek ( PGconn conn,
int  fd,
int  offset,
int  whence 
)

Definition at line 344 of file fe-lobj.c.

345 {
346  PQArgBlock argv[3];
347  PGresult *res;
348  int retval;
349  int result_len;
350 
351  if (lo_initialize(conn) < 0)
352  return -1;
353 
354  argv[0].isint = 1;
355  argv[0].len = 4;
356  argv[0].u.integer = fd;
357 
358  argv[1].isint = 1;
359  argv[1].len = 4;
360  argv[1].u.integer = offset;
361 
362  argv[2].isint = 1;
363  argv[2].len = 4;
364  argv[2].u.integer = whence;
365 
367  &retval, &result_len, 1, argv, 3);
369  {
370  PQclear(res);
371  return retval;
372  }
373  else
374  {
375  PQclear(res);
376  return -1;
377  }
378 }
Oid fn_lo_lseek
Definition: libpq-int.h:291

References conn, fd(), pgLobjfuncs::fn_lo_lseek, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

◆ lo_lseek64()

pg_int64 lo_lseek64 ( PGconn conn,
int  fd,
pg_int64  offset,
int  whence 
)

Definition at line 385 of file fe-lobj.c.

386 {
387  PQArgBlock argv[3];
388  PGresult *res;
389  pg_int64 retval;
390  int result_len;
391 
392  if (lo_initialize(conn) < 0)
393  return -1;
394 
395  if (conn->lobjfuncs->fn_lo_lseek64 == 0)
396  {
397  libpq_append_conn_error(conn, "cannot determine OID of function %s",
398  "lo_lseek64");
399  return -1;
400  }
401 
402  argv[0].isint = 1;
403  argv[0].len = 4;
404  argv[0].u.integer = fd;
405 
406  offset = lo_hton64(offset);
407  argv[1].isint = 0;
408  argv[1].len = 8;
409  argv[1].u.ptr = (int *) &offset;
410 
411  argv[2].isint = 1;
412  argv[2].len = 4;
413  argv[2].u.integer = whence;
414 
416  (void *) &retval, &result_len, 0, argv, 3);
417  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
418  {
419  PQclear(res);
420  return lo_ntoh64(retval);
421  }
422  else
423  {
424  PQclear(res);
425  return -1;
426  }
427 }
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1048
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1023
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
int * ptr
Definition: libpq-fe.h:284
Oid fn_lo_lseek64
Definition: libpq-int.h:292

References conn, fd(), pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_hton64(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

◆ lo_open()

int lo_open ( PGconn conn,
Oid  lobjId,
int  mode 
)

Definition at line 57 of file fe-lobj.c.

58 {
59  int fd;
60  int result_len;
61  PQArgBlock argv[2];
62  PGresult *res;
63 
64  if (lo_initialize(conn) < 0)
65  return -1;
66 
67  argv[0].isint = 1;
68  argv[0].len = 4;
69  argv[0].u.integer = lobjId;
70 
71  argv[1].isint = 1;
72  argv[1].len = 4;
73  argv[1].u.integer = mode;
74 
75  res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
77  {
78  PQclear(res);
79  return fd;
80  }
81  else
82  {
83  PQclear(res);
84  return -1;
85  }
86 }
Oid fn_lo_open
Definition: libpq-int.h:286

References conn, fd(), pgLobjfuncs::fn_lo_open, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by dumpLOs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreLO().

◆ lo_read()

int lo_read ( PGconn conn,
int  fd,
char *  buf,
size_t  len 
)

Definition at line 245 of file fe-lobj.c.

246 {
247  PQArgBlock argv[2];
248  PGresult *res;
249  int result_len;
250 
251  if (lo_initialize(conn) < 0)
252  return -1;
253 
254  /*
255  * Long ago, somebody thought it'd be a good idea to declare this function
256  * as taking size_t ... but the underlying backend function only accepts a
257  * signed int32 length. So throw error if the given value overflows
258  * int32.
259  */
260  if (len > (size_t) INT_MAX)
261  {
262  libpq_append_conn_error(conn, "argument of lo_read exceeds integer range");
263  return -1;
264  }
265 
266  argv[0].isint = 1;
267  argv[0].len = 4;
268  argv[0].u.integer = fd;
269 
270  argv[1].isint = 1;
271  argv[1].len = 4;
272  argv[1].u.integer = (int) len;
273 
275  (void *) buf, &result_len, 0, argv, 2);
277  {
278  PQclear(res);
279  return result_len;
280  }
281  else
282  {
283  PQclear(res);
284  return -1;
285  }
286 }
const void size_t len
Oid fn_lo_read
Definition: libpq-int.h:297

References buf, conn, fd(), pgLobjfuncs::fn_lo_read, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by lo_export().

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 515 of file fe-lobj.c.

516 {
517  int retval;
518  PQArgBlock argv[1];
519  PGresult *res;
520  int result_len;
521 
522  if (lo_initialize(conn) < 0)
523  return -1;
524 
525  argv[0].isint = 1;
526  argv[0].len = 4;
527  argv[0].u.integer = fd;
528 
530  &retval, &result_len, 1, argv, 1);
532  {
533  PQclear(res);
534  return retval;
535  }
536  else
537  {
538  PQclear(res);
539  return -1;
540  }
541 }
Oid fn_lo_tell
Definition: libpq-int.h:293

References conn, fd(), pgLobjfuncs::fn_lo_tell, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

◆ lo_tell64()

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

Definition at line 548 of file fe-lobj.c.

549 {
550  pg_int64 retval;
551  PQArgBlock argv[1];
552  PGresult *res;
553  int result_len;
554 
555  if (lo_initialize(conn) < 0)
556  return -1;
557 
558  if (conn->lobjfuncs->fn_lo_tell64 == 0)
559  {
560  libpq_append_conn_error(conn, "cannot determine OID of function %s",
561  "lo_tell64");
562  return -1;
563  }
564 
565  argv[0].isint = 1;
566  argv[0].len = 4;
567  argv[0].u.integer = fd;
568 
570  (void *) &retval, &result_len, 0, argv, 1);
571  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
572  {
573  PQclear(res);
574  return lo_ntoh64(retval);
575  }
576  else
577  {
578  PQclear(res);
579  return -1;
580  }
581 }
Oid fn_lo_tell64
Definition: libpq-int.h:294

References conn, fd(), pgLobjfuncs::fn_lo_tell64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by pickout().

◆ lo_truncate()

int lo_truncate ( PGconn conn,
int  fd,
size_t  len 
)

Definition at line 131 of file fe-lobj.c.

132 {
133  PQArgBlock argv[2];
134  PGresult *res;
135  int retval;
136  int result_len;
137 
138  if (lo_initialize(conn) < 0)
139  return -1;
140 
141  /* Must check this on-the-fly because it's not there pre-8.3 */
142  if (conn->lobjfuncs->fn_lo_truncate == 0)
143  {
144  libpq_append_conn_error(conn, "cannot determine OID of function %s",
145  "lo_truncate");
146  return -1;
147  }
148 
149  /*
150  * Long ago, somebody thought it'd be a good idea to declare this function
151  * as taking size_t ... but the underlying backend function only accepts a
152  * signed int32 length. So throw error if the given value overflows
153  * int32. (A possible alternative is to automatically redirect the call
154  * to lo_truncate64; but if the caller wanted to rely on that backend
155  * function being available, he could have called lo_truncate64 for
156  * himself.)
157  */
158  if (len > (size_t) INT_MAX)
159  {
160  libpq_append_conn_error(conn, "argument of lo_truncate exceeds integer range");
161  return -1;
162  }
163 
164  argv[0].isint = 1;
165  argv[0].len = 4;
166  argv[0].u.integer = fd;
167 
168  argv[1].isint = 1;
169  argv[1].len = 4;
170  argv[1].u.integer = (int) len;
171 
173  &retval, &result_len, 1, argv, 2);
174 
176  {
177  PQclear(res);
178  return retval;
179  }
180  else
181  {
182  PQclear(res);
183  return -1;
184  }
185 }
Oid fn_lo_truncate
Definition: libpq-int.h:295

References conn, fd(), pgLobjfuncs::fn_lo_truncate, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

◆ lo_truncate64()

int lo_truncate64 ( PGconn conn,
int  fd,
pg_int64  len 
)

Definition at line 195 of file fe-lobj.c.

196 {
197  PQArgBlock argv[2];
198  PGresult *res;
199  int retval;
200  int result_len;
201 
202  if (lo_initialize(conn) < 0)
203  return -1;
204 
205  if (conn->lobjfuncs->fn_lo_truncate64 == 0)
206  {
207  libpq_append_conn_error(conn, "cannot determine OID of function %s",
208  "lo_truncate64");
209  return -1;
210  }
211 
212  argv[0].isint = 1;
213  argv[0].len = 4;
214  argv[0].u.integer = fd;
215 
216  len = lo_hton64(len);
217  argv[1].isint = 0;
218  argv[1].len = 8;
219  argv[1].u.ptr = (int *) &len;
220 
222  &retval, &result_len, 1, argv, 2);
223 
225  {
226  PQclear(res);
227  return retval;
228  }
229  else
230  {
231  PQclear(res);
232  return -1;
233  }
234 }
Oid fn_lo_truncate64
Definition: libpq-int.h:296

References conn, fd(), pgLobjfuncs::fn_lo_truncate64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_hton64(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, and PQArgBlock::u.

Referenced by my_truncate().

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 589 of file fe-lobj.c.

590 {
591  PQArgBlock argv[1];
592  PGresult *res;
593  int result_len;
594  int retval;
595 
596  if (lo_initialize(conn) < 0)
597  return -1;
598 
599  argv[0].isint = 1;
600  argv[0].len = 4;
601  argv[0].u.integer = lobjId;
602 
604  &retval, &result_len, 1, argv, 1);
606  {
607  PQclear(res);
608  return retval;
609  }
610  else
611  {
612  PQclear(res);
613  return -1;
614  }
615 }
Oid fn_lo_unlink
Definition: libpq-int.h:290

References conn, pgLobjfuncs::fn_lo_unlink, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by do_lo_unlink(), and vacuumlo().

◆ lo_write()

int lo_write ( PGconn conn,
int  fd,
const char *  buf,
size_t  len 
)

Definition at line 295 of file fe-lobj.c.

296 {
297  PQArgBlock argv[2];
298  PGresult *res;
299  int result_len;
300  int retval;
301 
302  if (lo_initialize(conn) < 0)
303  return -1;
304 
305  /*
306  * Long ago, somebody thought it'd be a good idea to declare this function
307  * as taking size_t ... but the underlying backend function only accepts a
308  * signed int32 length. So throw error if the given value overflows
309  * int32.
310  */
311  if (len > (size_t) INT_MAX)
312  {
313  libpq_append_conn_error(conn, "argument of lo_write exceeds integer range");
314  return -1;
315  }
316 
317  argv[0].isint = 1;
318  argv[0].len = 4;
319  argv[0].u.integer = fd;
320 
321  argv[1].isint = 0;
322  argv[1].len = (int) len;
323  argv[1].u.ptr = (int *) unconstify(char *, buf);
324 
326  &retval, &result_len, 1, argv, 2);
328  {
329  PQclear(res);
330  return retval;
331  }
332  else
333  {
334  PQclear(res);
335  return -1;
336  }
337 }
#define unconstify(underlying_type, expr)
Definition: c.h:1245
Oid fn_lo_write
Definition: libpq-int.h:298

References buf, conn, fd(), pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, PQArgBlock::u, and unconstify.

Referenced by lo_import_internal().

◆ pg_char_to_encoding()

int pg_char_to_encoding ( const char *  name)

Definition at line 549 of file encnames.c.

550 {
551  unsigned int nel = lengthof(pg_encname_tbl);
552  const pg_encname *base = pg_encname_tbl,
553  *last = base + nel - 1,
554  *position;
555  int result;
556  char buff[NAMEDATALEN],
557  *key;
558 
559  if (name == NULL || *name == '\0')
560  return -1;
561 
562  if (strlen(name) >= NAMEDATALEN)
563  return -1; /* it's certainly not in the table */
564 
565  key = clean_encoding_name(name, buff);
566 
567  while (last >= base)
568  {
569  position = base + ((last - base) >> 1);
570  result = key[0] - position->name[0];
571 
572  if (result == 0)
573  {
574  result = strcmp(key, position->name);
575  if (result == 0)
576  return position->encoding;
577  }
578  if (result < 0)
579  last = position - 1;
580  else
581  base = position + 1;
582  }
583  return -1;
584 }
#define lengthof(array)
Definition: c.h:788
static const pg_encname pg_encname_tbl[]
Definition: encnames.c:39
static char * clean_encoding_name(const char *key, char *newkey)
Definition: encnames.c:524
#define NAMEDATALEN
const char * name

References clean_encoding_name(), sort-test::key, lengthof, name, NAMEDATALEN, and pg_encname_tbl.

Referenced by pg_valid_client_encoding(), and pg_valid_server_encoding().

◆ pg_encoding_to_char()

const char* pg_encoding_to_char ( int  encoding)

Definition at line 587 of file encnames.c.

588 {
590  {
591  const pg_enc2name *p = &pg_enc2name_tbl[encoding];
592 
593  Assert(encoding == p->encoding);
594  return p->name;
595  }
596  return "";
597 }
#define Assert(condition)
Definition: c.h:858
const pg_enc2name pg_enc2name_tbl[]
Definition: encnames.c:308
int32 encoding
Definition: pg_database.h:41
#define PG_VALID_ENCODING(_enc)
Definition: pg_wchar.h:287
pg_enc encoding
Definition: pg_wchar.h:342
const char * name
Definition: pg_wchar.h:341

References Assert, encoding, pg_enc2name::encoding, pg_enc2name::name, pg_enc2name_tbl, and PG_VALID_ENCODING.

◆ pg_valid_server_encoding_id()

int pg_valid_server_encoding_id ( int  encoding)

Definition at line 513 of file encnames.c.

514 {
516 }
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:281

References encoding, and PG_VALID_BE_ENCODING.

◆ PQbackendPID()

int PQbackendPID ( const PGconn conn)

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

7217 {
7218  if (!conn || conn->status != CONNECTION_OK)
7219  return 0;
7220  return conn->be_pid;
7221 }
int be_pid
Definition: libpq-int.h:522
ConnStatusType status
Definition: libpq-int.h:448

References pg_conn::be_pid, conn, CONNECTION_OK, and pg_conn::status.

Referenced by get_prompt(), libpqrcv_get_backend_pid(), main(), send_cancellable_query_impl(), and StartLogStreamer().

◆ PQbinaryTuples()

int PQbinaryTuples ( const PGresult res)

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

3498 {
3499  if (!res)
3500  return 0;
3501  return res->binary;
3502 }
int binary
Definition: libpq-int.h:182

References pg_result::binary, and res.

Referenced by HandleCopyResult().

◆ PQcancel()

int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

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

464 {
465  int save_errno = SOCK_ERRNO;
466  pgsocket tmpsock = PGINVALID_SOCKET;
467  int maxlen;
468  struct
469  {
470  uint32 packetlen;
472  } crp;
473 
474  if (!cancel)
475  {
476  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
477  /* strlcpy probably doesn't change errno, but be paranoid */
478  SOCK_ERRNO_SET(save_errno);
479  return false;
480  }
481 
482  /*
483  * We need to open a temporary connection to the postmaster. Do this with
484  * only kernel calls.
485  */
486  if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
487  {
488  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
489  goto cancel_errReturn;
490  }
491 
492  /*
493  * Since this connection will only be used to send a single packet of
494  * data, we don't need NODELAY. We also don't set the socket to
495  * nonblocking mode, because the API definition of PQcancel requires the
496  * cancel to be sent in a blocking way.
497  *
498  * We do set socket options related to keepalives and other TCP timeouts.
499  * This ensures that this function does not block indefinitely when
500  * reasonable keepalive and timeout settings have been provided.
501  */
502  if (cancel->raddr.addr.ss_family != AF_UNIX &&
503  cancel->keepalives != 0)
504  {
505 #ifndef WIN32
506  if (!optional_setsockopt(tmpsock, SOL_SOCKET, SO_KEEPALIVE, 1))
507  {
508  strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize);
509  goto cancel_errReturn;
510  }
511 
512 #ifdef PG_TCP_KEEPALIVE_IDLE
513  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
514  cancel->keepalives_idle))
515  {
516  strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize);
517  goto cancel_errReturn;
518  }
519 #endif
520 
521 #ifdef TCP_KEEPINTVL
522  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPINTVL,
523  cancel->keepalives_interval))
524  {
525  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize);
526  goto cancel_errReturn;
527  }
528 #endif
529 
530 #ifdef TCP_KEEPCNT
531  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPCNT,
532  cancel->keepalives_count))
533  {
534  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize);
535  goto cancel_errReturn;
536  }
537 #endif
538 
539 #else /* WIN32 */
540 
541 #ifdef SIO_KEEPALIVE_VALS
542  if (!pqSetKeepalivesWin32(tmpsock,
543  cancel->keepalives_idle,
544  cancel->keepalives_interval))
545  {
546  strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize);
547  goto cancel_errReturn;
548  }
549 #endif /* SIO_KEEPALIVE_VALS */
550 #endif /* WIN32 */
551 
552  /* TCP_USER_TIMEOUT works the same way on Unix and Windows */
553 #ifdef TCP_USER_TIMEOUT
554  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT,
555  cancel->pgtcp_user_timeout))
556  {
557  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize);
558  goto cancel_errReturn;
559  }
560 #endif
561  }
562 
563 retry3:
564  if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
565  cancel->raddr.salen) < 0)
566  {
567  if (SOCK_ERRNO == EINTR)
568  /* Interrupted system call - we'll just try again */
569  goto retry3;
570  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
571  goto cancel_errReturn;
572  }
573 
574  /* Create and send the cancel request packet. */
575 
576  crp.packetlen = pg_hton32((uint32) sizeof(crp));
577  crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
578  crp.cp.backendPID = pg_hton32(cancel->be_pid);
579  crp.cp.cancelAuthCode = pg_hton32(cancel->be_key);
580 
581 retry4:
582  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
583  {
584  if (SOCK_ERRNO == EINTR)
585  /* Interrupted system call - we'll just try again */
586  goto retry4;
587  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
588  goto cancel_errReturn;
589  }
590 
591  /*
592  * Wait for the postmaster to close the connection, which indicates that
593  * it's processed the request. Without this delay, we might issue another
594  * command only to find that our cancel zaps that command instead of the
595  * one we thought we were canceling. Note we don't actually expect this
596  * read to obtain any data, we are just waiting for EOF to be signaled.
597  */
598 retry5:
599  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
600  {
601  if (SOCK_ERRNO == EINTR)
602  /* Interrupted system call - we'll just try again */
603  goto retry5;
604  /* we ignore other error conditions */
605  }
606 
607  /* All done */
608  closesocket(tmpsock);
609  SOCK_ERRNO_SET(save_errno);
610  return true;
611 
612 cancel_errReturn:
613 
614  /*
615  * Make sure we don't overflow the error buffer. Leave space for the \n at
616  * the end, and for the terminating zero.
617  */
618  maxlen = errbufsize - strlen(errbuf) - 2;
619  if (maxlen >= 0)
620  {
621  /*
622  * We can't invoke strerror here, since it's not signal-safe. Settle
623  * for printing the decimal value of errno. Even that has to be done
624  * the hard way.
625  */
626  int val = SOCK_ERRNO;
627  char buf[32];
628  char *bufp;
629 
630  bufp = buf + sizeof(buf) - 1;
631  *bufp = '\0';
632  do
633  {
634  *(--bufp) = (val % 10) + '0';
635  val /= 10;
636  } while (val > 0);
637  bufp -= 6;
638  memcpy(bufp, "error ", 6);
639  strncat(errbuf, bufp, maxlen);
640  strcat(errbuf, "\n");
641  }
642  if (tmpsock != PGINVALID_SOCKET)
643  closesocket(tmpsock);
644  SOCK_ERRNO_SET(save_errno);
645  return false;
646 }
unsigned int uint32
Definition: c.h:506
static bool optional_setsockopt(int fd, int protoid, int optid, int value)
Definition: fe-cancel.c:431
long val
Definition: informix.c:689
#define SOCK_ERRNO
Definition: libpq-int.h:926
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:928
#define pg_hton32(x)
Definition: pg_bswap.h:121
int pgsocket
Definition: port.h:29
#define PGINVALID_SOCKET
Definition: port.h:31
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define closesocket
Definition: port.h:349
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:133
ProtocolVersion MsgType
Definition: pqcomm.h:102
struct sockaddr_storage addr
Definition: pqcomm.h:32
socklen_t salen
Definition: pqcomm.h:33
int pgtcp_user_timeout
Definition: fe-cancel.c:45
int keepalives_interval
Definition: fe-cancel.c:48
int keepalives_idle
Definition: fe-cancel.c:47
int keepalives_count
Definition: fe-cancel.c:50
SockAddr raddr
Definition: fe-cancel.c:42
int be_pid
Definition: fe-cancel.c:43
int keepalives
Definition: fe-cancel.c:46
int be_key
Definition: fe-cancel.c:44
#define EINTR
Definition: win32_port.h:374
#define recv(s, buf, len, flags)
Definition: win32_port.h:514
#define send(s, buf, len, flags)
Definition: win32_port.h:515
#define socket(af, type, protocol)
Definition: win32_port.h:508
#define connect(s, name, namelen)
Definition: win32_port.h:512

References SockAddr::addr, pg_cancel::be_key, pg_cancel::be_pid, buf, CANCEL_REQUEST_CODE, closesocket, connect, EINTR, pg_cancel::keepalives, pg_cancel::keepalives_count, pg_cancel::keepalives_idle, pg_cancel::keepalives_interval, optional_setsockopt(), pg_hton32, PGINVALID_SOCKET, pg_cancel::pgtcp_user_timeout, pg_cancel::raddr, recv, SockAddr::salen, send, SOCK_ERRNO, SOCK_ERRNO_SET, socket, strlcpy(), and val.

Referenced by DisconnectDatabase(), handle_sigint(), PQrequestCancel(), ShutdownWorkersHard(), sigTermHandler(), and test_cancel().

◆ PQcancelBlocking()

int PQcancelBlocking ( PGcancelConn cancelConn)

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

172 {
174  return 0;
175  return pqConnectDBComplete(&cancelConn->conn);
176 }
static PGcancel *volatile cancelConn
Definition: cancel.c:43
int PQcancelStart(PGcancelConn *cancelConn)
Definition: fe-cancel.c:185
int pqConnectDBComplete(PGconn *conn)
Definition: fe-connect.c:2471

References cancelConn, PQcancelStart(), and pqConnectDBComplete().

Referenced by disconnectDatabase(), test_cancel(), and try_complete_step().

◆ PQcancelCreate()

PGcancelConn* PQcancelCreate ( PGconn conn)

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

66 {
68  pg_conn_host originalHost;
69 
70  if (cancelConn == NULL)
71  return NULL;
72 
73  /* Check we have an open connection */
74  if (!conn)
75  {
76  libpq_append_conn_error(cancelConn, "connection pointer is NULL");
77  return (PGcancelConn *) cancelConn;
78  }
79 
80  if (conn->sock == PGINVALID_SOCKET)
81  {
82  libpq_append_conn_error(cancelConn, "connection not open");
83  return (PGcancelConn *) cancelConn;
84  }
85 
86  /*
87  * Indicate that this connection is used to send a cancellation
88  */
89  cancelConn->cancelRequest = true;
90 
92  return (PGcancelConn *) cancelConn;
93 
94  /*
95  * Compute derived options
96  */
98  return (PGcancelConn *) cancelConn;
99 
100  /*
101  * Copy cancellation token data from the original connection
102  */
105 
106  /*
107  * Cancel requests should not iterate over all possible hosts. The request
108  * needs to be sent to the exact host and address that the original
109  * connection used. So we manually create the host and address arrays with
110  * a single element after freeing the host array that we generated from
111  * the connection options.
112  */
114  cancelConn->nconnhost = 1;
115  cancelConn->naddr = 1;
116 
117  cancelConn->connhost = calloc(cancelConn->nconnhost, sizeof(pg_conn_host));
118  if (!cancelConn->connhost)
119  goto oom_error;
120 
121  originalHost = conn->connhost[conn->whichhost];
122  if (originalHost.host)
123  {
124  cancelConn->connhost[0].host = strdup(originalHost.host);
125  if (!cancelConn->connhost[0].host)
126  goto oom_error;
127  }
128  if (originalHost.hostaddr)
129  {
130  cancelConn->connhost[0].hostaddr = strdup(originalHost.hostaddr);
131  if (!cancelConn->connhost[0].hostaddr)
132  goto oom_error;
133  }
134  if (originalHost.port)
135  {
136  cancelConn->connhost[0].port = strdup(originalHost.port);
137  if (!cancelConn->connhost[0].port)
138  goto oom_error;
139  }
140  if (originalHost.password)
141  {
142  cancelConn->connhost[0].password = strdup(originalHost.password);
143  if (!cancelConn->connhost[0].password)
144  goto oom_error;
145  }
146 
147  cancelConn->addr = calloc(cancelConn->naddr, sizeof(AddrInfo));
148  if (!cancelConn->addr)
149  goto oom_error;
150 
151  cancelConn->addr[0].addr = conn->raddr;
152  cancelConn->addr[0].family = conn->raddr.addr.ss_family;
153 
155  return (PGcancelConn *) cancelConn;
156 
157 oom_error:
158  cancelConn->status = CONNECTION_BAD;
159  libpq_append_conn_error(cancelConn, "out of memory");
160  return (PGcancelConn *) cancelConn;
161 }
bool pqConnectOptions2(PGconn *conn)
Definition: fe-connect.c:1121
void pqReleaseConnHosts(PGconn *conn)
Definition: fe-connect.c:4731
PGconn * pqMakeEmptyPGconn(void)
Definition: fe-connect.c:4550
bool pqCopyPGconn(PGconn *srcConn, PGconn *dstConn)
Definition: fe-connect.c:957
#define calloc(a, b)
Definition: header.h:55
char * host
Definition: libpq-int.h:364
char * password
Definition: libpq-int.h:367
char * port
Definition: libpq-int.h:366
char * hostaddr
Definition: libpq-int.h:365
pgsocket sock
Definition: libpq-int.h:485
int be_key
Definition: libpq-int.h:523
SockAddr raddr
Definition: libpq-int.h:488
int whichhost
Definition: libpq-int.h:467
pg_conn_host * connhost
Definition: libpq-int.h:468

References SockAddr::addr, pg_cancel::be_key, pg_conn::be_key, pg_cancel::be_pid, pg_conn::be_pid, calloc, cancelConn, conn, CONNECTION_ALLOCATED, CONNECTION_BAD, pg_conn::connhost, pg_conn_host::host, pg_conn_host::hostaddr, libpq_append_conn_error(), pg_conn_host::password, PGINVALID_SOCKET, pg_conn_host::port, pqConnectOptions2(), pqCopyPGconn(), pqMakeEmptyPGconn(), pqReleaseConnHosts(), pg_conn::raddr, pg_conn::sock, and pg_conn::whichhost.

Referenced by disconnectDatabase(), libpqsrv_cancel(), test_cancel(), and try_complete_step().

◆ PQcancelErrorMessage()

char* PQcancelErrorMessage ( const PGcancelConn cancelConn)

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

307 {
308  return PQerrorMessage(&cancelConn->conn);
309 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7182

References cancelConn, and PQerrorMessage().

Referenced by libpqsrv_cancel(), test_cancel(), and try_complete_step().

◆ PQcancelFinish()

void PQcancelFinish ( PGcancelConn cancelConn)

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

335 {
336  PQfinish(&cancelConn->conn);
337 }
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4893

References cancelConn, and PQfinish().

Referenced by disconnectDatabase(), libpqsrv_cancel(), test_cancel(), and try_complete_step().

◆ PQcancelPoll()

PostgresPollingStatusType PQcancelPoll ( PGcancelConn cancelConn)

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

208 {
209  PGconn *conn = &cancelConn->conn;
210  int n;
211 
212  /*
213  * We leave most of the connection establishment to PQconnectPoll, since
214  * it's very similar to normal connection establishment. But once we get
215  * to the CONNECTION_AWAITING_RESPONSE we need to start doing our own
216  * thing.
217  */
219  {
220  return PQconnectPoll(conn);
221  }
222 
223  /*
224  * At this point we are waiting on the server to close the connection,
225  * which is its way of communicating that the cancel has been handled.
226  */
227 
228  n = pqReadData(conn);
229 
230  if (n == 0)
231  return PGRES_POLLING_READING;
232 
233 #ifndef WIN32
234 
235  /*
236  * If we receive an error report it, but only if errno is non-zero.
237  * Otherwise we assume it's an EOF, which is what we expect from the
238  * server.
239  *
240  * We skip this for Windows, because Windows is a bit special in its EOF
241  * behaviour for TCP. Sometimes it will error with an ECONNRESET when
242  * there is a clean connection closure. See these threads for details:
243  * https://www.postgresql.org/message-id/flat/90b34057-4176-7bb0-0dbb-9822a5f6425b%40greiz-reinsdorf.de
244  *
245  * https://www.postgresql.org/message-id/flat/CA%2BhUKG%2BOeoETZQ%3DQw5Ub5h3tmwQhBmDA%3DnuNO3KG%3DzWfUypFAw%40mail.gmail.com
246  *
247  * PQcancel ignores such errors and reports success for the cancellation
248  * anyway, so even if this is not always correct we do the same here.
249  */
250  if (n < 0 && errno != 0)
251  {
253  return PGRES_POLLING_FAILED;
254  }
255 #endif
256 
257  /*
258  * We don't expect any data, only connection closure. So if we strangely
259  * do receive some data we consider that an error.
260  */
261  if (n > 0)
262  {
263  libpq_append_conn_error(conn, "unexpected response from server");
265  return PGRES_POLLING_FAILED;
266  }
267 
268  /*
269  * Getting here means that we received an EOF, which is what we were
270  * expecting -- the cancel request has completed.
271  */
272  cancelConn->conn.status = CONNECTION_OK;
274  return PGRES_POLLING_OK;
275 }
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2597
int pqReadData(PGconn *conn)
Definition: fe-misc.c:580
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
PQExpBufferData errorMessage
Definition: libpq-int.h:642

References cancelConn, conn, CONNECTION_AWAITING_RESPONSE, CONNECTION_BAD, CONNECTION_OK, pg_conn::errorMessage, libpq_append_conn_error(), PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PQconnectPoll(), pqReadData(), resetPQExpBuffer(), and pg_conn::status.

Referenced by libpqsrv_cancel(), pqConnectDBComplete(), and test_cancel().

◆ PQcancelReset()

void PQcancelReset ( PGcancelConn cancelConn)

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

319 {
320  pqClosePGconn(&cancelConn->conn);
321  cancelConn->conn.status = CONNECTION_ALLOCATED;
322  cancelConn->conn.whichhost = 0;
323  cancelConn->conn.whichaddr = 0;
324  cancelConn->conn.try_next_host = false;
325  cancelConn->conn.try_next_addr = false;
326 }
void pqClosePGconn(PGconn *conn)
Definition: fe-connect.c:4847

References cancelConn, CONNECTION_ALLOCATED, and pqClosePGconn().

Referenced by test_cancel().

◆ PQcancelSocket()

int PQcancelSocket ( const PGcancelConn cancelConn)

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

295 {
296  return PQsocket(&cancelConn->conn);
297 }
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7208

References cancelConn, and PQsocket().

Referenced by libpqsrv_cancel(), and test_cancel().

◆ PQcancelStart()

int PQcancelStart ( PGcancelConn cancelConn)

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

186 {
187  if (!cancelConn || cancelConn->conn.status == CONNECTION_BAD)
188  return 0;
189 
190  if (cancelConn->conn.status != CONNECTION_ALLOCATED)
191  {
193  "cancel request is already being sent on this connection");
194  cancelConn->conn.status = CONNECTION_BAD;
195  return 0;
196  }
197 
198  return pqConnectDBStart(&cancelConn->conn);
199 }
int pqConnectDBStart(PGconn *conn)
Definition: fe-connect.c:2393

References cancelConn, CONNECTION_ALLOCATED, CONNECTION_BAD, libpq_append_conn_error(), and pqConnectDBStart().

Referenced by libpqsrv_cancel(), PQcancelBlocking(), and test_cancel().

◆ PQcancelStatus()

ConnStatusType PQcancelStatus ( const PGcancelConn cancelConn)

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

284 {
285  return PQstatus(&cancelConn->conn);
286 }
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7119

References cancelConn, and PQstatus().

Referenced by test_cancel().

◆ PQchangePassword()

PGresult* PQchangePassword ( PGconn conn,
const char *  user,
const char *  passwd 
)

Definition at line 1442 of file fe-auth.c.

1443 {
1444  char *encrypted_password = PQencryptPasswordConn(conn, passwd,
1445  user, NULL);
1446 
1447  if (!encrypted_password)
1448  {
1449  /* PQencryptPasswordConn() already registered the error */
1450  return NULL;
1451  }
1452  else
1453  {
1454  char *fmtpw = PQescapeLiteral(conn, encrypted_password,
1455  strlen(encrypted_password));
1456 
1457  /* no longer needed, so clean up now */
1458  PQfreemem(encrypted_password);
1459 
1460  if (!fmtpw)
1461  {
1462  /* PQescapeLiteral() already registered the error */
1463  return NULL;
1464  }
1465  else
1466  {
1467  char *fmtuser = PQescapeIdentifier(conn, user, strlen(user));
1468 
1469  if (!fmtuser)
1470  {
1471  /* PQescapeIdentifier() already registered the error */
1472  PQfreemem(fmtpw);
1473  return NULL;
1474  }
1475  else
1476  {
1478  PGresult *res;
1479 
1480  initPQExpBuffer(&buf);
1481  printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD %s",
1482  fmtuser, fmtpw);
1483 
1484  res = PQexec(conn, buf.data);
1485 
1486  /* clean up */
1487  termPQExpBuffer(&buf);
1488  PQfreemem(fmtuser);
1489  PQfreemem(fmtpw);
1490 
1491  return res;
1492  }
1493  }
1494  }
1495 }
char * PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm)
Definition: fe-auth.c:1317
void PQfreemem(void *ptr)
Definition: fe-exec.c:4032
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4310
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4304
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
static char * user
Definition: pg_regress.c:120
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129

References buf, conn, initPQExpBuffer(), PQencryptPasswordConn(), PQescapeIdentifier(), PQescapeLiteral(), PQexec(), PQfreemem(), printfPQExpBuffer(), res, termPQExpBuffer(), and user.

Referenced by exec_command_password().

◆ PQclear()

void PQclear ( PGresult res)

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

722 {
723  PGresult_data *block;
724  int i;
725 
726  /* As a convenience, do nothing for a NULL pointer */
727  if (!res)
728  return;
729  /* Also, do nothing if the argument is OOM_result */
730  if ((const PGresult *) res == &OOM_result)
731  return;
732 
733  /* Close down any events we may have */
734  for (i = 0; i < res->nEvents; i++)
735  {
736  /* only send DESTROY to successfully-initialized event procs */
738  {
740 
741  evt.result = res;
742  (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
743  res->events[i].passThrough);
744  }
745  free(res->events[i].name);
746  }
747 
748  free(res->events);
749 
750  /* Free all the subsidiary blocks */
751  while ((block = res->curBlock) != NULL)
752  {
753  res->curBlock = block->next;
754  free(block);
755  }
756 
757  /* Free the top-level tuple pointer array */
758  free(res->tuples);
759 
760  /* zero out the pointer fields to catch programming errors */
761  res->attDescs = NULL;
762  res->tuples = NULL;
763  res->paramDescs = NULL;
764  res->errFields = NULL;
765  res->events = NULL;
766  res->nEvents = 0;
767  /* res->curBlock was zeroed out earlier */
768 
769  /* Free the PGresult structure itself */
770  free(res);
771 }
static const PGresult OOM_result
Definition: fe-exec.c:49
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:73
@ PGEVT_RESULTDESTROY
Definition: libpq-events.h:34
void * passThrough
Definition: libpq-int.h:165
char * name
Definition: libpq-int.h:164
PGEventProc proc
Definition: libpq-int.h:163
bool resultInitialized
Definition: libpq-int.h:167
int nEvents
Definition: libpq-int.h:191
PGresAttValue ** tuples
Definition: libpq-int.h:175
PGresAttDesc * attDescs
Definition: libpq-int.h:174
PGMessageField * errFields
Definition: libpq-int.h:200
PGresParamDesc * paramDescs
Definition: libpq-int.h:179
PGEvent * events
Definition: libpq-int.h:190
PGresult_data * curBlock
Definition: libpq-int.h:211
PGresult_data * next
Definition: libpq-int.h:108

References pg_result::attDescs, pg_result::curBlock, pg_result::errFields, pg_result::events, free, i, PGEvent::name, pg_result::nEvents, pgresult_data::next, OOM_result, pg_result::paramDescs, PGEvent::passThrough, PGEVT_RESULTDESTROY, PGEvent::proc, res, PGEventResultDestroy::result, PGEvent::resultInitialized, and pg_result::tuples.

Referenced by pqClearAsyncResult(), PQcopyResult(), PQexecFinish(), PQexecStart(), pqInternalNotice(), and PQmakeEmptyPGresult().

◆ PQclientEncoding()

int PQclientEncoding ( const PGconn conn)

◆ PQclosePortal()

PGresult* PQclosePortal ( PGconn conn,
const char *  portal 
)

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

2540 {
2541  if (!PQexecStart(conn))
2542  return NULL;
2543  if (!PQsendTypedCommand(conn, PqMsg_Close, 'P', portal))
2544  return NULL;
2545  return PQexecFinish(conn);
2546 }
static PGresult * PQexecFinish(PGconn *conn)
Definition: fe-exec.c:2410
static int PQsendTypedCommand(PGconn *conn, char command, char type, const char *target)
Definition: fe-exec.c:2589
static bool PQexecStart(PGconn *conn)
Definition: fe-exec.c:2344
#define PqMsg_Close
Definition: protocol.h:20

References conn, PQexecFinish(), PQexecStart(), PqMsg_Close, and PQsendTypedCommand().

Referenced by test_prepared().

◆ PQclosePrepared()

PGresult* PQclosePrepared ( PGconn conn,
const char *  stmt 
)

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

2522 {
2523  if (!PQexecStart(conn))
2524  return NULL;
2525  if (!PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt))
2526  return NULL;
2527  return PQexecFinish(conn);
2528 }
#define stmt
Definition: indent_codes.h:59

References conn, PQexecFinish(), PQexecStart(), PqMsg_Close, PQsendTypedCommand(), and stmt.

Referenced by test_prepared().

◆ PQcmdStatus()

char* PQcmdStatus ( PGresult res)

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

3753 {
3754  if (!res)
3755  return NULL;
3756  return res->cmdStatus;
3757 }
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:181

References pg_result::cmdStatus, and res.

Referenced by dblink_exec(), ecpg_process_output(), ExecQueryAndProcessResults(), materializeResult(), PrintQueryStatus(), and test_pipelined_insert().

◆ PQcmdTuples()

char* PQcmdTuples ( PGresult res)

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

3823 {
3824  char *p,
3825  *c;
3826 
3827  if (!res)
3828  return "";
3829 
3830  if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
3831  {
3832  p = res->cmdStatus + 7;
3833  /* INSERT: skip oid and space */
3834  while (*p && *p != ' ')
3835  p++;
3836  if (*p == 0)
3837  goto interpret_error; /* no space? */
3838  p++;
3839  }
3840  else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
3841  strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
3842  strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
3843  p = res->cmdStatus + 7;
3844  else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0 ||
3845  strncmp(res->cmdStatus, "MERGE ", 6) == 0)
3846  p = res->cmdStatus + 6;
3847  else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 ||
3848  strncmp(res->cmdStatus, "COPY ", 5) == 0)
3849  p = res->cmdStatus + 5;
3850  else
3851  return "";
3852 
3853  /* check that we have an integer (at least one digit, nothing else) */
3854  for (c = p; *c; c++)
3855  {
3856  if (!isdigit((unsigned char) *c))
3857  goto interpret_error;
3858  }
3859  if (c == p)
3860  goto interpret_error;
3861 
3862  return p;
3863 
3864 interpret_error:
3866  "could not interpret result from server: %s",
3867  res->cmdStatus);
3868  return "";
3869 }
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:938
char * c
PGNoticeHooks noticeHooks
Definition: libpq-int.h:189

References pg_result::cmdStatus, pg_result::noticeHooks, pqInternalNotice(), and res.

Referenced by ecpg_process_output(), execute_dml_stmt(), execute_foreign_modify(), and SetResultVariables().

◆ PQconndefaults()

PQconninfoOption* PQconndefaults ( void  )

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

1883 {
1884  PQExpBufferData errorBuf;
1885  PQconninfoOption *connOptions;
1886 
1887  /* We don't actually report any errors here, but callees want a buffer */
1888  initPQExpBuffer(&errorBuf);
1889  if (PQExpBufferDataBroken(errorBuf))
1890  return NULL; /* out of memory already :-( */
1891 
1892  connOptions = conninfo_init(&errorBuf);
1893  if (connOptions != NULL)
1894  {
1895  /* pass NULL errorBuf to ignore errors */
1896  if (!conninfo_add_defaults(connOptions, NULL))
1897  {
1898  PQconninfoFree(connOptions);
1899  connOptions = NULL;
1900  }
1901  }
1902 
1903  termPQExpBuffer(&errorBuf);
1904  return connOptions;
1905 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:5775
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:6202
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:7005
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67

References conninfo_add_defaults(), conninfo_init(), initPQExpBuffer(), PQconninfoFree(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by check_pghost_envvar(), dblink_fdw_validator(), do_connect(), get_connect_string(), GetDbnameFromConnectionOptions(), InitPgFdwOptions(), and main().

◆ PQconnectdb()

PGconn* PQconnectdb ( const char *  conninfo)

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

746 {
747  PGconn *conn = PQconnectStart(conninfo);
748 
749  if (conn && conn->status != CONNECTION_BAD)
750  (void) pqConnectDBComplete(conn);
751 
752  return conn;
753 }
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:873

References conn, CONNECTION_BAD, pqConnectDBComplete(), PQconnectStart(), and pg_conn::status.

Referenced by connect_database(), get_db_conn(), and main().

◆ PQconnectdbParams()

PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

693 {
694  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
695 
696  if (conn && conn->status != CONNECTION_BAD)
697  (void) pqConnectDBComplete(conn);
698 
699  return conn;
700 }
static Datum values[MAXATTR]
Definition: bootstrap.c:150
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:792

References conn, CONNECTION_BAD, pqConnectDBComplete(), PQconnectStartParams(), pg_conn::status, and values.

Referenced by ConnectDatabase(), connectDatabase(), copy_connection(), doConnect(), ECPGconnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

◆ PQconnectionNeedsPassword()

int PQconnectionNeedsPassword ( const PGconn conn)

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

7234 {
7235  char *password;
7236 
7237  if (!conn)
7238  return false;
7239  password = PQpass(conn);
7240  if (conn->password_needed &&
7241  (password == NULL || password[0] == '\0'))
7242  return true;
7243  else
7244  return false;
7245 }
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:7034
static char * password
Definition: streamutil.c:54
bool password_needed
Definition: libpq-int.h:492

References conn, password, pg_conn::password_needed, and PQpass().

Referenced by ConnectDatabase(), connectDatabase(), do_connect(), doConnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

◆ PQconnectionUsedGSSAPI()

int PQconnectionUsedGSSAPI ( const PGconn conn)

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

7260 {
7261  if (!conn)
7262  return false;
7263  if (conn->gssapi_used)
7264  return true;
7265  else
7266  return false;
7267 }
bool gssapi_used
Definition: libpq-int.h:493

References conn, and pg_conn::gssapi_used.

Referenced by dblink_security_check(), and pgfdw_security_check().

◆ PQconnectionUsedPassword()

int PQconnectionUsedPassword ( const PGconn conn)

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

7249 {
7250  if (!conn)
7251  return false;
7252  if (conn->password_needed)
7253  return true;
7254  else
7255  return false;
7256 }

References conn, and pg_conn::password_needed.

Referenced by ConnectDatabase(), dblink_security_check(), libpqrcv_connect(), and pgfdw_security_check().

◆ PQconnectPoll()

PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

2598 {
2599  bool reset_connection_state_machine = false;
2600  bool need_new_connection = false;
2601  PGresult *res;
2602  char sebuf[PG_STRERROR_R_BUFLEN];
2603  int optval;
2604 
2605  if (conn == NULL)
2606  return PGRES_POLLING_FAILED;
2607 
2608  /* Get the new data */
2609  switch (conn->status)
2610  {
2611  /*
2612  * We really shouldn't have been polled in these two cases, but we
2613  * can handle it.
2614  */
2615  case CONNECTION_BAD:
2616  return PGRES_POLLING_FAILED;
2617  case CONNECTION_OK:
2618  return PGRES_POLLING_OK;
2619 
2620  /* These are reading states */
2622  case CONNECTION_AUTH_OK:
2624  case CONNECTION_CONSUME:
2626  {
2627  /* Load waiting data */
2628  int n = pqReadData(conn);
2629 
2630  if (n < 0)
2631  goto error_return;
2632  if (n == 0)
2633  return PGRES_POLLING_READING;
2634 
2635  break;
2636  }
2637 
2638  /* These are writing states, so we just proceed. */
2639  case CONNECTION_STARTED:
2640  case CONNECTION_MADE:
2641  break;
2642 
2643  /* Special cases: proceed without waiting. */
2645  case CONNECTION_NEEDED:
2648  break;
2649 
2650  default:
2651  libpq_append_conn_error(conn, "invalid connection state, probably indicative of memory corruption");
2652  goto error_return;
2653  }
2654 
2655 
2656 keep_going: /* We will come back to here until there is
2657  * nothing left to do. */
2658 
2659  /* Time to advance to next address, or next host if no more addresses? */
2660  if (conn->try_next_addr)
2661  {
2662  if (conn->whichaddr < conn->naddr)
2663  {
2664  conn->whichaddr++;
2665  reset_connection_state_machine = true;
2666  }
2667  else
2668  conn->try_next_host = true;
2669  conn->try_next_addr = false;
2670  }
2671 
2672  /* Time to advance to next connhost[] entry? */
2673  if (conn->try_next_host)
2674  {
2675  pg_conn_host *ch;
2676  struct addrinfo hint;
2677  struct addrinfo *addrlist;
2678  int thisport;
2679  int ret;
2680  char portstr[MAXPGPATH];
2681 
2682  if (conn->whichhost + 1 < conn->nconnhost)
2683  conn->whichhost++;
2684  else
2685  {
2686  /*
2687  * Oops, no more hosts.
2688  *
2689  * If we are trying to connect in "prefer-standby" mode, then drop
2690  * the standby requirement and start over. Don't do this for
2691  * cancel requests though, since we are certain the list of
2692  * servers won't change as the target_server_type option is not
2693  * applicable to those connections.
2694  *
2695  * Otherwise, an appropriate error message is already set up, so
2696  * we just need to set the right status.
2697  */
2699  conn->nconnhost > 0 &&
2700  !conn->cancelRequest)
2701  {
2703  conn->whichhost = 0;
2704  }
2705  else
2706  goto error_return;
2707  }
2708 
2709  /* Drop any address info for previous host */
2711 
2712  /*
2713  * Look up info for the new host. On failure, log the problem in
2714  * conn->errorMessage, then loop around to try the next host. (Note
2715  * we don't clear try_next_host until we've succeeded.)
2716  */
2717  ch = &conn->connhost[conn->whichhost];
2718 
2719  /* Initialize hint structure */
2720  MemSet(&hint, 0, sizeof(hint));
2721  hint.ai_socktype = SOCK_STREAM;
2722  hint.ai_family = AF_UNSPEC;
2723 
2724  /* Figure out the port number we're going to use. */
2725  if (ch->port == NULL || ch->port[0] == '\0')
2726  thisport = DEF_PGPORT;
2727  else
2728  {
2729  if (!pqParseIntParam(ch->port, &thisport, conn, "port"))
2730  goto error_return;
2731 
2732  if (thisport < 1 || thisport > 65535)
2733  {
2734  libpq_append_conn_error(conn, "invalid port number: \"%s\"", ch->port);
2735  goto keep_going;
2736  }
2737  }
2738  snprintf(portstr, sizeof(portstr), "%d", thisport);
2739 
2740  /* Use pg_getaddrinfo_all() to resolve the address */
2741  switch (ch->type)
2742  {
2743  case CHT_HOST_NAME:
2744  ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
2745  &addrlist);
2746  if (ret || !addrlist)
2747  {
2748  libpq_append_conn_error(conn, "could not translate host name \"%s\" to address: %s",
2749  ch->host, gai_strerror(ret));
2750  goto keep_going;
2751  }
2752  break;
2753 
2754  case CHT_HOST_ADDRESS:
2755  hint.ai_flags = AI_NUMERICHOST;
2756  ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
2757  &addrlist);
2758  if (ret || !addrlist)
2759  {
2760  libpq_append_conn_error(conn, "could not parse network address \"%s\": %s",
2761  ch->hostaddr, gai_strerror(ret));
2762  goto keep_going;
2763  }
2764  break;
2765 
2766  case CHT_UNIX_SOCKET:
2767  hint.ai_family = AF_UNIX;
2768  UNIXSOCK_PATH(portstr, thisport, ch->host);
2769  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
2770  {
2771  libpq_append_conn_error(conn, "Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
2772  portstr,
2773  (int) (UNIXSOCK_PATH_BUFLEN - 1));
2774  goto keep_going;
2775  }
2776 
2777  /*
2778  * NULL hostname tells pg_getaddrinfo_all to parse the service
2779  * name as a Unix-domain socket path.
2780  */
2781  ret = pg_getaddrinfo_all(NULL, portstr, &hint,
2782  &addrlist);
2783  if (ret || !addrlist)
2784  {
2785  libpq_append_conn_error(conn, "could not translate Unix-domain socket path \"%s\" to address: %s",
2786  portstr, gai_strerror(ret));
2787  goto keep_going;
2788  }
2789  break;
2790  }
2791 
2792  /*
2793  * Store a copy of the addrlist in private memory so we can perform
2794  * randomization for load balancing.
2795  */
2796  ret = store_conn_addrinfo(conn, addrlist);
2797  pg_freeaddrinfo_all(hint.ai_family, addrlist);
2798  if (ret)
2799  goto error_return; /* message already logged */
2800 
2801  /*
2802  * If random load balancing is enabled we shuffle the addresses.
2803  */
2805  {
2806  /*
2807  * This is the "inside-out" variant of the Fisher-Yates shuffle
2808  * algorithm. Notionally, we append each new value to the array
2809  * and then swap it with a randomly-chosen array element (possibly
2810  * including itself, else we fail to generate permutations with
2811  * the last integer last). The swap step can be optimized by
2812  * combining it with the insertion.
2813  *
2814  * We don't need to initialize conn->prng_state here, because that
2815  * already happened in pqConnectOptions2.
2816  */
2817  for (int i = 1; i < conn->naddr; i++)
2818  {
2819  int j = pg_prng_uint64_range(&conn->prng_state, 0, i);
2820  AddrInfo temp = conn->addr[j];
2821 
2822  conn->addr[j] = conn->addr[i];
2823  conn->addr[i] = temp;
2824  }
2825  }
2826 
2827  reset_connection_state_machine = true;
2828  conn->try_next_host = false;
2829  }
2830 
2831  /* Reset connection state machine? */
2832  if (reset_connection_state_machine)
2833  {
2834  /*
2835  * (Re) initialize our connection control variables for a set of
2836  * connection attempts to a single server address. These variables
2837  * must persist across individual connection attempts, but we must
2838  * reset them when we start to consider a new server.
2839  */
2840  conn->pversion = PG_PROTOCOL(3, 0);
2841  conn->send_appname = true;
2842  conn->failed_enc_methods = 0;
2843  conn->current_enc_method = 0;
2845  reset_connection_state_machine = false;
2846  need_new_connection = true;
2847  }
2848 
2849  /* Force a new connection (perhaps to the same server as before)? */
2850  if (need_new_connection)
2851  {
2852  /* Drop any existing connection */
2853  pqDropConnection(conn, true);
2854 
2855  /* Reset all state obtained from old server */
2857 
2858  /* Drop any PGresult we might have, too */
2863 
2864  /* Reset conn->status to put the state machine in the right state */
2866 
2867  need_new_connection = false;
2868  }
2869 
2870  /*
2871  * Decide what to do next, if server rejects SSL or GSS negotiation, but
2872  * the connection is still valid. If there are no options left, error out
2873  * with 'msg'.
2874  */
2875 #define ENCRYPTION_NEGOTIATION_FAILED(msg) \
2876  do { \
2877  switch (encryption_negotiation_failed(conn)) \
2878  { \
2879  case 0: \
2880  libpq_append_conn_error(conn, (msg)); \
2881  goto error_return; \
2882  case 1: \
2883  conn->status = CONNECTION_MADE; \
2884  return PGRES_POLLING_WRITING; \
2885  case 2: \
2886  need_new_connection = true; \
2887  goto keep_going; \
2888  } \
2889  } while(0);
2890 
2891  /*
2892  * Decide what to do next, if connection fails. If there are no options
2893  * left, return with an error. The error message has already been written
2894  * to the connection's error buffer.
2895  */
2896 #define CONNECTION_FAILED() \
2897  do { \
2898  if (connection_failed(conn)) \
2899  { \
2900  need_new_connection = true; \
2901  goto keep_going; \
2902  } \
2903  else \
2904  goto error_return; \
2905  } while(0);
2906 
2907  /* Now try to advance the state machine for this connection */
2908  switch (conn->status)
2909  {
2910  case CONNECTION_NEEDED:
2911  {
2912  /*
2913  * Try to initiate a connection to one of the addresses
2914  * returned by pg_getaddrinfo_all(). conn->whichaddr is the
2915  * next one to try.
2916  *
2917  * The extra level of braces here is historical. It's not
2918  * worth reindenting this whole switch case to remove 'em.
2919  */
2920  {
2921  char host_addr[NI_MAXHOST];
2922  int sock_type;
2923  AddrInfo *addr_cur;
2924 
2925  /*
2926  * Advance to next possible host, if we've tried all of
2927  * the addresses for the current host.
2928  */
2929  if (conn->whichaddr == conn->naddr)
2930  {
2931  conn->try_next_host = true;
2932  goto keep_going;
2933  }
2934  addr_cur = &conn->addr[conn->whichaddr];
2935 
2936  /* Remember current address for possible use later */
2937  memcpy(&conn->raddr, &addr_cur->addr, sizeof(SockAddr));
2938 
2939 #ifdef ENABLE_GSS
2940 
2941  /*
2942  * Before establishing the connection, check if it's
2943  * doomed to fail because gssencmode='require' but GSSAPI
2944  * is not available.
2945  */
2946  if (conn->gssencmode[0] == 'r')
2947  {
2948  if (conn->raddr.addr.ss_family == AF_UNIX)
2949  {
2951  "GSSAPI encryption required but it is not supported over a local socket");
2952  goto error_return;
2953  }
2954  if (conn->gcred == GSS_C_NO_CREDENTIAL)
2955  {
2956  if (!pg_GSS_have_cred_cache(&conn->gcred))
2957  {
2959  "GSSAPI encryption required but no credential cache");
2960  goto error_return;
2961  }
2962  }
2963  }
2964 #endif
2965 
2966  /*
2967  * Choose the encryption method to try first. Do this
2968  * before establishing the connection, so that if none of
2969  * the modes allowed by the connections options are
2970  * available, we can error out before establishing the
2971  * connection.
2972  */
2974  goto error_return;
2975 
2976  /*
2977  * Set connip, too. Note we purposely ignore strdup
2978  * failure; not a big problem if it fails.
2979  */
2980  if (conn->connip != NULL)
2981  {
2982  free(conn->connip);
2983  conn->connip = NULL;
2984  }
2985  getHostaddr(conn, host_addr, NI_MAXHOST);
2986  if (host_addr[0])
2987  conn->connip = strdup(host_addr);
2988 
2989  /* Try to create the socket */
2990  sock_type = SOCK_STREAM;
2991 #ifdef SOCK_CLOEXEC
2992 
2993  /*
2994  * Atomically mark close-on-exec, if possible on this
2995  * platform, so that there isn't a window where a
2996  * subprogram executed by another thread inherits the
2997  * socket. See fallback code below.
2998  */
2999  sock_type |= SOCK_CLOEXEC;
3000 #endif
3001 #ifdef SOCK_NONBLOCK
3002 
3003  /*
3004  * We might as well skip a system call for nonblocking
3005  * mode too, if we can.
3006  */
3007  sock_type |= SOCK_NONBLOCK;
3008 #endif
3009  conn->sock = socket(addr_cur->family, sock_type, 0);
3010  if (conn->sock == PGINVALID_SOCKET)
3011  {
3012  int errorno = SOCK_ERRNO;
3013 
3014  /*
3015  * Silently ignore socket() failure if we have more
3016  * addresses to try; this reduces useless chatter in
3017  * cases where the address list includes both IPv4 and
3018  * IPv6 but kernel only accepts one family.
3019  */
3020  if (conn->whichaddr < conn->naddr ||
3021  conn->whichhost + 1 < conn->nconnhost)
3022  {
3023  conn->try_next_addr = true;
3024  goto keep_going;
3025  }
3026  emitHostIdentityInfo(conn, host_addr);
3027  libpq_append_conn_error(conn, "could not create socket: %s",
3028  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
3029  goto error_return;
3030  }
3031 
3032  /*
3033  * Once we've identified a target address, all errors
3034  * except the preceding socket()-failure case should be
3035  * prefixed with host-identity information. (If the
3036  * connection succeeds, the contents of conn->errorMessage
3037  * won't matter, so this is harmless.)
3038  */
3039  emitHostIdentityInfo(conn, host_addr);
3040 
3041  /*
3042  * Select socket options: no delay of outgoing data for
3043  * TCP sockets, nonblock mode, close-on-exec. Try the
3044  * next address if any of this fails.
3045  */
3046  if (addr_cur->family != AF_UNIX)
3047  {
3048  if (!connectNoDelay(conn))
3049  {
3050  /* error message already created */
3051  conn->try_next_addr = true;
3052  goto keep_going;
3053  }
3054  }
3055 #ifndef SOCK_NONBLOCK
3056  if (!pg_set_noblock(conn->sock))
3057  {
3058  libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s",
3059  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3060  conn->try_next_addr = true;
3061  goto keep_going;
3062  }
3063 #endif
3064 
3065 #ifndef SOCK_CLOEXEC
3066 #ifdef F_SETFD
3067  if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
3068  {
3069  libpq_append_conn_error(conn, "could not set socket to close-on-exec mode: %s",
3070  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3071  conn->try_next_addr = true;
3072  goto keep_going;
3073  }
3074 #endif /* F_SETFD */
3075 #endif
3076 
3077  if (addr_cur->family != AF_UNIX)
3078  {
3079 #ifndef WIN32
3080  int on = 1;
3081 #endif
3082  int usekeepalives = useKeepalives(conn);
3083  int err = 0;
3084 
3085  if (usekeepalives < 0)
3086  {
3087  libpq_append_conn_error(conn, "keepalives parameter must be an integer");
3088  err = 1;
3089  }
3090  else if (usekeepalives == 0)
3091  {
3092  /* Do nothing */
3093  }
3094 #ifndef WIN32
3095  else if (setsockopt(conn->sock,
3096  SOL_SOCKET, SO_KEEPALIVE,
3097  (char *) &on, sizeof(on)) < 0)
3098  {
3099  libpq_append_conn_error(conn, "%s(%s) failed: %s",
3100  "setsockopt",
3101  "SO_KEEPALIVE",
3102  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3103  err = 1;
3104  }
3105  else if (!setKeepalivesIdle(conn)
3107  || !setKeepalivesCount(conn))
3108  err = 1;
3109 #else /* WIN32 */
3110 #ifdef SIO_KEEPALIVE_VALS
3111  else if (!prepKeepalivesWin32(conn))
3112  err = 1;
3113 #endif /* SIO_KEEPALIVE_VALS */
3114 #endif /* WIN32 */
3115  else if (!setTCPUserTimeout(conn))
3116  err = 1;
3117 
3118  if (err)
3119  {
3120  conn->try_next_addr = true;
3121  goto keep_going;
3122  }
3123  }
3124 
3125  /*----------
3126  * We have three methods of blocking SIGPIPE during
3127  * send() calls to this socket:
3128  *
3129  * - setsockopt(sock, SO_NOSIGPIPE)
3130  * - send(sock, ..., MSG_NOSIGNAL)
3131  * - setting the signal mask to SIG_IGN during send()
3132  *
3133  * The third method requires three syscalls per send,
3134  * so we prefer either of the first two, but they are
3135  * less portable. The state is tracked in the following
3136  * members of PGconn:
3137  *
3138  * conn->sigpipe_so - we have set up SO_NOSIGPIPE
3139  * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
3140  *
3141  * If we can use SO_NOSIGPIPE, then set sigpipe_so here
3142  * and we're done. Otherwise, set sigpipe_flag so that
3143  * we will try MSG_NOSIGNAL on sends. If we get an error
3144  * with MSG_NOSIGNAL, we'll clear that flag and revert to
3145  * signal masking.
3146  *----------
3147  */
3148  conn->sigpipe_so = false;
3149 #ifdef MSG_NOSIGNAL
3150  conn->sigpipe_flag = true;
3151 #else
3152  conn->sigpipe_flag = false;
3153 #endif /* MSG_NOSIGNAL */
3154 
3155 #ifdef SO_NOSIGPIPE
3156  optval = 1;
3157  if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
3158  (char *) &optval, sizeof(optval)) == 0)
3159  {
3160  conn->sigpipe_so = true;
3161  conn->sigpipe_flag = false;
3162  }
3163 #endif /* SO_NOSIGPIPE */
3164 
3165  /*
3166  * Start/make connection. This should not block, since we
3167  * are in nonblock mode. If it does, well, too bad.
3168  */
3169  if (connect(conn->sock, (struct sockaddr *) &addr_cur->addr.addr,
3170  addr_cur->addr.salen) < 0)
3171  {
3172  if (SOCK_ERRNO == EINPROGRESS ||
3173 #ifdef WIN32
3174  SOCK_ERRNO == EWOULDBLOCK ||
3175 #endif
3176  SOCK_ERRNO == EINTR)
3177  {
3178  /*
3179  * This is fine - we're in non-blocking mode, and
3180  * the connection is in progress. Tell caller to
3181  * wait for write-ready on socket.
3182  */
3184  return PGRES_POLLING_WRITING;
3185  }
3186  /* otherwise, trouble */
3187  }
3188  else
3189  {
3190  /*
3191  * Hm, we're connected already --- seems the "nonblock
3192  * connection" wasn't. Advance the state machine and
3193  * go do the next stuff.
3194  */
3196  goto keep_going;
3197  }
3198 
3199  /*
3200  * This connection failed. Add the error report to
3201  * conn->errorMessage, then try the next address if any.
3202  */
3204  conn->try_next_addr = true;
3205  goto keep_going;
3206  }
3207  }
3208 
3209  case CONNECTION_STARTED:
3210  {
3211  socklen_t optlen = sizeof(optval);
3212 
3213  /*
3214  * Write ready, since we've made it here, so the connection
3215  * has been made ... or has failed.
3216  */
3217 
3218  /*
3219  * Now check (using getsockopt) that there is not an error
3220  * state waiting for us on the socket.
3221  */
3222 
3223  if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
3224  (char *) &optval, &optlen) == -1)
3225  {
3226  libpq_append_conn_error(conn, "could not get socket error status: %s",
3227  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3228  goto error_return;
3229  }
3230  else if (optval != 0)
3231  {
3232  /*
3233  * When using a nonblocking connect, we will typically see
3234  * connect failures at this point, so provide a friendly
3235  * error message.
3236  */
3237  connectFailureMessage(conn, optval);
3238 
3239  /*
3240  * Try the next address if any, just as in the case where
3241  * connect() returned failure immediately.
3242  */
3243  conn->try_next_addr = true;
3244  goto keep_going;
3245  }
3246 
3247  /* Fill in the client address */
3248  conn->laddr.salen = sizeof(conn->laddr.addr);
3249  if (getsockname(conn->sock,
3250  (struct sockaddr *) &conn->laddr.addr,
3251  &conn->laddr.salen) < 0)
3252  {
3253  libpq_append_conn_error(conn, "could not get client address from socket: %s",
3254  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3255  goto error_return;
3256  }
3257 
3258  /*
3259  * Implement requirepeer check, if requested and it's a
3260  * Unix-domain socket.
3261  */
3262  if (conn->requirepeer && conn->requirepeer[0] &&
3263  conn->raddr.addr.ss_family == AF_UNIX)
3264  {
3265 #ifndef WIN32
3266  char *remote_username;
3267 #endif
3268  uid_t uid;
3269  gid_t gid;
3270 
3271  errno = 0;
3272  if (getpeereid(conn->sock, &uid, &gid) != 0)
3273  {
3274  /*
3275  * Provide special error message if getpeereid is a
3276  * stub
3277  */
3278  if (errno == ENOSYS)
3279  libpq_append_conn_error(conn, "requirepeer parameter is not supported on this platform");
3280  else
3281  libpq_append_conn_error(conn, "could not get peer credentials: %s",
3282  strerror_r(errno, sebuf, sizeof(sebuf)));
3283  goto error_return;
3284  }
3285 
3286 #ifndef WIN32
3287  remote_username = pg_fe_getusername(uid,
3288  &conn->errorMessage);
3289  if (remote_username == NULL)
3290  goto error_return; /* message already logged */
3291 
3292  if (strcmp(remote_username, conn->requirepeer) != 0)
3293  {
3294  libpq_append_conn_error(conn, "requirepeer specifies \"%s\", but actual peer user name is \"%s\"",
3295  conn->requirepeer, remote_username);
3296  free(remote_username);
3297  goto error_return;
3298  }
3299  free(remote_username);
3300 #else /* WIN32 */
3301  /* should have failed with ENOSYS above */
3302  Assert(false);
3303 #endif /* WIN32 */
3304  }
3305 
3306  /*
3307  * Make sure we can write before advancing to next step.
3308  */
3310  return PGRES_POLLING_WRITING;
3311  }
3312 
3313  case CONNECTION_MADE:
3314  {
3315  char *startpacket;
3316  int packetlen;
3317 
3318 #ifdef ENABLE_GSS
3319 
3320  /*
3321  * If GSSAPI encryption is enabled, send a packet to the
3322  * server asking for GSSAPI Encryption and proceed with GSSAPI
3323  * handshake. We will come back here after GSSAPI encryption
3324  * has been established, with conn->gctx set.
3325  */
3326  if (conn->current_enc_method == ENC_GSSAPI && !conn->gctx)
3327  {
3329 
3330  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
3331  {
3332  libpq_append_conn_error(conn, "could not send GSSAPI negotiation packet: %s",
3333  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3334  goto error_return;
3335  }
3336 
3337  /* Ok, wait for response */
3339  return PGRES_POLLING_READING;
3340  }
3341 #endif
3342 
3343 #ifdef USE_SSL
3344 
3345  /*
3346  * If SSL is enabled, start the SSL negotiation. We will come
3347  * back here after SSL encryption has been established, with
3348  * ssl_in_use set.
3349  */
3351  {
3352  /*
3353  * If traditional postgres SSL negotiation is used, send
3354  * the SSL request. In direct negotiation, jump straight
3355  * into the SSL handshake.
3356  */
3357  if (conn->sslnegotiation[0] == 'p')
3358  {
3359  ProtocolVersion pv;
3360 
3361  /*
3362  * Send the SSL request packet.
3363  *
3364  * Theoretically, this could block, but it really
3365  * shouldn't since we only got here if the socket is
3366  * write-ready.
3367  */
3369  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
3370  {
3371  libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
3372  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3373  goto error_return;
3374  }
3375  /* Ok, wait for response */
3377  return PGRES_POLLING_READING;
3378  }
3379  else
3380  {
3381  Assert(conn->sslnegotiation[0] == 'd');
3383  return PGRES_POLLING_WRITING;
3384  }
3385  }
3386 #endif /* USE_SSL */
3387 
3388  /*
3389  * For cancel requests this is as far as we need to go in the
3390  * connection establishment. Now we can actually send our
3391  * cancellation request.
3392  */
3393  if (conn->cancelRequest)
3394  {
3395  CancelRequestPacket cancelpacket;
3396 
3397  packetlen = sizeof(cancelpacket);
3399  cancelpacket.backendPID = pg_hton32(conn->be_pid);
3400  cancelpacket.cancelAuthCode = pg_hton32(conn->be_key);
3401  if (pqPacketSend(conn, 0, &cancelpacket, packetlen) != STATUS_OK)
3402  {
3403  libpq_append_conn_error(conn, "could not send cancel packet: %s",
3404  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3405  goto error_return;
3406  }
3408  return PGRES_POLLING_READING;
3409  }
3410 
3411  /*
3412  * We have now established encryption, or we are happy to
3413  * proceed without.
3414  */
3415 
3416  /* Build the startup packet. */
3417  startpacket = pqBuildStartupPacket3(conn, &packetlen,
3419  if (!startpacket)
3420  {
3421  libpq_append_conn_error(conn, "out of memory");
3422  goto error_return;
3423  }
3424 
3425  /*
3426  * Send the startup packet.
3427  *
3428  * Theoretically, this could block, but it really shouldn't
3429  * since we only got here if the socket is write-ready.
3430  */
3431  if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
3432  {
3433  libpq_append_conn_error(conn, "could not send startup packet: %s",
3434  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3435  free(startpacket);
3436  goto error_return;
3437  }
3438 
3439  free(startpacket);
3440 
3442  return PGRES_POLLING_READING;
3443  }
3444 
3445  /*
3446  * Handle SSL negotiation: wait for postmaster messages and
3447  * respond as necessary.
3448  */
3450  {
3451 #ifdef USE_SSL
3452  PostgresPollingStatusType pollres;
3453 
3454  /*
3455  * On first time through with traditional SSL negotiation, get
3456  * the postmaster's response to our SSLRequest packet. With
3457  * sslnegotiation='direct', go straight to initiating SSL.
3458  */
3459  if (!conn->ssl_in_use && conn->sslnegotiation[0] == 'p')
3460  {
3461  /*
3462  * We use pqReadData here since it has the logic to
3463  * distinguish no-data-yet from connection closure. Since
3464  * conn->ssl isn't set, a plain recv() will occur.
3465  */
3466  char SSLok;
3467  int rdresult;
3468 
3469  rdresult = pqReadData(conn);
3470  if (rdresult < 0)
3471  {
3472  /* errorMessage is already filled in */
3473  goto error_return;
3474  }
3475  if (rdresult == 0)
3476  {
3477  /* caller failed to wait for data */
3478  return PGRES_POLLING_READING;
3479  }
3480  if (pqGetc(&SSLok, conn) < 0)
3481  {
3482  /* should not happen really */
3483  return PGRES_POLLING_READING;
3484  }
3485  if (SSLok == 'S')
3486  {
3487  if (conn->Pfdebug)
3488  pqTraceOutputCharResponse(conn, "SSLResponse",
3489  SSLok);
3490  /* mark byte consumed */
3491  conn->inStart = conn->inCursor;
3492  }
3493  else if (SSLok == 'N')
3494  {
3495  if (conn->Pfdebug)
3496  pqTraceOutputCharResponse(conn, "SSLResponse",
3497  SSLok);
3498  /* mark byte consumed */
3499  conn->inStart = conn->inCursor;
3500 
3501  /*
3502  * The connection is still valid, so if it's OK to
3503  * continue without SSL, we can proceed using this
3504  * connection. Otherwise return with an error.
3505  */
3506  ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server does not support SSL, but SSL was required"));
3507  }
3508  else if (SSLok == 'E')
3509  {
3510  /*
3511  * Server failure of some sort, such as failure to
3512  * fork a backend process. We need to process and
3513  * report the error message, which might be formatted
3514  * according to either protocol 2 or protocol 3.
3515  * Rather than duplicate the code for that, we flip
3516  * into AWAITING_RESPONSE state and let the code there
3517  * deal with it. Note we have *not* consumed the "E"
3518  * byte here.
3519  */
3521 
3522  /*
3523  * Don't fall back to a plaintext connection after
3524  * reading the error.
3525  */
3527  goto keep_going;
3528  }
3529  else
3530  {
3531  libpq_append_conn_error(conn, "received invalid response to SSL negotiation: %c",
3532  SSLok);
3533  goto error_return;
3534  }
3535  }
3536 
3537  /*
3538  * Begin or continue the SSL negotiation process.
3539  */
3540  pollres = pqsecure_open_client(conn);
3541  if (pollres == PGRES_POLLING_OK)
3542  {
3543  /*
3544  * At this point we should have no data already buffered.
3545  * If we do, it was received before we performed the SSL
3546  * handshake, so it wasn't encrypted and indeed may have
3547  * been injected by a man-in-the-middle.
3548  */
3549  if (conn->inCursor != conn->inEnd)
3550  {
3551  libpq_append_conn_error(conn, "received unencrypted data after SSL response");
3552  goto error_return;
3553  }
3554 
3555  /* SSL handshake done, ready to send startup packet */
3557  return PGRES_POLLING_WRITING;
3558  }
3559  if (pollres == PGRES_POLLING_FAILED)
3560  {
3561  /*
3562  * SSL handshake failed. We will retry with a plaintext
3563  * connection, if permitted by sslmode.
3564  */
3566  }
3567  /* Else, return POLLING_READING or POLLING_WRITING status */
3568  return pollres;
3569 #else /* !USE_SSL */
3570  /* can't get here */
3571  goto error_return;
3572 #endif /* USE_SSL */
3573  }
3574 
3576  {
3577 #ifdef ENABLE_GSS
3578  PostgresPollingStatusType pollres;
3579 
3580  /*
3581  * If we haven't yet, get the postmaster's response to our
3582  * negotiation packet
3583  */
3584  if (!conn->gctx)
3585  {
3586  char gss_ok;
3587  int rdresult = pqReadData(conn);
3588 
3589  if (rdresult < 0)
3590  /* pqReadData fills in error message */
3591  goto error_return;
3592  else if (rdresult == 0)
3593  /* caller failed to wait for data */
3594  return PGRES_POLLING_READING;
3595  if (pqGetc(&gss_ok, conn) < 0)
3596  /* shouldn't happen... */
3597  return PGRES_POLLING_READING;
3598 
3599  if (gss_ok == 'E')
3600  {
3601  /*
3602  * Server failure of some sort, possibly protocol
3603  * version support failure. We need to process and
3604  * report the error message, which might be formatted
3605  * according to either protocol 2 or protocol 3.
3606  * Rather than duplicate the code for that, we flip
3607  * into AWAITING_RESPONSE state and let the code there
3608  * deal with it. Note we have *not* consumed the "E"
3609  * byte here.
3610  *
3611  * Note that unlike on an error response to
3612  * SSLRequest, we allow falling back to SSL or
3613  * plaintext connection here. GSS support was
3614  * introduced in PostgreSQL version 12, so an error
3615  * response might mean that we are connecting to a
3616  * pre-v12 server.
3617  */
3619  goto keep_going;
3620  }
3621 
3622  /* mark byte consumed */
3623  conn->inStart = conn->inCursor;
3624 
3625  if (gss_ok == 'N')
3626  {
3627  if (conn->Pfdebug)
3628  pqTraceOutputCharResponse(conn, "GSSENCResponse",
3629  gss_ok);
3630 
3631  /*
3632  * The connection is still valid, so if it's OK to
3633  * continue without GSS, we can proceed using this
3634  * connection. Otherwise return with an error.
3635  */
3636  ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server doesn't support GSSAPI encryption, but it was required"));
3637  }
3638  else if (gss_ok != 'G')
3639  {
3640  libpq_append_conn_error(conn, "received invalid response to GSSAPI negotiation: %c",
3641  gss_ok);
3642  goto error_return;
3643  }
3644 
3645  if (conn->Pfdebug)
3646  pqTraceOutputCharResponse(conn, "GSSENCResponse",
3647  gss_ok);
3648  }
3649 
3650  /* Begin or continue GSSAPI negotiation */
3651  pollres = pqsecure_open_gss(conn);
3652  if (pollres == PGRES_POLLING_OK)
3653  {
3654  /*
3655  * At this point we should have no data already buffered.
3656  * If we do, it was received before we performed the GSS
3657  * handshake, so it wasn't encrypted and indeed may have
3658  * been injected by a man-in-the-middle.
3659  */
3660  if (conn->inCursor != conn->inEnd)
3661  {
3662  libpq_append_conn_error(conn, "received unencrypted data after GSSAPI encryption response");
3663  goto error_return;
3664  }
3665 
3666  /* All set for startup packet */
3668  return PGRES_POLLING_WRITING;
3669  }
3670  else if (pollres == PGRES_POLLING_FAILED)
3671  {
3672  /*
3673  * GSS handshake failed. We will retry with an SSL or
3674  * plaintext connection, if permitted by the options.
3675  */
3677  }
3678  /* Else, return POLLING_READING or POLLING_WRITING status */
3679  return pollres;
3680 #else /* !ENABLE_GSS */
3681  /* unreachable */
3682  goto error_return;
3683 #endif /* ENABLE_GSS */
3684  }
3685 
3686  /*
3687  * Handle authentication exchange: wait for postmaster messages
3688  * and respond as necessary.
3689  */
3691  {
3692  char beresp;
3693  int msgLength;
3694  int avail;
3695  AuthRequest areq;
3696  int res;
3697 
3698  /*
3699  * Scan the message from current point (note that if we find
3700  * the message is incomplete, we will return without advancing
3701  * inStart, and resume here next time).
3702  */
3703  conn->inCursor = conn->inStart;
3704 
3705  /* Read type byte */
3706  if (pqGetc(&beresp, conn))
3707  {
3708  /* We'll come back when there is more data */
3709  return PGRES_POLLING_READING;
3710  }
3711 
3712  /*
3713  * Validate message type: we expect only an authentication
3714  * request, NegotiateProtocolVersion, or an error here.
3715  * Anything else probably means it's not Postgres on the other
3716  * end at all.
3717  */
3718  if (beresp != PqMsg_AuthenticationRequest &&
3719  beresp != PqMsg_ErrorResponse &&
3721  {
3722  libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
3723  beresp);
3724  goto error_return;
3725  }
3726 
3727  /* Read message length word */
3728  if (pqGetInt(&msgLength, 4, conn))
3729  {
3730  /* We'll come back when there is more data */
3731  return PGRES_POLLING_READING;
3732  }
3733 
3734  /*
3735  * Try to validate message length before using it.
3736  *
3737  * Authentication requests can't be very large, although GSS
3738  * auth requests may not be that small. Same for
3739  * NegotiateProtocolVersion.
3740  *
3741  * Errors can be a little larger, but not huge. If we see a
3742  * large apparent length in an error, it means we're really
3743  * talking to a pre-3.0-protocol server; cope. (Before
3744  * version 14, the server also used the old protocol for
3745  * errors that happened before processing the startup packet.)
3746  */
3747  if (beresp == PqMsg_AuthenticationRequest &&
3748  (msgLength < 8 || msgLength > 2000))
3749  {
3750  libpq_append_conn_error(conn, "received invalid authentication request");
3751  goto error_return;
3752  }
3753  if (beresp == PqMsg_NegotiateProtocolVersion &&
3754  (msgLength < 8 || msgLength > 2000))
3755  {
3756  libpq_append_conn_error(conn, "received invalid protocol negotiation message");
3757  goto error_return;
3758  }
3759 
3760 #define MAX_ERRLEN 30000
3761  if (beresp == PqMsg_ErrorResponse &&
3762  (msgLength < 8 || msgLength > MAX_ERRLEN))
3763  {
3764  /* Handle error from a pre-3.0 server */
3765  conn->inCursor = conn->inStart + 1; /* reread data */
3767  {
3768  /*
3769  * We may not have authenticated the server yet, so
3770  * don't let the buffer grow forever.
3771  */
3772  avail = conn->inEnd - conn->inCursor;
3773  if (avail > MAX_ERRLEN)
3774  {
3775  libpq_append_conn_error(conn, "received invalid error message");
3776  goto error_return;
3777  }
3778 
3779  /* We'll come back when there is more data */
3780  return PGRES_POLLING_READING;
3781  }
3782  /* OK, we read the message; mark data consumed */
3784 
3785  /*
3786  * Before 7.2, the postmaster didn't always end its
3787  * messages with a newline, so add one if needed to
3788  * conform to libpq conventions.
3789  */
3790  if (conn->errorMessage.len == 0 ||
3791  conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
3792  {
3794  }
3795 
3796  goto error_return;
3797  }
3798 #undef MAX_ERRLEN
3799 
3800  /*
3801  * Can't process if message body isn't all here yet.
3802  *
3803  * After this check passes, any further EOF during parsing
3804  * implies that the server sent a bad/truncated message.
3805  * Reading more bytes won't help in that case, so don't return
3806  * PGRES_POLLING_READING after this point.
3807  */
3808  msgLength -= 4;
3809  avail = conn->inEnd - conn->inCursor;
3810  if (avail < msgLength)
3811  {
3812  /*
3813  * Before returning, try to enlarge the input buffer if
3814  * needed to hold the whole message; see notes in
3815  * pqParseInput3.
3816  */
3817  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
3818  conn))
3819  goto error_return;
3820  /* We'll come back when there is more data */
3821  return PGRES_POLLING_READING;
3822  }
3823 
3824  /* Handle errors. */
3825  if (beresp == PqMsg_ErrorResponse)
3826  {
3827  if (pqGetErrorNotice3(conn, true))
3828  {
3829  libpq_append_conn_error(conn, "received invalid error message");
3830  goto error_return;
3831  }
3832  /* OK, we read the message; mark data consumed */
3834 
3835  /*
3836  * If error is "cannot connect now", try the next host if
3837  * any (but we don't want to consider additional addresses
3838  * for this host, nor is there much point in changing SSL
3839  * or GSS mode). This is helpful when dealing with
3840  * standby servers that might not be in hot-standby state.
3841  */
3842  if (strcmp(conn->last_sqlstate,
3844  {
3845  conn->try_next_host = true;
3846  goto keep_going;
3847  }
3848 
3849  /* Check to see if we should mention pgpassfile */
3851 
3853  }
3854  else if (beresp == PqMsg_NegotiateProtocolVersion)
3855  {
3857  {
3858  libpq_append_conn_error(conn, "received invalid protocol negotiation message");
3859  goto error_return;
3860  }
3861  /* OK, we read the message; mark data consumed */
3863  goto error_return;
3864  }
3865 
3866  /* It is an authentication request. */
3867  conn->auth_req_received = true;
3868 
3869  /* Get the type of request. */
3870  if (pqGetInt((int *) &areq, 4, conn))
3871  {
3872  /* can't happen because we checked the length already */
3873  libpq_append_conn_error(conn, "received invalid authentication request");
3874  goto error_return;
3875  }
3876  msgLength -= 4;
3877 
3878  /*
3879  * Process the rest of the authentication request message, and
3880  * respond to it if necessary.
3881  *
3882  * Note that conn->pghost must be non-NULL if we are going to
3883  * avoid the Kerberos code doing a hostname look-up.
3884  */
3885  res = pg_fe_sendauth(areq, msgLength, conn);
3886 
3887  /*
3888  * OK, we have processed the message; mark data consumed. We
3889  * don't call pqParseDone here because we already traced this
3890  * message inside pg_fe_sendauth.
3891  */
3892  conn->inStart = conn->inCursor;
3893 
3894  if (res != STATUS_OK)
3895  goto error_return;
3896 
3897  /*
3898  * Just make sure that any data sent by pg_fe_sendauth is
3899  * flushed out. Although this theoretically could block, it
3900  * really shouldn't since we don't send large auth responses.
3901  */
3902  if (pqFlush(conn))
3903  goto error_return;
3904 
3905  if (areq == AUTH_REQ_OK)
3906  {
3907  /* We are done with authentication exchange */
3909 
3910  /*
3911  * Set asyncStatus so that PQgetResult will think that
3912  * what comes back next is the result of a query. See
3913  * below.
3914  */
3916  }
3917 
3918  /* Look to see if we have more data yet. */
3919  goto keep_going;
3920  }
3921 
3922  case CONNECTION_AUTH_OK:
3923  {
3924  /*
3925  * Now we expect to hear from the backend. A ReadyForQuery
3926  * message indicates that startup is successful, but we might
3927  * also get an Error message indicating failure. (Notice
3928  * messages indicating nonfatal warnings are also allowed by
3929  * the protocol, as are ParameterStatus and BackendKeyData
3930  * messages.) Easiest way to handle this is to let
3931  * PQgetResult() read the messages. We just have to fake it
3932  * out about the state of the connection, by setting
3933  * asyncStatus = PGASYNC_BUSY (done above).
3934  */
3935 
3936  if (PQisBusy(conn))
3937  return PGRES_POLLING_READING;
3938 
3939  res = PQgetResult(conn);
3940 
3941  /*
3942  * NULL return indicating we have gone to IDLE state is
3943  * expected
3944  */
3945  if (res)
3946  {
3948  libpq_append_conn_error(conn, "unexpected message from server during startup");
3949  else if (conn->send_appname &&
3950  (conn->appname || conn->fbappname))
3951  {
3952  /*
3953  * If we tried to send application_name, check to see
3954  * if the error is about that --- pre-9.0 servers will
3955  * reject it at this stage of the process. If so,
3956  * close the connection and retry without sending
3957  * application_name. We could possibly get a false
3958  * SQLSTATE match here and retry uselessly, but there
3959  * seems no great harm in that; we'll just get the
3960  * same error again if it's unrelated.
3961  */
3962  const char *sqlstate;
3963 
3965  if (sqlstate &&
3966  strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
3967  {
3968  PQclear(res);
3969  conn->send_appname = false;
3970  need_new_connection = true;
3971  goto keep_going;
3972  }
3973  }
3974 
3975  /*
3976  * if the resultStatus is FATAL, then conn->errorMessage
3977  * already has a copy of the error; needn't copy it back.
3978  * But add a newline if it's not there already, since
3979  * postmaster error messages may not have one.
3980  */
3981  if (conn->errorMessage.len <= 0 ||
3982  conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
3984  PQclear(res);
3985  goto error_return;
3986  }
3987 
3988  /* Almost there now ... */
3990  goto keep_going;
3991  }
3992 
3994  {
3995  /*
3996  * If a read-write, read-only, primary, or standby connection
3997  * is required, see if we have one.
3998  */
4001  {
4002  bool read_only_server;
4003 
4004  /*
4005  * If the server didn't report
4006  * "default_transaction_read_only" or "in_hot_standby" at
4007  * startup, we must determine its state by sending the
4008  * query "SHOW transaction_read_only". This GUC exists in
4009  * all server versions that support 3.0 protocol.
4010  */
4013  {
4014  /*
4015  * We use PQsendQueryContinue so that
4016  * conn->errorMessage does not get cleared. We need
4017  * to preserve any error messages related to previous
4018  * hosts we have tried and failed to connect to.
4019  */
4022  "SHOW transaction_read_only"))
4023  goto error_return;
4024  /* We'll return to this state when we have the answer */
4026  return PGRES_POLLING_READING;
4027  }
4028 
4029  /* OK, we can make the test */
4030  read_only_server =
4033 
4035  read_only_server : !read_only_server)
4036  {
4037  /* Wrong server state, reject and try the next host */
4039  libpq_append_conn_error(conn, "session is read-only");
4040  else
4041  libpq_append_conn_error(conn, "session is not read-only");
4042 
4043  /* Close connection politely. */
4046 
4047  /*
4048  * Try next host if any, but we don't want to consider
4049  * additional addresses for this host.
4050  */
4051  conn->try_next_host = true;
4052  goto keep_going;
4053  }
4054  }
4058  {
4059  /*
4060  * If the server didn't report "in_hot_standby" at
4061  * startup, we must determine its state by sending the
4062  * query "SELECT pg_catalog.pg_is_in_recovery()". Servers
4063  * before 9.0 don't have that function, but by the same
4064  * token they don't have any standby mode, so we may just
4065  * assume the result.
4066  */
4067  if (conn->sversion < 90000)
4069 
4071  {
4072  /*
4073  * We use PQsendQueryContinue so that
4074  * conn->errorMessage does not get cleared. We need
4075  * to preserve any error messages related to previous
4076  * hosts we have tried and failed to connect to.
4077  */
4080  "SELECT pg_catalog.pg_is_in_recovery()"))
4081  goto error_return;
4082  /* We'll return to this state when we have the answer */
4084  return PGRES_POLLING_READING;
4085  }
4086 
4087  /* OK, we can make the test */
4091  {
4092  /* Wrong server state, reject and try the next host */
4094  libpq_append_conn_error(conn, "server is in hot standby mode");
4095  else
4096  libpq_append_conn_error(conn, "server is not in hot standby mode");
4097 
4098  /* Close connection politely. */
4101 
4102  /*
4103  * Try next host if any, but we don't want to consider
4104  * additional addresses for this host.
4105  */
4106  conn->try_next_host = true;
4107  goto keep_going;
4108  }
4109  }
4110 
4111  /*
4112  * For non cancel requests we can release the address list
4113  * now. For cancel requests we never actually resolve
4114  * addresses and instead the addrinfo exists for the lifetime
4115  * of the connection.
4116  */
4117  if (!conn->cancelRequest)
4119 
4120  /*
4121  * Contents of conn->errorMessage are no longer interesting
4122  * (and it seems some clients expect it to be empty after a
4123  * successful connection).
4124  */
4126 
4127  /* We are open for business! */
4129  return PGRES_POLLING_OK;
4130  }
4131 
4132  case CONNECTION_CONSUME:
4133  {
4134  /*
4135  * This state just makes sure the connection is idle after
4136  * we've obtained the result of a SHOW or SELECT query. Once
4137  * we're clear, return to CONNECTION_CHECK_TARGET state to
4138  * decide what to do next. We must transiently set status =
4139  * CONNECTION_OK in order to use the result-consuming
4140  * subroutines.
4141  */
4143  if (!PQconsumeInput(conn))
4144  goto error_return;
4145 
4146  if (PQisBusy(conn))
4147  {
4149  return PGRES_POLLING_READING;
4150  }
4151 
4152  /* Call PQgetResult() again until we get a NULL result */
4153  res = PQgetResult(conn);
4154  if (res != NULL)
4155  {
4156  PQclear(res);
4158  return PGRES_POLLING_READING;
4159  }
4160 
4162  goto keep_going;
4163  }
4164 
4166  {
4167  /*
4168  * Waiting for result of "SHOW transaction_read_only". We
4169  * must transiently set status = CONNECTION_OK in order to use
4170  * the result-consuming subroutines.
4171  */
4173  if (!PQconsumeInput(conn))
4174  goto error_return;
4175 
4176  if (PQisBusy(conn))
4177  {
4179  return PGRES_POLLING_READING;
4180  }
4181 
4182  res = PQgetResult(conn);
4183  if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
4184  PQntuples(res) == 1)
4185  {
4186  char *val = PQgetvalue(res, 0, 0);
4187 
4188  /*
4189  * "transaction_read_only = on" proves that at least one
4190  * of default_transaction_read_only and in_hot_standby is
4191  * on, but we don't actually know which. We don't care
4192  * though for the purpose of identifying a read-only
4193  * session, so satisfy the CONNECTION_CHECK_TARGET code by
4194  * claiming they are both on. On the other hand, if it's
4195  * a read-write session, they are certainly both off.
4196  */
4197  if (strncmp(val, "on", 2) == 0)
4198  {
4201  }
4202  else
4203  {
4206  }
4207  PQclear(res);
4208 
4209  /* Finish reading messages before continuing */
4211  goto keep_going;
4212  }
4213 
4214  /* Something went wrong with "SHOW transaction_read_only". */
4215  PQclear(res);
4216 
4217  /* Append error report to conn->errorMessage. */
4218  libpq_append_conn_error(conn, "\"%s\" failed",
4219  "SHOW transaction_read_only");
4220 
4221  /* Close connection politely. */
4224 
4225  /* Try next host. */
4226  conn->try_next_host = true;
4227  goto keep_going;
4228  }
4229 
4231  {
4232  /*
4233  * Waiting for result of "SELECT pg_is_in_recovery()". We
4234  * must transiently set status = CONNECTION_OK in order to use
4235  * the result-consuming subroutines.
4236  */
4238  if (!PQconsumeInput(conn))
4239  goto error_return;
4240 
4241  if (PQisBusy(conn))
4242  {
4244  return PGRES_POLLING_READING;
4245  }
4246 
4247  res = PQgetResult(conn);
4248  if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
4249  PQntuples(res) == 1)
4250  {
4251  char *val = PQgetvalue(res, 0, 0);
4252 
4253  if (strncmp(val, "t", 1) == 0)
4255  else
4257  PQclear(res);
4258 
4259  /* Finish reading messages before continuing */
4261  goto keep_going;
4262  }
4263 
4264  /* Something went wrong with "SELECT pg_is_in_recovery()". */
4265  PQclear(res);
4266 
4267  /* Append error report to conn->errorMessage. */
4268  libpq_append_conn_error(conn, "\"%s\" failed",
4269  "SELECT pg_is_in_recovery()");
4270 
4271  /* Close connection politely. */
4274 
4275  /* Try next host. */
4276  conn->try_next_host = true;
4277  goto keep_going;
4278  }
4279 
4280  default:
4282  "invalid connection state %d, probably indicative of memory corruption",
4283  conn->status);
4284  goto error_return;
4285  }
4286 
4287  /* Unreachable */
4288 
4289 error_return:
4290 
4291  /*
4292  * We used to close the socket at this point, but that makes it awkward
4293  * for those above us if they wish to remove this socket from their own
4294  * records (an fd_set for example). We'll just have this socket closed
4295  * when PQfinish is called (which is compulsory even after an error, since
4296  * the connection structure must be freed).
4297  */
4299  return PGRES_POLLING_FAILED;
4300 }
#define STATUS_OK
Definition: c.h:1169
#define MemSet(start, val, len)
Definition: c.h:1020
void err(int eval, const char *fmt,...)
Definition: err.c:43
int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
Definition: fe-auth.c:989
char * pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
Definition: fe-auth.c:1197
#define MAX_ERRLEN
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:472
static const PQEnvironmentOption EnvironmentOptions[]
Definition: fe-connect.c:373
#define CONNECTION_FAILED()
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:4813
static int setKeepalivesCount(PGconn *conn)
Definition: fe-connect.c:2257
static int useKeepalives(PGconn *conn)
Definition: fe-connect.c:2170
static int store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist)
Definition: fe-connect.c:4760
static void connectFailureMessage(PGconn *conn, int errorno)
Definition: fe-connect.c:2150
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:4799
#define ERRCODE_APPNAME_UNKNOWN
Definition: fe-connect.c:87
static int setKeepalivesInterval(PGconn *conn)
Definition: fe-connect.c:2222
static int setKeepalivesIdle(PGconn *conn)
Definition: fe-connect.c:2188
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:7733
static void pgpassfileWarning(PGconn *conn)
Definition: fe-connect.c:7590
static void emitHostIdentityInfo(PGconn *conn, const char *host_addr)
Definition: fe-connect.c:2094
static int setTCPUserTimeout(PGconn *conn)
Definition: fe-connect.c:2354
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:585
static int connectNoDelay(PGconn *conn)
Definition: fe-connect.c:2035
static void getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
Definition: fe-connect.c:2061
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:92
#define ENCRYPTION_NEGOTIATION_FAILED(msg)
static bool init_allowed_encryption_methods(PGconn *conn)
Definition: fe-connect.c:4306
int pqPacketSend(PGconn *conn, char pack_type, const void *buf, size_t buf_len)
Definition: fe-connect.c:5001
int PQsendQueryContinue(PGconn *conn, const char *query)
Definition: fe-exec.c:1422
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1984
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:779
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2031
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3466
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
bool pg_GSS_have_cred_cache(gss_cred_id_t *cred_out)
int pqFlush(PGconn *conn)
Definition: fe-misc.c:968
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 pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:351
int pqGets_append(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:142
int pqGetNegotiateProtocolVersion3(PGconn *conn)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:878
char * pqBuildStartupPacket3(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
PostgresPollingStatusType pqsecure_open_gss(PGconn *conn)
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition: fe-secure.c:138
void pqTraceOutputCharResponse(PGconn *conn, const char *responseType, char response)
Definition: fe-trace.c:909
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
Definition: ip.c:82
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:53
int j
Definition: isn.c:74
@ PGASYNC_IDLE
Definition: libpq-int.h:221
@ PGASYNC_BUSY
Definition: libpq-int.h:222
#define libpq_gettext(x)
Definition: libpq-int.h:905
@ LOAD_BALANCE_RANDOM
Definition: libpq-int.h:256
#define SOCK_STRERROR
Definition: libpq-int.h:927
#define ENC_GSSAPI
Definition: libpq-int.h:237
#define ENC_SSL
Definition: libpq-int.h:238
@ CHT_UNIX_SOCKET
Definition: libpq-int.h:317
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:316
@ CHT_HOST_NAME
Definition: libpq-int.h:315
@ PG_BOOL_YES
Definition: libpq-int.h:263
@ PG_BOOL_NO
Definition: libpq-int.h:264
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:262
@ SERVER_TYPE_STANDBY
Definition: libpq-int.h:247
@ SERVER_TYPE_PRIMARY
Definition: libpq-int.h:246
@ SERVER_TYPE_READ_WRITE
Definition: libpq-int.h:244
@ SERVER_TYPE_PREFER_STANDBY_PASS2
Definition: libpq-int.h:249
@ SERVER_TYPE_PREFER_STANDBY
Definition: libpq-int.h:248
@ SERVER_TYPE_READ_ONLY
Definition: libpq-int.h:245
#define MAXPGPATH
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
static char portstr[16]
Definition: pg_regress.c:117
bool pg_set_noblock(pgsocket sock)
Definition: noblock.c:25
#define snprintf
Definition: port.h:238
unsigned int socklen_t
Definition: port.h:40
int getpeereid(int sock, uid_t *uid, gid_t *gid)
Definition: getpeereid.c:33
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:56
#define UNIXSOCK_PATH(path, port, sockdir)
Definition: pqcomm.h:44
#define UNIXSOCK_PATH_BUFLEN
Definition: pqcomm.h:60
#define NEGOTIATE_GSS_CODE
Definition: pqcomm.h:168
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:167
uint32 ProtocolVersion
Definition: pqcomm.h:100
uint32 AuthRequest
Definition: pqcomm.h:122
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:90
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
#define AUTH_REQ_OK
Definition: protocol.h:74
#define PqMsg_AuthenticationRequest
Definition: protocol.h:50
#define PqMsg_NegotiateProtocolVersion
Definition: protocol.h:59
#define PqMsg_ErrorResponse
Definition: protocol.h:44
const char * gai_strerror(int ecode)
int family
Definition: pqcomm.h:38
SockAddr addr
Definition: pqcomm.h:39
MsgType cancelRequestCode
Definition: pqcomm.h:138
uint32 backendPID
Definition: pqcomm.h:139
uint32 cancelAuthCode
Definition: pqcomm.h:140
pg_conn_host_type type
Definition: libpq-int.h:363
SockAddr laddr
Definition: libpq-int.h:487
bool try_next_host
Definition: libpq-int.h:514
AddrInfo * addr
Definition: libpq-int.h:517
uint8 failed_enc_methods
Definition: libpq-int.h:576
char * sslnegotiation
Definition: libpq-int.h:409
bool sigpipe_flag
Definition: libpq-int.h:495
int nconnhost
Definition: libpq-int.h:466
ProtocolVersion pversion
Definition: libpq-int.h:489
bool send_appname
Definition: libpq-int.h:519
PGTransactionStatusType xactStatus
Definition: libpq-int.h:450
bool cancelRequest
Definition: libpq-int.h:431
int inCursor
Definition: libpq-int.h:539
PGTernaryBool in_hot_standby
Definition: libpq-int.h:528
int inEnd
Definition: libpq-int.h:540
char * fbappname
Definition: libpq-int.h:394
uint8 current_enc_method
Definition: libpq-int.h:577
int naddr
Definition: libpq-int.h:515
int inStart
Definition: libpq-int.h:538
char * connip
Definition: libpq-int.h:469
int sversion
Definition: libpq-int.h:490
bool auth_req_received
Definition: libpq-int.h:491
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:527
bool sigpipe_so
Definition: libpq-int.h:494
int whichaddr
Definition: libpq-int.h:516
char * appname
Definition: libpq-int.h:393
pg_prng_state prng_state
Definition: libpq-int.h:532
char * gssencmode
Definition: libpq-int.h:420
char last_sqlstate[6]
Definition: libpq-int.h:451
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:449
PGLoadBalanceType load_balance_type
Definition: libpq-int.h:511
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:455
uint8 allowed_enc_methods
Definition: libpq-int.h:575
PGTargetServerType target_server_type
Definition: libpq-int.h:510
FILE * Pfdebug
Definition: libpq-int.h:436
bool try_next_addr
Definition: libpq-int.h:513
char * requirepeer
Definition: libpq-int.h:419
bool ssl_in_use
Definition: libpq-int.h:580
ExecStatusType resultStatus
Definition: libpq-int.h:180
#define EWOULDBLOCK
Definition: win32_port.h:380
#define EINPROGRESS
Definition: win32_port.h:386
int gid_t
Definition: win32_port.h:245
int uid_t
Definition: win32_port.h:244

References AddrInfo::addr, SockAddr::addr, pg_conn::addr, pg_conn::allowed_enc_methods, appendPQExpBufferChar(), pg_conn::appname, Assert, pg_conn::asyncStatus, AUTH_REQ_OK, pg_conn::auth_req_received, CancelRequestPacket::backendPID, pg_conn::be_key, pg_conn::be_pid, CANCEL_REQUEST_CODE, CancelRequestPacket::cancelAuthCode, pg_conn::cancelRequest, CancelRequestPacket::cancelRequestCode, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, conn, connect, connectFailureMessage(), CONNECTION_AUTH_OK, CONNECTION_AWAITING_RESPONSE, CONNECTION_BAD, CONNECTION_CHECK_STANDBY, CONNECTION_CHECK_TARGET, CONNECTION_CHECK_WRITABLE, CONNECTION_CONSUME, CONNECTION_FAILED, CONNECTION_GSS_STARTUP, CONNECTION_MADE, CONNECTION_NEEDED, CONNECTION_OK, CONNECTION_SSL_STARTUP, CONNECTION_STARTED, connectNoDelay(), pg_conn::connhost, pg_conn::connip, pg_conn::current_enc_method, PQExpBufferData::data, pg_conn::default_transaction_read_only, EINPROGRESS, EINTR, emitHostIdentityInfo(), ENC_GSSAPI, ENC_SSL, ENCRYPTION_NEGOTIATION_FAILED, EnvironmentOptions, err(), ERRCODE_APPNAME_UNKNOWN, ERRCODE_CANNOT_CONNECT_NOW, pg_conn::errorMessage, EWOULDBLOCK, pg_conn::failed_enc_methods, AddrInfo::family, pg_conn::fbappname, free, gai_strerror(), getHostaddr(), getpeereid(), pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, pg_conn::in_hot_standby, pg_conn::inCursor, pg_conn::inEnd, init_allowed_encryption_methods(), pg_conn::inStart, j, pg_conn::laddr, pg_conn::last_sqlstate, PQExpBufferData::len, libpq_append_conn_error(), libpq_gettext, LOAD_BALANCE_RANDOM, pg_conn::load_balance_type, MAX_ERRLEN, MAXPGPATH, MemSet, pg_conn::naddr, pg_conn::nconnhost, NEGOTIATE_GSS_CODE, NEGOTIATE_SSL_CODE, pg_conn::Pfdebug, PG_BOOL_NO, PG_BOOL_UNKNOWN, PG_BOOL_YES, PG_DIAG_SQLSTATE, pg_fe_getusername(), pg_fe_sendauth(), pg_freeaddrinfo_all(), pg_getaddrinfo_all(), pg_GSS_have_cred_cache(), pg_hton32, pg_prng_uint64_range(), PG_PROTOCOL, pg_set_noblock(), PG_STRERROR_R_BUFLEN, PGASYNC_BUSY, PGASYNC_IDLE, PGINVALID_SOCKET, pgpassfileWarning(), PGRES_FATAL_ERROR, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PGRES_TUPLES_OK, pg_conn::pipelineStatus, pg_conn_host::port, portstr, PQ_PIPELINE_OFF, pqBuildStartupPacket3(), pqCheckInBufferSpace(), PQclear(), pqClearAsyncResult(), pqClearConnErrorState, PQconsumeInput(), pqDropConnection(), pqDropServerData(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetNegotiateProtocolVersion3(), PQgetResult(), pqGets_append(), PQgetvalue(), PQisBusy(), PqMsg_AuthenticationRequest, PqMsg_ErrorResponse, PqMsg_NegotiateProtocolVersion, PQntuples(), pqPacketSend(), pqParseDone(), pqParseIntParam(), pqReadData(), PQresultErrorField(), PQresultStatus(), pqsecure_open_client(), pqsecure_open_gss(), PQsendQueryContinue(), pqTraceOutputCharResponse(), PQTRANS_IDLE, pg_conn::prng_state, pg_conn::pversion, pg_conn::raddr, release_conn_addrinfo(), pg_conn::requirepeer, res, pg_result::resultStatus, SockAddr::salen, pg_conn::send_appname, sendTerminateConn(), SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PREFER_STANDBY_PASS2, SERVER_TYPE_PRIMARY, SERVER_TYPE_READ_ONLY, SERVER_TYPE_READ_WRITE, SERVER_TYPE_STANDBY, setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), setTCPUserTimeout(), pg_conn::sigpipe_flag, pg_conn::sigpipe_so, snprintf, pg_conn::sock, SOCK_ERRNO, SOCK_STRERROR, socket, pg_conn::ssl_in_use, pg_conn::sslnegotiation, pg_conn::status, STATUS_OK, store_conn_addrinfo(), strerror_r, pg_conn::sversion, pg_conn::target_server_type, pg_conn::try_next_addr, pg_conn::try_next_host, pg_conn_host::type, UNIXSOCK_PATH, UNIXSOCK_PATH_BUFLEN, useKeepalives(), val, pg_conn::whichaddr, pg_conn::whichhost, and pg_conn::xactStatus.

Referenced by libpqrcv_connect(), libpqsrv_connect_internal(), PQcancelPoll(), pqConnectDBComplete(), pqConnectDBStart(), PQresetPoll(), and wait_until_connected().

◆ PQconnectStart()

PGconn* PQconnectStart ( const char *  conninfo)

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

874 {
875  PGconn *conn;
876 
877  /*
878  * Allocate memory for the conn structure. Note that we also expect this
879  * to initialize conn->errorMessage to empty. All subsequent steps during
880  * connection initialization will only append to that buffer.
881  */
883  if (conn == NULL)
884  return NULL;
885 
886  /*
887  * Parse the conninfo string
888  */
889  if (!connectOptions1(conn, conninfo))
890  return conn;
891 
892  /*
893  * Compute derived options
894  */
895  if (!pqConnectOptions2(conn))
896  return conn;
897 
898  /*
899  * Connect to the database
900  */
901  if (!pqConnectDBStart(conn))
902  {
903  /* Just in case we failed to set it in pqConnectDBStart */
905  }
906 
907  return conn;
908 }
static bool connectOptions1(PGconn *conn, const char *conninfo)
Definition: fe-connect.c:998

References conn, CONNECTION_BAD, connectOptions1(), pqConnectDBStart(), pqConnectOptions2(), pqMakeEmptyPGconn(), and pg_conn::status.

Referenced by libpqsrv_connect(), PQconnectdb(), and PQping().

◆ PQconnectStartParams()

PGconn* PQconnectStartParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

795 {
796  PGconn *conn;
797  PQconninfoOption *connOptions;
798 
799  /*
800  * Allocate memory for the conn structure. Note that we also expect this
801  * to initialize conn->errorMessage to empty. All subsequent steps during
802  * connection initialization will only append to that buffer.
803  */
805  if (conn == NULL)
806  return NULL;
807 
808  /*
809  * Parse the conninfo arrays
810  */
811  connOptions = conninfo_array_parse(keywords, values,
812  &conn->errorMessage,
813  true, expand_dbname);
814  if (connOptions == NULL)
815  {
817  /* errorMessage is already set */
818  return conn;
819  }
820 
821  /*
822  * Move option values into conn structure
823  */
824  if (!fillPGconn(conn, connOptions))
825  {
826  PQconninfoFree(connOptions);
827  return conn;
828  }
829 
830  /*
831  * Free the option info - all is in conn now
832  */
833  PQconninfoFree(connOptions);
834 
835  /*
836  * Compute derived options
837  */
838  if (!pqConnectOptions2(conn))
839  return conn;
840 
841  /*
842  * Connect to the database
843  */
844  if (!pqConnectDBStart(conn))
845  {
846  /* Just in case we failed to set it in pqConnectDBStart */
848  }
849 
850  return conn;
851 }
static PQconninfoOption * conninfo_array_parse(const char *const *keywords, const char *const *values, PQExpBuffer errorMessage, bool use_defaults, int expand_dbname)
Definition: fe-connect.c:6044
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:919

References conn, CONNECTION_BAD, conninfo_array_parse(), pg_conn::errorMessage, fillPGconn(), pqConnectDBStart(), pqConnectOptions2(), PQconninfoFree(), pqMakeEmptyPGconn(), pg_conn::status, and values.

Referenced by do_connect(), libpqrcv_connect(), libpqsrv_connect_params(), PQconnectdbParams(), and PQpingParams().

◆ PQconninfo()

PQconninfoOption* PQconninfo ( PGconn conn)

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

6962 {
6963  PQExpBufferData errorBuf;
6964  PQconninfoOption *connOptions;
6965 
6966  if (conn == NULL)
6967  return NULL;
6968 
6969  /*
6970  * We don't actually report any errors here, but callees want a buffer,
6971  * and we prefer not to trash the conn's errorMessage.
6972  */
6973  initPQExpBuffer(&errorBuf);
6974  if (PQExpBufferDataBroken(errorBuf))
6975  return NULL; /* out of memory already :-( */
6976 
6977  connOptions = conninfo_init(&errorBuf);
6978 
6979  if (connOptions != NULL)
6980  {
6981  const internalPQconni