PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
libpq-int.h File Reference
#include "libpq-events.h"
#include <time.h>
#include "getaddrinfo.h"
#include "libpq/pqcomm.h"
#include "pqexpbuffer.h"
Include dependency graph for libpq-int.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

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

Macros

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

Typedefs

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

Enumerations

enum  PGAsyncStatusType {
  PGASYNC_IDLE, PGASYNC_BUSY, PGASYNC_READY, PGASYNC_COPY_IN,
  PGASYNC_COPY_OUT, PGASYNC_COPY_BOTH
}
 
enum  PGQueryClass { PGQUERY_SIMPLE, PGQUERY_EXTENDED, PGQUERY_PREPARE, PGQUERY_DESCRIBE }
 
enum  PGSetenvStatusType {
  SETENV_STATE_CLIENT_ENCODING_SEND, SETENV_STATE_CLIENT_ENCODING_WAIT, SETENV_STATE_OPTION_SEND, SETENV_STATE_OPTION_WAIT,
  SETENV_STATE_QUERY1_SEND, SETENV_STATE_QUERY1_WAIT, SETENV_STATE_QUERY2_SEND, SETENV_STATE_QUERY2_WAIT,
  SETENV_STATE_IDLE
}
 
enum  pg_conn_host_type { CHT_HOST_NAME, CHT_HOST_ADDRESS, CHT_UNIX_SOCKET }
 

Functions

void pqDropConnection (PGconn *conn, bool flushInput)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
void pqSetResultError (PGresult *res, const char *msg)
 
void pqCatenateResultError (PGresult *res, const char *msg)
 
void * pqResultAlloc (PGresult *res, size_t nBytes, bool isBinary)
 
char * pqResultStrdup (PGresult *res, const char *str)
 
void pqClearAsyncResult (PGconn *conn)
 
void pqSaveErrorResult (PGconn *conn)
 
PGresultpqPrepareAsyncResult (PGconn *conn)
 
void pqInternalNotice (const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2
 
void void pqSaveMessageField (PGresult *res, char code, const char *value)
 
void pqSaveParameterStatus (PGconn *conn, const char *name, const char *value)
 
int pqRowProcessor (PGconn *conn, const char **errmsgp)
 
void pqHandleSendFailure (PGconn *conn)
 
PostgresPollingStatusType pqSetenvPoll (PGconn *conn)
 
char * pqBuildStartupPacket2 (PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
 
void pqParseInput2 (PGconn *conn)
 
int pqGetCopyData2 (PGconn *conn, char **buffer, int async)
 
int pqGetline2 (PGconn *conn, char *s, int maxlen)
 
int pqGetlineAsync2 (PGconn *conn, char *buffer, int bufsize)
 
int pqEndcopy2 (PGconn *conn)
 
PGresultpqFunctionCall2 (PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
char * pqBuildStartupPacket3 (PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
 
void pqParseInput3 (PGconn *conn)
 
int pqGetErrorNotice3 (PGconn *conn, bool isError)
 
void pqBuildErrorMessage3 (PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
 
int pqGetCopyData3 (PGconn *conn, char **buffer, int async)
 
int pqGetline3 (PGconn *conn, char *s, int maxlen)
 
int pqGetlineAsync3 (PGconn *conn, char *buffer, int bufsize)
 
int pqEndcopy3 (PGconn *conn)
 
PGresultpqFunctionCall3 (PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
int pqCheckOutBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqCheckInBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqGetc (char *result, PGconn *conn)
 
int pqPutc (char c, PGconn *conn)
 
int pqGets (PQExpBuffer buf, PGconn *conn)
 
int pqGets_append (PQExpBuffer buf, PGconn *conn)
 
int pqPuts (const char *s, PGconn *conn)
 
int pqGetnchar (char *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const char *s, size_t len, PGconn *conn)
 
int pqGetInt (int *result, size_t bytes, PGconn *conn)
 
int pqPutInt (int value, size_t bytes, PGconn *conn)
 
int pqPutMsgStart (char msg_type, bool force_len, PGconn *conn)
 
int pqPutMsgEnd (PGconn *conn)
 
int pqReadData (PGconn *conn)
 
int pqFlush (PGconn *conn)
 
int pqWait (int forRead, int forWrite, PGconn *conn)
 
int pqWaitTimed (int forRead, int forWrite, PGconn *conn, time_t finish_time)
 
int pqReadReady (PGconn *conn)
 
int pqWriteReady (PGconn *conn)
 
int pqsecure_initialize (PGconn *)
 
void pqsecure_destroy (void)
 
PostgresPollingStatusType pqsecure_open_client (PGconn *)
 
void pqsecure_close (PGconn *)
 
ssize_t pqsecure_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_write (PGconn *, const void *ptr, size_t len)
 
ssize_t pqsecure_raw_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_raw_write (PGconn *, const void *ptr, size_t len)
 
void pgtls_init_library (bool do_ssl, int do_crypto)
 
int pgtls_init (PGconn *conn)
 
PostgresPollingStatusType pgtls_open_client (PGconn *conn)
 
void pgtls_close (PGconn *conn)
 
ssize_t pgtls_read (PGconn *conn, void *ptr, size_t len)
 
bool pgtls_read_pending (PGconn *conn)
 
ssize_t pgtls_write (PGconn *conn, const void *ptr, size_t len)
 

Variables

char *const pgresStatus []
 

Macro Definition Documentation

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */

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

Referenced by pqParseInput2(), and pqParseInput3().

#define libpq_gettext (   x)    (x)

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

Referenced by build_client_final_message(), build_client_first_message(), connectDBStart(), connectFailureMessage(), connectNoDelay(), connectOptions2(), conninfo_add_defaults(), conninfo_array_parse(), conninfo_init(), conninfo_parse(), conninfo_storeval(), conninfo_uri_decode(), conninfo_uri_parse_options(), conninfo_uri_parse_params(), do_field(), do_header(), fillPGconn(), getAnotherTuple(), getParamDescriptions(), getRowDescriptions(), handleSyncLoss(), initialize_SSL(), lo_create(), lo_export(), lo_import_internal(), lo_initialize(), lo_lseek64(), lo_read(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_write(), open_client_SSL(), parseServiceFile(), parseServiceInfo(), passwordFromFile(), pg_fe_getauthname(), pg_fe_scram_exchange(), pg_fe_sendauth(), pg_local_sendauth(), pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pgpassfileWarning(), pgtls_read(), pgtls_write(), pqBuildErrorMessage3(), PQconnectPoll(), PQdisplayTuples(), PQencryptPasswordConn(), pqEndcopy2(), pqEndcopy3(), PQerrorMessage(), PQescapeByteaInternal(), PQescapeInternal(), PQescapeStringInternal(), PQexecStart(), PQfn(), pqFunctionCall2(), pqFunctionCall3(), PQgetCopyData(), pqGetCopyData2(), pqGetCopyData3(), pqGetErrorNotice2(), pqGetErrorNotice3(), pqGetline3(), PQgetResult(), pqInternalNotice(), pqParseInput2(), pqParseInput3(), PQprint(), PQprintTuples(), PQputCopyData(), PQputCopyEnd(), pqReadData(), PQreset(), PQresetPoll(), PQresStatus(), PQresultVerboseErrorMessage(), pqsecure_raw_read(), pqsecure_raw_write(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), PQsendQueryParams(), PQsendQueryPrepared(), PQsendQueryStart(), pqSendSome(), PQsetdbLogin(), pqSetenvPoll(), pqSocketCheck(), pqWaitTimed(), read_attr_value(), read_server_final_message(), read_server_first_message(), reportErrorPosition(), saveErrorMessage(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), SSLerrmessage(), verify_peer_name_matches_certificate(), and verify_peer_name_matches_certificate_name().

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

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

Referenced by verify_peer_name_matches_certificate().

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

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

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

#define pglock_thread ( )    ((void) 0)

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

Referenced by pg_fe_getauthname(), pg_fe_sendauth(), and pg_frontend_random().

#define pgunlock_thread ( )    ((void) 0)

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

Referenced by pg_fe_getauthname(), pg_fe_sendauth(), and pg_frontend_random().

#define pqIsnonblocking (   conn)    ((conn)->nonblocking)
#define SOCK_ERRNO_SET (   e)    (errno = (e))

Typedef Documentation

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

Enumeration Type Documentation

Enumerator
CHT_HOST_NAME 
CHT_HOST_ADDRESS 
CHT_UNIX_SOCKET 

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

Enumerator
PGASYNC_IDLE 
PGASYNC_BUSY 
PGASYNC_READY 
PGASYNC_COPY_IN 
PGASYNC_COPY_OUT 
PGASYNC_COPY_BOTH 

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

215 {
216  PGASYNC_IDLE, /* nothing's happening, dude */
217  PGASYNC_BUSY, /* query in progress */
218  PGASYNC_READY, /* result ready for PQgetResult */
219  PGASYNC_COPY_IN, /* Copy In data transfer in progress */
220  PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */
221  PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */
PGAsyncStatusType
Definition: libpq-int.h:214
Enumerator
PGQUERY_SIMPLE 
PGQUERY_EXTENDED 
PGQUERY_PREPARE 
PGQUERY_DESCRIBE 

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

226 {
227  PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
228  PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
229  PGQUERY_PREPARE, /* Parse only (PQprepare) */
230  PGQUERY_DESCRIBE /* Describe Statement or Portal */
231 } PGQueryClass;
PGQueryClass
Definition: libpq-int.h:225
Enumerator
SETENV_STATE_CLIENT_ENCODING_SEND 
SETENV_STATE_CLIENT_ENCODING_WAIT 
SETENV_STATE_OPTION_SEND 
SETENV_STATE_OPTION_WAIT 
SETENV_STATE_QUERY1_SEND 
SETENV_STATE_QUERY1_WAIT 
SETENV_STATE_QUERY2_SEND 
SETENV_STATE_QUERY2_WAIT 
SETENV_STATE_IDLE 

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

236 {
237  SETENV_STATE_CLIENT_ENCODING_SEND, /* About to send an Environment Option */
238  SETENV_STATE_CLIENT_ENCODING_WAIT, /* Waiting for above send to complete */
239  SETENV_STATE_OPTION_SEND, /* About to send an Environment Option */
240  SETENV_STATE_OPTION_WAIT, /* Waiting for above send to complete */
241  SETENV_STATE_QUERY1_SEND, /* About to send a status query */
242  SETENV_STATE_QUERY1_WAIT, /* Waiting for query to complete */
243  SETENV_STATE_QUERY2_SEND, /* About to send a status query */
244  SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */
PGSetenvStatusType
Definition: libpq-int.h:235

Function Documentation

void pgtls_close ( PGconn conn)

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

References destroy_ssl_system(), and NULL.

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

1388 {
1389  bool destroy_needed = false;
1390 
1391  if (conn->ssl)
1392  {
1393  /*
1394  * We can't destroy everything SSL-related here due to the possible
1395  * later calls to OpenSSL routines which may need our thread
1396  * callbacks, so set a flag here and check at the end.
1397  */
1398  destroy_needed = true;
1399 
1400  SSL_shutdown(conn->ssl);
1401  SSL_free(conn->ssl);
1402  conn->ssl = NULL;
1403  conn->ssl_in_use = false;
1404  }
1405 
1406  if (conn->peer)
1407  {
1408  X509_free(conn->peer);
1409  conn->peer = NULL;
1410  }
1411 
1412 #ifdef USE_SSL_ENGINE
1413  if (conn->engine)
1414  {
1415  ENGINE_finish(conn->engine);
1416  ENGINE_free(conn->engine);
1417  conn->engine = NULL;
1418  }
1419 #endif
1420 
1421  /*
1422  * This will remove our SSL locking hooks, if this is the last SSL
1423  * connection, which means we must wait to call it until after all SSL
1424  * calls have been made, otherwise we can end up with a race condition and
1425  * possible deadlocks.
1426  *
1427  * See comments above destroy_ssl_system().
1428  */
1429  if (destroy_needed)
1431 }
#define NULL
Definition: c.h:229
static void destroy_ssl_system(void)
int pgtls_init ( PGconn conn)

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

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

Referenced by pqsecure_initialize().

752 {
753 #ifdef ENABLE_THREAD_SAFETY
754 #ifdef WIN32
755  /* Also see similar code in fe-connect.c, default_threadlock() */
756  if (ssl_config_mutex == NULL)
757  {
758  while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
759  /* loop, another thread own the lock */ ;
760  if (ssl_config_mutex == NULL)
761  {
762  if (pthread_mutex_init(&ssl_config_mutex, NULL))
763  return -1;
764  }
765  InterlockedExchange(&win32_ssl_create_mutex, 0);
766  }
767 #endif
768  if (pthread_mutex_lock(&ssl_config_mutex))
769  return -1;
770 
771 #ifdef HAVE_CRYPTO_LOCK
772  if (pq_init_crypto_lib)
773  {
774  /*
775  * If necessary, set up an array to hold locks for libcrypto.
776  * libcrypto will tell us how big to make this array.
777  */
778  if (pq_lockarray == NULL)
779  {
780  int i;
781 
782  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
783  if (!pq_lockarray)
784  {
785  pthread_mutex_unlock(&ssl_config_mutex);
786  return -1;
787  }
788  for (i = 0; i < CRYPTO_num_locks(); i++)
789  {
790  if (pthread_mutex_init(&pq_lockarray[i], NULL))
791  {
792  free(pq_lockarray);
793  pq_lockarray = NULL;
794  pthread_mutex_unlock(&ssl_config_mutex);
795  return -1;
796  }
797  }
798  }
799 
800  if (ssl_open_connections++ == 0)
801  {
802  /*
803  * These are only required for threaded libcrypto applications,
804  * but make sure we don't stomp on them if they're already set.
805  */
806  if (CRYPTO_get_id_callback() == NULL)
807  CRYPTO_set_id_callback(pq_threadidcallback);
808  if (CRYPTO_get_locking_callback() == NULL)
809  CRYPTO_set_locking_callback(pq_lockingcallback);
810  }
811  }
812 #endif /* HAVE_CRYPTO_LOCK */
813 #endif /* ENABLE_THREAD_SAFETY */
814 
815  if (!ssl_lib_initialized)
816  {
817  if (pq_init_ssl_lib)
818  {
819 #ifdef HAVE_OPENSSL_INIT_SSL
820  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
821 #else
822  OPENSSL_config(NULL);
823  SSL_library_init();
824  SSL_load_error_strings();
825 #endif
826  }
827  ssl_lib_initialized = true;
828  }
829 
830 #ifdef ENABLE_THREAD_SAFETY
831  pthread_mutex_unlock(&ssl_config_mutex);
832 #endif
833  return 0;
834 }
static bool pq_init_ssl_lib
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
#define malloc(a)
Definition: header.h:50
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
static bool pq_init_crypto_lib
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
int i
static bool ssl_lib_initialized
void pgtls_init_library ( bool  do_ssl,
int  do_crypto 
)

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

References pq_init_crypto_lib, and pq_init_ssl_lib.

Referenced by PQinitOpenSSL(), and PQinitSSL().

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

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

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

Referenced by pqsecure_open_client().

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

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

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

Referenced by pqsecure_read().

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

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

Referenced by pqSocketCheck().

152 {
153  return SSL_pending(conn->ssl);
154 }
ssize_t pgtls_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

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

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

Referenced by pqsecure_write().

296 {
297  ssize_t n;
298  int result_errno = 0;
299  char sebuf[256];
300  int err;
301  unsigned long ecode;
302 
303  SOCK_ERRNO_SET(0);
304  ERR_clear_error();
305  n = SSL_write(conn->ssl, ptr, len);
306  err = SSL_get_error(conn->ssl, n);
307  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
308  switch (err)
309  {
310  case SSL_ERROR_NONE:
311  if (n < 0)
312  {
313  /* Not supposed to happen, so we don't translate the msg */
315  "SSL_write failed but did not provide error information\n");
316  /* assume the connection is broken */
317  result_errno = ECONNRESET;
318  }
319  break;
320  case SSL_ERROR_WANT_READ:
321 
322  /*
323  * Returning 0 here causes caller to wait for write-ready, which
324  * is not really the right thing, but it's the best we can do.
325  */
326  n = 0;
327  break;
328  case SSL_ERROR_WANT_WRITE:
329  n = 0;
330  break;
331  case SSL_ERROR_SYSCALL:
332  if (n < 0)
333  {
334  result_errno = SOCK_ERRNO;
335  if (result_errno == EPIPE || result_errno == ECONNRESET)
338  "server closed the connection unexpectedly\n"
339  "\tThis probably means the server terminated abnormally\n"
340  "\tbefore or while processing the request.\n"));
341  else
343  libpq_gettext("SSL SYSCALL error: %s\n"),
344  SOCK_STRERROR(result_errno,
345  sebuf, sizeof(sebuf)));
346  }
347  else
348  {
350  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
351  /* assume the connection is broken */
352  result_errno = ECONNRESET;
353  n = -1;
354  }
355  break;
356  case SSL_ERROR_SSL:
357  {
358  char *errm = SSLerrmessage(ecode);
359 
361  libpq_gettext("SSL error: %s\n"), errm);
362  SSLerrfree(errm);
363  /* assume the connection is broken */
364  result_errno = ECONNRESET;
365  n = -1;
366  break;
367  }
368  case SSL_ERROR_ZERO_RETURN:
369 
370  /*
371  * Per OpenSSL documentation, this error code is only returned for
372  * a clean connection closure, so we should not report it as a
373  * server crash.
374  */
376  libpq_gettext("SSL connection has been closed unexpectedly\n"));
377  result_errno = ECONNRESET;
378  n = -1;
379  break;
380  default:
382  libpq_gettext("unrecognized SSL error code: %d\n"),
383  err);
384  /* assume the connection is broken */
385  result_errno = ECONNRESET;
386  n = -1;
387  break;
388  }
389 
390  /* ensure we return the intended errno to caller */
391  SOCK_ERRNO_SET(result_errno);
392 
393  return n;
394 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define ECONNRESET
Definition: win32.h:295
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define SOCK_ERRNO
Definition: libpq-int.h:695
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:697
static void SSLerrfree(char *buf)
PQExpBufferData errorMessage
Definition: libpq-int.h:491
static char * SSLerrmessage(unsigned long ecode)
#define libpq_gettext(x)
Definition: libpq-int.h:682
void pqBuildErrorMessage3 ( PQExpBuffer  msg,
const PGresult res,
PGVerbosity  verbosity,
PGContextVisibility  show_context 
)

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

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

Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().

984 {
985  const char *val;
986  const char *querytext = NULL;
987  int querypos = 0;
988 
989  /* If we couldn't allocate a PGresult, just say "out of memory" */
990  if (res == NULL)
991  {
992  appendPQExpBuffer(msg, libpq_gettext("out of memory\n"));
993  return;
994  }
995 
996  /*
997  * If we don't have any broken-down fields, just return the base message.
998  * This mainly applies if we're given a libpq-generated error result.
999  */
1000  if (res->errFields == NULL)
1001  {
1002  if (res->errMsg && res->errMsg[0])
1003  appendPQExpBufferStr(msg, res->errMsg);
1004  else
1005  appendPQExpBuffer(msg, libpq_gettext("no error message available\n"));
1006  return;
1007  }
1008 
1009  /* Else build error message from relevant fields */
1011  if (val)
1012  appendPQExpBuffer(msg, "%s: ", val);
1013  if (verbosity == PQERRORS_VERBOSE)
1014  {
1016  if (val)
1017  appendPQExpBuffer(msg, "%s: ", val);
1018  }
1020  if (val)
1021  appendPQExpBufferStr(msg, val);
1023  if (val)
1024  {
1025  if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1026  {
1027  /* emit position as a syntax cursor display */
1028  querytext = res->errQuery;
1029  querypos = atoi(val);
1030  }
1031  else
1032  {
1033  /* emit position as text addition to primary message */
1034  /* translator: %s represents a digit string */
1035  appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1036  val);
1037  }
1038  }
1039  else
1040  {
1042  if (val)
1043  {
1044  querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1045  if (verbosity != PQERRORS_TERSE && querytext != NULL)
1046  {
1047  /* emit position as a syntax cursor display */
1048  querypos = atoi(val);
1049  }
1050  else
1051  {
1052  /* emit position as text addition to primary message */
1053  /* translator: %s represents a digit string */
1054  appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1055  val);
1056  }
1057  }
1058  }
1059  appendPQExpBufferChar(msg, '\n');
1060  if (verbosity != PQERRORS_TERSE)
1061  {
1062  if (querytext && querypos > 0)
1063  reportErrorPosition(msg, querytext, querypos,
1064  res->client_encoding);
1066  if (val)
1067  appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1069  if (val)
1070  appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1072  if (val)
1073  appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1074  if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1075  (show_context == PQSHOW_CONTEXT_ERRORS &&
1077  {
1078  val = PQresultErrorField(res, PG_DIAG_CONTEXT);
1079  if (val)
1080  appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1081  val);
1082  }
1083  }
1084  if (verbosity == PQERRORS_VERBOSE)
1085  {
1087  if (val)
1088  appendPQExpBuffer(msg,
1089  libpq_gettext("SCHEMA NAME: %s\n"), val);
1091  if (val)
1092  appendPQExpBuffer(msg,
1093  libpq_gettext("TABLE NAME: %s\n"), val);
1095  if (val)
1096  appendPQExpBuffer(msg,
1097  libpq_gettext("COLUMN NAME: %s\n"), val);
1099  if (val)
1100  appendPQExpBuffer(msg,
1101  libpq_gettext("DATATYPE NAME: %s\n"), val);
1103  if (val)
1104  appendPQExpBuffer(msg,
1105  libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1106  }
1107  if (verbosity == PQERRORS_VERBOSE)
1108  {
1109  const char *valf;
1110  const char *vall;
1111 
1115  if (val || valf || vall)
1116  {
1117  appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1118  if (val)
1119  appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1120  if (valf && vall) /* unlikely we'd have just one */
1121  appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1122  valf, vall);
1123  appendPQExpBufferChar(msg, '\n');
1124  }
1125  }
1126 }
PGMessageField * errFields
Definition: libpq-int.h:197
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:67
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:66
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:71
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:62
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * errMsg
Definition: libpq-int.h:196
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:70
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
char * errQuery
Definition: libpq-int.h:198
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:68
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:69
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:63
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define NULL
Definition: c.h:229
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:72
ExecStatusType resultStatus
Definition: libpq-int.h:177
long val
Definition: informix.c:689
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64
#define libpq_gettext(x)
Definition: libpq-int.h:682
int client_encoding
Definition: libpq-int.h:189
char* pqBuildStartupPacket2 ( PGconn conn,
int *  packetlen,
const PQEnvironmentOption options 
)

Definition at line 1600 of file fe-protocol2.c.

References StartupPacket::database, pg_conn::dbName, malloc, MemSet, NULL, StartupPacket::options, pg_conn::pgoptions, pg_conn::pgtty, pg_conn::pguser, StartupPacket::protoVersion, pg_conn::pversion, SM_DATABASE, SM_OPTIONS, SM_TTY, SM_USER, StartupPacket::tty, and StartupPacket::user.

Referenced by PQconnectPoll().

1602 {
1603  StartupPacket *startpacket;
1604 
1605  *packetlen = sizeof(StartupPacket);
1606  startpacket = (StartupPacket *) malloc(sizeof(StartupPacket));
1607  if (!startpacket)
1608  return NULL;
1609 
1610  MemSet(startpacket, 0, sizeof(StartupPacket));
1611 
1612  startpacket->protoVersion = htonl(conn->pversion);
1613 
1614  /* strncpy is safe here: postmaster will handle full fields correctly */
1615  strncpy(startpacket->user, conn->pguser, SM_USER);
1616  strncpy(startpacket->database, conn->dbName, SM_DATABASE);
1617  strncpy(startpacket->tty, conn->pgtty, SM_TTY);
1618 
1619  if (conn->pgoptions)
1620  strncpy(startpacket->options, conn->pgoptions, SM_OPTIONS);
1621 
1622  return (char *) startpacket;
1623 }
char tty[SM_TTY]
Definition: pqcomm.h:149
struct StartupPacket StartupPacket
char * dbName
Definition: libpq-int.h:341
#define MemSet(start, val, len)
Definition: c.h:858
#define SM_USER
Definition: pqcomm.h:134
char options[SM_OPTIONS]
Definition: pqcomm.h:147
#define malloc(a)
Definition: header.h:50
#define SM_TTY
Definition: pqcomm.h:139
char * pguser
Definition: libpq-int.h:343
char database[SM_DATABASE]
Definition: pqcomm.h:144
#define NULL
Definition: c.h:229
char * pgoptions
Definition: libpq-int.h:338
ProtocolVersion pversion
Definition: libpq-int.h:404
char user[SM_USER]
Definition: pqcomm.h:146
ProtocolVersion protoVersion
Definition: pqcomm.h:143
#define SM_OPTIONS
Definition: pqcomm.h:137
#define SM_DATABASE
Definition: pqcomm.h:133
char * pgtty
Definition: libpq-int.h:334
char* pqBuildStartupPacket3 ( PGconn conn,
int *  packetlen,
const PQEnvironmentOption options 
)

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

References build_startup_packet(), malloc, and NULL.

Referenced by PQconnectPoll().

2120 {
2121  char *startpacket;
2122 
2123  *packetlen = build_startup_packet(conn, NULL, options);
2124  startpacket = (char *) malloc(*packetlen);
2125  if (!startpacket)
2126  return NULL;
2127  *packetlen = build_startup_packet(conn, startpacket, options);
2128  return startpacket;
2129 }
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)
#define malloc(a)
Definition: header.h:50
#define NULL
Definition: c.h:229
void pqCatenateResultError ( PGresult res,
const char *  msg 
)

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

References appendPQExpBufferStr(), PQExpBufferData::data, pg_result::errMsg, initPQExpBuffer(), pqSetResultError(), and termPQExpBuffer().

Referenced by PQexecFinish(), and pqSaveErrorResult().

632 {
633  PQExpBufferData errorBuf;
634 
635  if (!res || !msg)
636  return;
637  initPQExpBuffer(&errorBuf);
638  if (res->errMsg)
639  appendPQExpBufferStr(&errorBuf, res->errMsg);
640  appendPQExpBufferStr(&errorBuf, msg);
641  pqSetResultError(res, errorBuf.data);
642  termPQExpBuffer(&errorBuf);
643 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
char * errMsg
Definition: libpq-int.h:196
void pqSetResultError(PGresult *res, const char *msg)
Definition: fe-exec.c:616
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
int pqCheckInBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

References pg_conn::errorMessage, pg_conn::inBuffer, pg_conn::inBufSize, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, memmove, printfPQExpBuffer(), and realloc.

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

411 {
412  int newsize = conn->inBufSize;
413  char *newbuf;
414 
415  /* Quick exit if we have enough space */
416  if (bytes_needed <= (size_t) newsize)
417  return 0;
418 
419  /*
420  * Before concluding that we need to enlarge the buffer, left-justify
421  * whatever is in it and recheck. The caller's value of bytes_needed
422  * includes any data to the left of inStart, but we can delete that in
423  * preference to enlarging the buffer. It's slightly ugly to have this
424  * function do this, but it's better than making callers worry about it.
425  */
426  bytes_needed -= conn->inStart;
427 
428  if (conn->inStart < conn->inEnd)
429  {
430  if (conn->inStart > 0)
431  {
432  memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
433  conn->inEnd - conn->inStart);
434  conn->inEnd -= conn->inStart;
435  conn->inCursor -= conn->inStart;
436  conn->inStart = 0;
437  }
438  }
439  else
440  {
441  /* buffer is logically empty, reset it */
442  conn->inStart = conn->inCursor = conn->inEnd = 0;
443  }
444 
445  /* Recheck whether we have enough space */
446  if (bytes_needed <= (size_t) newsize)
447  return 0;
448 
449  /*
450  * If we need to enlarge the buffer, we first try to double it in size; if
451  * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
452  * the malloc pool by repeated small enlargements.
453  *
454  * Note: tests for newsize > 0 are to catch integer overflow.
455  */
456  do
457  {
458  newsize *= 2;
459  } while (newsize > 0 && bytes_needed > (size_t) newsize);
460 
461  if (newsize > 0 && bytes_needed <= (size_t) newsize)
462  {
463  newbuf = realloc(conn->inBuffer, newsize);
464  if (newbuf)
465  {
466  /* realloc succeeded */
467  conn->inBuffer = newbuf;
468  conn->inBufSize = newsize;
469  return 0;
470  }
471  }
472 
473  newsize = conn->inBufSize;
474  do
475  {
476  newsize += 8192;
477  } while (newsize > 0 && bytes_needed > (size_t) newsize);
478 
479  if (newsize > 0 && bytes_needed <= (size_t) newsize)
480  {
481  newbuf = realloc(conn->inBuffer, newsize);
482  if (newbuf)
483  {
484  /* realloc succeeded */
485  conn->inBuffer = newbuf;
486  conn->inBufSize = newsize;
487  return 0;
488  }
489  }
490 
491  /* realloc failed. Probably out of memory */
493  "cannot allocate memory for input buffer\n");
494  return EOF;
495 }
int inEnd
Definition: libpq-int.h:433
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:431
int inBufSize
Definition: libpq-int.h:430
#define memmove(d, s, c)
Definition: c.h:1059
char * inBuffer
Definition: libpq-int.h:429
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define realloc(a, b)
Definition: header.h:60
int inCursor
Definition: libpq-int.h:432
int pqCheckOutBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

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

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

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

347 {
348  int newsize = conn->outBufSize;
349  char *newbuf;
350 
351  /* Quick exit if we have enough space */
352  if (bytes_needed <= (size_t) newsize)
353  return 0;
354 
355  /*
356  * If we need to enlarge the buffer, we first try to double it in size; if
357  * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
358  * the malloc pool by repeated small enlargements.
359  *
360  * Note: tests for newsize > 0 are to catch integer overflow.
361  */
362  do
363  {
364  newsize *= 2;
365  } while (newsize > 0 && bytes_needed > (size_t) newsize);
366 
367  if (newsize > 0 && bytes_needed <= (size_t) newsize)
368  {
369  newbuf = realloc(conn->outBuffer, newsize);
370  if (newbuf)
371  {
372  /* realloc succeeded */
373  conn->outBuffer = newbuf;
374  conn->outBufSize = newsize;
375  return 0;
376  }
377  }
378 
379  newsize = conn->outBufSize;
380  do
381  {
382  newsize += 8192;
383  } while (newsize > 0 && bytes_needed > (size_t) newsize);
384 
385  if (newsize > 0 && bytes_needed <= (size_t) newsize)
386  {
387  newbuf = realloc(conn->outBuffer, newsize);
388  if (newbuf)
389  {
390  /* realloc succeeded */
391  conn->outBuffer = newbuf;
392  conn->outBufSize = newsize;
393  return 0;
394  }
395  }
396 
397  /* realloc failed. Probably out of memory */
399  "cannot allocate memory for output buffer\n");
400  return EOF;
401 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PQExpBufferData errorMessage
Definition: libpq-int.h:491
int outBufSize
Definition: libpq-int.h:437
#define realloc(a, b)
Definition: header.h:60
char * outBuffer
Definition: libpq-int.h:436
void pqClearAsyncResult ( PGconn conn)

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

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

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

706 {
707  if (conn->result)
708  PQclear(conn->result);
709  conn->result = NULL;
710  if (conn->next_result)
711  PQclear(conn->next_result);
712  conn->next_result = NULL;
713 }
PGresult * result
Definition: libpq-int.h:450
PGresult * next_result
Definition: libpq-int.h:451
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
void pqDropConnection ( PGconn conn,
bool  flushInput 
)

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

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

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

425 {
426  /* Drop any SSL state */
427  pqsecure_close(conn);
428 
429  /* Close the socket itself */
430  if (conn->sock != PGINVALID_SOCKET)
431  closesocket(conn->sock);
432  conn->sock = PGINVALID_SOCKET;
433 
434  /* Optionally discard any unread data */
435  if (flushInput)
436  conn->inStart = conn->inCursor = conn->inEnd = 0;
437 
438  /* Always discard any unsent data */
439  conn->outCount = 0;
440 
441  /* Free authentication state */
442 #ifdef ENABLE_GSS
443  {
444  OM_uint32 min_s;
445 
446  if (conn->gctx)
447  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
448  if (conn->gtarg_nam)
449  gss_release_name(&min_s, &conn->gtarg_nam);
450  }
451 #endif
452 #ifdef ENABLE_SSPI
453  if (conn->sspitarget)
454  {
455  free(conn->sspitarget);
456  conn->sspitarget = NULL;
457  }
458  if (conn->sspicred)
459  {
460  FreeCredentialsHandle(conn->sspicred);
461  free(conn->sspicred);
462  conn->sspicred = NULL;
463  }
464  if (conn->sspictx)
465  {
466  DeleteSecurityContext(conn->sspictx);
467  free(conn->sspictx);
468  conn->sspictx = NULL;
469  }
470  conn->usesspi = 0;
471 #endif
472  if (conn->sasl_state)
473  {
474  /*
475  * XXX: if support for more authentication mechanisms is added, this
476  * needs to call the right 'free' function.
477  */
479  conn->sasl_state = NULL;
480  }
481 }
int inEnd
Definition: libpq-int.h:433
int inStart
Definition: libpq-int.h:431
void pg_fe_scram_free(void *opaq)
#define closesocket
Definition: port.h:331
int outCount
Definition: libpq-int.h:438
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:189
void * sasl_state
Definition: libpq-int.h:454
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
int inCursor
Definition: libpq-int.h:432
int pqEndcopy2 ( PGconn conn)

Definition at line 1344 of file fe-protocol2.c.

References pg_conn::asyncStatus, PQExpBufferData::data, pg_conn::errorMessage, PQExpBufferData::len, libpq_gettext, pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGRES_COMMAND_OK, PQclear(), pqFlush(), PQgetResult(), pqInternalNotice(), PQisBusy(), pqIsnonblocking, PQreset(), PQresetStart(), printfPQExpBuffer(), resetPQExpBuffer(), result, and pg_result::resultStatus.

Referenced by PQendcopy().

1345 {
1346  PGresult *result;
1347 
1348  if (conn->asyncStatus != PGASYNC_COPY_IN &&
1349  conn->asyncStatus != PGASYNC_COPY_OUT)
1350  {
1352  libpq_gettext("no COPY in progress\n"));
1353  return 1;
1354  }
1355 
1356  /*
1357  * make sure no data is waiting to be sent, abort if we are non-blocking
1358  * and the flush fails
1359  */
1360  if (pqFlush(conn) && pqIsnonblocking(conn))
1361  return 1;
1362 
1363  /* non blocking connections may have to abort at this point. */
1364  if (pqIsnonblocking(conn) && PQisBusy(conn))
1365  return 1;
1366 
1367  /* Return to active duty */
1368  conn->asyncStatus = PGASYNC_BUSY;
1370 
1371  /* Wait for the completion response */
1372  result = PQgetResult(conn);
1373 
1374  /* Expecting a successful result */
1375  if (result && result->resultStatus == PGRES_COMMAND_OK)
1376  {
1377  PQclear(result);
1378  return 0;
1379  }
1380 
1381  /*
1382  * Trouble. For backwards-compatibility reasons, we issue the error
1383  * message as if it were a notice (would be nice to get rid of this
1384  * silliness, but too many apps probably don't handle errors from
1385  * PQendcopy reasonably). Note that the app can still obtain the error
1386  * status from the PGconn object.
1387  */
1388  if (conn->errorMessage.len > 0)
1389  {
1390  /* We have to strip the trailing newline ... pain in neck... */
1391  char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1392 
1393  if (svLast == '\n')
1394  conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1395  pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1396  conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1397  }
1398 
1399  PQclear(result);
1400 
1401  /*
1402  * The worst case is that we've lost sync with the backend entirely due to
1403  * application screwup of the copy in/out protocol. To recover, reset the
1404  * connection (talk about using a sledgehammer...)
1405  */
1407  "lost synchronization with server, resetting connection");
1408 
1409  /*
1410  * Users doing non-blocking connections need to handle the reset
1411  * themselves, they'll need to check the connection status if we return an
1412  * error.
1413  */
1414  if (pqIsnonblocking(conn))
1415  PQresetStart(conn);
1416  else
1417  PQreset(conn);
1418 
1419  return 1;
1420 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:963
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int PQresetStart(PGconn *conn)
Definition: fe-connect.c:3685
#define pqIsnonblocking(conn)
Definition: libpq-int.h:676
return result
Definition: formatting.c:1633
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
PQExpBufferData errorMessage
Definition: libpq-int.h:491
void PQclear(PGresult *res)
Definition: fe-exec.c:650
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1681
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
ExecStatusType resultStatus
Definition: libpq-int.h:177
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
#define libpq_gettext(x)
Definition: libpq-int.h:682
void PQreset(PGconn *conn)
Definition: fe-connect.c:3644
int pqEndcopy3 ( PGconn conn)

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

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

Referenced by PQendcopy().

1809 {
1810  PGresult *result;
1811 
1812  if (conn->asyncStatus != PGASYNC_COPY_IN &&
1813  conn->asyncStatus != PGASYNC_COPY_OUT &&
1814  conn->asyncStatus != PGASYNC_COPY_BOTH)
1815  {
1817  libpq_gettext("no COPY in progress\n"));
1818  return 1;
1819  }
1820 
1821  /* Send the CopyDone message if needed */
1822  if (conn->asyncStatus == PGASYNC_COPY_IN ||
1823  conn->asyncStatus == PGASYNC_COPY_BOTH)
1824  {
1825  if (pqPutMsgStart('c', false, conn) < 0 ||
1826  pqPutMsgEnd(conn) < 0)
1827  return 1;
1828 
1829  /*
1830  * If we sent the COPY command in extended-query mode, we must issue a
1831  * Sync as well.
1832  */
1833  if (conn->queryclass != PGQUERY_SIMPLE)
1834  {
1835  if (pqPutMsgStart('S', false, conn) < 0 ||
1836  pqPutMsgEnd(conn) < 0)
1837  return 1;
1838  }
1839  }
1840 
1841  /*
1842  * make sure no data is waiting to be sent, abort if we are non-blocking
1843  * and the flush fails
1844  */
1845  if (pqFlush(conn) && pqIsnonblocking(conn))
1846  return 1;
1847 
1848  /* Return to active duty */
1849  conn->asyncStatus = PGASYNC_BUSY;
1851 
1852  /*
1853  * Non blocking connections may have to abort at this point. If everyone
1854  * played the game there should be no problem, but in error scenarios the
1855  * expected messages may not have arrived yet. (We are assuming that the
1856  * backend's packetizing will ensure that CommandComplete arrives along
1857  * with the CopyDone; are there corner cases where that doesn't happen?)
1858  */
1859  if (pqIsnonblocking(conn) && PQisBusy(conn))
1860  return 1;
1861 
1862  /* Wait for the completion response */
1863  result = PQgetResult(conn);
1864 
1865  /* Expecting a successful result */
1866  if (result && result->resultStatus == PGRES_COMMAND_OK)
1867  {
1868  PQclear(result);
1869  return 0;
1870  }
1871 
1872  /*
1873  * Trouble. For backwards-compatibility reasons, we issue the error
1874  * message as if it were a notice (would be nice to get rid of this
1875  * silliness, but too many apps probably don't handle errors from
1876  * PQendcopy reasonably). Note that the app can still obtain the error
1877  * status from the PGconn object.
1878  */
1879  if (conn->errorMessage.len > 0)
1880  {
1881  /* We have to strip the trailing newline ... pain in neck... */
1882  char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1883 
1884  if (svLast == '\n')
1885  conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1886  pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1887  conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1888  }
1889 
1890  PQclear(result);
1891 
1892  return 1;
1893 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:963
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define pqIsnonblocking(conn)
Definition: libpq-int.h:676
PGQueryClass queryclass
Definition: libpq-int.h:382
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:521
return result
Definition: formatting.c:1633
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
PQExpBufferData errorMessage
Definition: libpq-int.h:491
void PQclear(PGresult *res)
Definition: fe-exec.c:650
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1681
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:589
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
ExecStatusType resultStatus
Definition: libpq-int.h:177
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
#define libpq_gettext(x)
Definition: libpq-int.h:682
int pqFlush ( PGconn conn)

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

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

Referenced by pg_SASL_init(), PQconnectPoll(), PQconsumeInput(), pqEndcopy2(), pqEndcopy3(), PQflush(), pqFunctionCall2(), pqFunctionCall3(), PQgetResult(), pqPacketSend(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), PQsetnonblocking(), and sendTerminateConn().

964 {
965  if (conn->Pfdebug)
966  fflush(conn->Pfdebug);
967 
968  if (conn->outCount > 0)
969  return pqSendSome(conn, conn->outCount);
970 
971  return 0;
972 }
int outCount
Definition: libpq-int.h:438
FILE * Pfdebug
Definition: libpq-int.h:368
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:831
PGresult* pqFunctionCall2 ( PGconn conn,
Oid  fnid,
int *  result_buf,
int *  actual_result_len,
int  result_is_int,
const PQArgBlock args,
int  nargs 
)

Definition at line 1429 of file fe-protocol2.c.

References pg_conn::errorMessage, FALSE, getNotify(), i, pg_conn::inCursor, pg_conn::inStart, PQArgBlock::integer, PQArgBlock::len, libpq_gettext, NULL, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pqFlush(), pqGetc(), pqGetErrorNotice2(), pqGetInt(), pqGetnchar(), pqHandleSendFailure(), PQmakeEmptyPGresult(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqPuts(), pqReadData(), pqSaveErrorResult(), pqWait(), printfPQExpBuffer(), PQArgBlock::ptr, pg_conn::result, status(), and TRUE.

Referenced by PQfn().

1433 {
1434  bool needInput = false;
1436  char id;
1437  int i;
1438 
1439  /* PQfn already validated connection state */
1440 
1441  if (pqPutMsgStart('F', false, conn) < 0 || /* function call msg */
1442  pqPuts(" ", conn) < 0 || /* dummy string */
1443  pqPutInt(fnid, 4, conn) != 0 || /* function id */
1444  pqPutInt(nargs, 4, conn) != 0) /* # of args */
1445  {
1446  pqHandleSendFailure(conn);
1447  return NULL;
1448  }
1449 
1450  for (i = 0; i < nargs; ++i)
1451  { /* len.int4 + contents */
1452  if (pqPutInt(args[i].len, 4, conn))
1453  {
1454  pqHandleSendFailure(conn);
1455  return NULL;
1456  }
1457 
1458  if (args[i].isint)
1459  {
1460  if (pqPutInt(args[i].u.integer, 4, conn))
1461  {
1462  pqHandleSendFailure(conn);
1463  return NULL;
1464  }
1465  }
1466  else
1467  {
1468  if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1469  {
1470  pqHandleSendFailure(conn);
1471  return NULL;
1472  }
1473  }
1474  }
1475 
1476  if (pqPutMsgEnd(conn) < 0 ||
1477  pqFlush(conn))
1478  {
1479  pqHandleSendFailure(conn);
1480  return NULL;
1481  }
1482 
1483  for (;;)
1484  {
1485  if (needInput)
1486  {
1487  /* Wait for some data to arrive (or for the channel to close) */
1488  if (pqWait(TRUE, FALSE, conn) ||
1489  pqReadData(conn) < 0)
1490  break;
1491  }
1492 
1493  /*
1494  * Scan the message. If we run out of data, loop around to try again.
1495  */
1496  conn->inCursor = conn->inStart;
1497  needInput = true;
1498 
1499  if (pqGetc(&id, conn))
1500  continue;
1501 
1502  /*
1503  * We should see V or E response to the command, but might get N
1504  * and/or A notices first. We also need to swallow the final Z before
1505  * returning.
1506  */
1507  switch (id)
1508  {
1509  case 'V': /* function result */
1510  if (pqGetc(&id, conn))
1511  continue;
1512  if (id == 'G')
1513  {
1514  /* function returned nonempty value */
1515  if (pqGetInt(actual_result_len, 4, conn))
1516  continue;
1517  if (result_is_int)
1518  {
1519  if (pqGetInt(result_buf, 4, conn))
1520  continue;
1521  }
1522  else
1523  {
1524  if (pqGetnchar((char *) result_buf,
1525  *actual_result_len,
1526  conn))
1527  continue;
1528  }
1529  if (pqGetc(&id, conn)) /* get the last '0' */
1530  continue;
1531  }
1532  if (id == '0')
1533  {
1534  /* correctly finished function result message */
1535  status = PGRES_COMMAND_OK;
1536  }
1537  else
1538  {
1539  /* The backend violates the protocol. */
1541  libpq_gettext("protocol error: id=0x%x\n"),
1542  id);
1543  pqSaveErrorResult(conn);
1544  conn->inStart = conn->inCursor;
1545  return pqPrepareAsyncResult(conn);
1546  }
1547  break;
1548  case 'E': /* error return */
1549  if (pqGetErrorNotice2(conn, true))
1550  continue;
1551  status = PGRES_FATAL_ERROR;
1552  break;
1553  case 'A': /* notify message */
1554  /* handle notify and go back to processing return values */
1555  if (getNotify(conn))
1556  continue;
1557  break;
1558  case 'N': /* notice */
1559  /* handle notice and go back to processing return values */
1560  if (pqGetErrorNotice2(conn, false))
1561  continue;
1562  break;
1563  case 'Z': /* backend is ready for new query */
1564  /* consume the message and exit */
1565  conn->inStart = conn->inCursor;
1566  /* if we saved a result object (probably an error), use it */
1567  if (conn->result)
1568  return pqPrepareAsyncResult(conn);
1569  return PQmakeEmptyPGresult(conn, status);
1570  default:
1571  /* The backend violates the protocol. */
1573  libpq_gettext("protocol error: id=0x%x\n"),
1574  id);
1575  pqSaveErrorResult(conn);
1576  conn->inStart = conn->inCursor;
1577  return pqPrepareAsyncResult(conn);
1578  }
1579  /* Completed this message, keep going */
1580  conn->inStart = conn->inCursor;
1581  needInput = false;
1582  }
1583 
1584  /*
1585  * We fall out of the loop only upon failing to read data.
1586  * conn->errorMessage has been set by pqWait or pqReadData. We want to
1587  * append it to any already-received error message.
1588  */
1589  pqSaveErrorResult(conn);
1590  return pqPrepareAsyncResult(conn);
1591 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:963
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
void pqHandleSendFailure(PGconn *conn)
Definition: fe-exec.c:1582
int inStart
Definition: libpq-int.h:431
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:521
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:269
ExecStatusType
Definition: libpq-fe.h:82
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:197
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:756
PGresult * result
Definition: libpq-int.h:450
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:309
#define FALSE
Definition: c.h:221
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
int pqPuts(const char *s, PGconn *conn)
Definition: fe-misc.c:181
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:96
static int getNotify(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:248
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:589
int i
#define TRUE
Definition: c.h:217
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:432
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:682
int integer
Definition: libpq-fe.h:227
static int pqGetErrorNotice2(PGconn *conn, bool isError)
Definition: fe-protocol2.c:963
PGresult* pqFunctionCall3 ( PGconn conn,
Oid  fnid,
int *  result_buf,
int *  actual_result_len,
int  result_is_int,
const PQArgBlock args,
int  nargs 
)

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

References pg_conn::errorMessage, FALSE, getNotify(), getParameterStatus(), getReadyForQuery(), handleSyncLoss(), i, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, PQArgBlock::integer, PQArgBlock::len, libpq_gettext, NULL, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), pqHandleSendFailure(), PQmakeEmptyPGresult(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), pqWait(), printfPQExpBuffer(), PQArgBlock::ptr, pg_conn::result, status(), TRUE, and VALID_LONG_MESSAGE_TYPE.

Referenced by PQfn().

1906 {
1907  bool needInput = false;
1909  char id;
1910  int msgLength;
1911  int avail;
1912  int i;
1913 
1914  /* PQfn already validated connection state */
1915 
1916  if (pqPutMsgStart('F', false, conn) < 0 || /* function call msg */
1917  pqPutInt(fnid, 4, conn) < 0 || /* function id */
1918  pqPutInt(1, 2, conn) < 0 || /* # of format codes */
1919  pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
1920  pqPutInt(nargs, 2, conn) < 0) /* # of args */
1921  {
1922  pqHandleSendFailure(conn);
1923  return NULL;
1924  }
1925 
1926  for (i = 0; i < nargs; ++i)
1927  { /* len.int4 + contents */
1928  if (pqPutInt(args[i].len, 4, conn))
1929  {
1930  pqHandleSendFailure(conn);
1931  return NULL;
1932  }
1933  if (args[i].len == -1)
1934  continue; /* it's NULL */
1935 
1936  if (args[i].isint)
1937  {
1938  if (pqPutInt(args[i].u.integer, args[i].len, conn))
1939  {
1940  pqHandleSendFailure(conn);
1941  return NULL;
1942  }
1943  }
1944  else
1945  {
1946  if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1947  {
1948  pqHandleSendFailure(conn);
1949  return NULL;
1950  }
1951  }
1952  }
1953 
1954  if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
1955  {
1956  pqHandleSendFailure(conn);
1957  return NULL;
1958  }
1959 
1960  if (pqPutMsgEnd(conn) < 0 ||
1961  pqFlush(conn))
1962  {
1963  pqHandleSendFailure(conn);
1964  return NULL;
1965  }
1966 
1967  for (;;)
1968  {
1969  if (needInput)
1970  {
1971  /* Wait for some data to arrive (or for the channel to close) */
1972  if (pqWait(TRUE, FALSE, conn) ||
1973  pqReadData(conn) < 0)
1974  break;
1975  }
1976 
1977  /*
1978  * Scan the message. If we run out of data, loop around to try again.
1979  */
1980  needInput = true;
1981 
1982  conn->inCursor = conn->inStart;
1983  if (pqGetc(&id, conn))
1984  continue;
1985  if (pqGetInt(&msgLength, 4, conn))
1986  continue;
1987 
1988  /*
1989  * Try to validate message type/length here. A length less than 4 is
1990  * definitely broken. Large lengths should only be believed for a few
1991  * message types.
1992  */
1993  if (msgLength < 4)
1994  {
1995  handleSyncLoss(conn, id, msgLength);
1996  break;
1997  }
1998  if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
1999  {
2000  handleSyncLoss(conn, id, msgLength);
2001  break;
2002  }
2003 
2004  /*
2005  * Can't process if message body isn't all here yet.
2006  */
2007  msgLength -= 4;
2008  avail = conn->inEnd - conn->inCursor;
2009  if (avail < msgLength)
2010  {
2011  /*
2012  * Before looping, enlarge the input buffer if needed to hold the
2013  * whole message. See notes in parseInput.
2014  */
2015  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2016  conn))
2017  {
2018  /*
2019  * XXX add some better recovery code... plan is to skip over
2020  * the message using its length, then report an error. For the
2021  * moment, just treat this like loss of sync (which indeed it
2022  * might be!)
2023  */
2024  handleSyncLoss(conn, id, msgLength);
2025  break;
2026  }
2027  continue;
2028  }
2029 
2030  /*
2031  * We should see V or E response to the command, but might get N
2032  * and/or A notices first. We also need to swallow the final Z before
2033  * returning.
2034  */
2035  switch (id)
2036  {
2037  case 'V': /* function result */
2038  if (pqGetInt(actual_result_len, 4, conn))
2039  continue;
2040  if (*actual_result_len != -1)
2041  {
2042  if (result_is_int)
2043  {
2044  if (pqGetInt(result_buf, *actual_result_len, conn))
2045  continue;
2046  }
2047  else
2048  {
2049  if (pqGetnchar((char *) result_buf,
2050  *actual_result_len,
2051  conn))
2052  continue;
2053  }
2054  }
2055  /* correctly finished function result message */
2056  status = PGRES_COMMAND_OK;
2057  break;
2058  case 'E': /* error return */
2059  if (pqGetErrorNotice3(conn, true))
2060  continue;
2061  status = PGRES_FATAL_ERROR;
2062  break;
2063  case 'A': /* notify message */
2064  /* handle notify and go back to processing return values */
2065  if (getNotify(conn))
2066  continue;
2067  break;
2068  case 'N': /* notice */
2069  /* handle notice and go back to processing return values */
2070  if (pqGetErrorNotice3(conn, false))
2071  continue;
2072  break;
2073  case 'Z': /* backend is ready for new query */
2074  if (getReadyForQuery(conn))
2075  continue;
2076  /* consume the message and exit */
2077  conn->inStart += 5 + msgLength;
2078  /* if we saved a result object (probably an error), use it */
2079  if (conn->result)
2080  return pqPrepareAsyncResult(conn);
2081  return PQmakeEmptyPGresult(conn, status);
2082  case 'S': /* parameter status */
2083  if (getParameterStatus(conn))
2084  continue;
2085  break;
2086  default:
2087  /* The backend violates the protocol. */
2089  libpq_gettext("protocol error: id=0x%x\n"),
2090  id);
2091  pqSaveErrorResult(conn);
2092  /* trust the specified message length as what to skip */
2093  conn->inStart += 5 + msgLength;
2094  return pqPrepareAsyncResult(conn);
2095  }
2096  /* Completed this message, keep going */
2097  /* trust the specified message length as what to skip */
2098  conn->inStart += 5 + msgLength;
2099  needInput = false;
2100  }
2101 
2102  /*
2103  * We fall out of the loop only upon failing to read data.
2104  * conn->errorMessage has been set by pqWait or pqReadData. We want to
2105  * append it to any already-received error message.
2106  */
2107  pqSaveErrorResult(conn);
2108  return pqPrepareAsyncResult(conn);
2109 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:963
int inEnd
Definition: libpq-int.h:433
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
void pqHandleSendFailure(PGconn *conn)
Definition: fe-exec.c:1582
int inStart
Definition: libpq-int.h:431
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:410
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:521
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:269
ExecStatusType
Definition: libpq-fe.h:82
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:197
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:756
PGresult * result
Definition: libpq-int.h:450
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:309
#define FALSE
Definition: c.h:221
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:876
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:96
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:41
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:248
static int getReadyForQuery(PGconn *conn)
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:589
static int getParameterStatus(PGconn *conn)
static int getNotify(PGconn *conn)
int i
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:450
#define TRUE
Definition: c.h:217
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:432
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:682
int integer
Definition: libpq-fe.h:227
int pqGetc ( char *  result,
PGconn conn 
)

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

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

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

97 {
98  if (conn->inCursor >= conn->inEnd)
99  return EOF;
100 
101  *result = conn->inBuffer[conn->inCursor++];
102 
103  if (conn->Pfdebug)
104  fprintf(conn->Pfdebug, "From backend> %c\n", *result);
105 
106  return 0;
107 }
int inEnd
Definition: libpq-int.h:433
return result
Definition: formatting.c:1633
FILE * Pfdebug
Definition: libpq-int.h:368
char * inBuffer
Definition: libpq-int.h:429
int inCursor
Definition: libpq-int.h:432
int pqGetCopyData2 ( PGconn conn,
char **  buffer,
int  async 
)

Definition at line 1161 of file fe-protocol2.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, FALSE, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_gettext, malloc, NULL, PGASYNC_BUSY, pqReadData(), pqWait(), printfPQExpBuffer(), and TRUE.

Referenced by PQgetCopyData().

1162 {
1163  bool found;
1164  int msgLength;
1165 
1166  for (;;)
1167  {
1168  /*
1169  * Do we have a complete line of data?
1170  */
1171  conn->inCursor = conn->inStart;
1172  found = false;
1173  while (conn->inCursor < conn->inEnd)
1174  {
1175  char c = conn->inBuffer[conn->inCursor++];
1176 
1177  if (c == '\n')
1178  {
1179  found = true;
1180  break;
1181  }
1182  }
1183  if (!found)
1184  goto nodata;
1185  msgLength = conn->inCursor - conn->inStart;
1186 
1187  /*
1188  * If it's the end-of-data marker, consume it, exit COPY_OUT mode, and
1189  * let caller read status with PQgetResult().
1190  */
1191  if (msgLength == 3 &&
1192  strncmp(&conn->inBuffer[conn->inStart], "\\.\n", 3) == 0)
1193  {
1194  conn->inStart = conn->inCursor;
1195  conn->asyncStatus = PGASYNC_BUSY;
1196  return -1;
1197  }
1198 
1199  /*
1200  * Pass the line back to the caller.
1201  */
1202  *buffer = (char *) malloc(msgLength + 1);
1203  if (*buffer == NULL)
1204  {
1206  libpq_gettext("out of memory\n"));
1207  return -2;
1208  }
1209  memcpy(*buffer, &conn->inBuffer[conn->inStart], msgLength);
1210  (*buffer)[msgLength] = '\0'; /* Add terminating null */
1211 
1212  /* Mark message consumed */
1213  conn->inStart = conn->inCursor;
1214 
1215  return msgLength;
1216 
1217 nodata:
1218  /* Don't block if async read requested */
1219  if (async)
1220  return 0;
1221  /* Need to load more data */
1222  if (pqWait(TRUE, FALSE, conn) ||
1223  pqReadData(conn) < 0)
1224  return -2;
1225  }
1226 }
int inEnd
Definition: libpq-int.h:433
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:431
#define malloc(a)
Definition: header.h:50
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define FALSE
Definition: c.h:221
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
char * c
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
char * inBuffer
Definition: libpq-int.h:429
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define TRUE
Definition: c.h:217
int inCursor
Definition: libpq-int.h:432
#define libpq_gettext(x)
Definition: libpq-int.h:682
int pqGetCopyData3 ( PGconn conn,
char **  buffer,
int  async 
)

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

References pg_conn::errorMessage, FALSE, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, libpq_gettext, malloc, NULL, pqReadData(), pqWait(), printfPQExpBuffer(), and TRUE.

Referenced by PQgetCopyData().

1642 {
1643  int msgLength;
1644 
1645  for (;;)
1646  {
1647  /*
1648  * Collect the next input message. To make life simpler for async
1649  * callers, we keep returning 0 until the next message is fully
1650  * available, even if it is not Copy Data.
1651  */
1652  msgLength = getCopyDataMessage(conn);
1653  if (msgLength < 0)
1654  return msgLength; /* end-of-copy or error */
1655  if (msgLength == 0)
1656  {
1657  /* Don't block if async read requested */
1658  if (async)
1659  return 0;
1660  /* Need to load more data */
1661  if (pqWait(TRUE, FALSE, conn) ||
1662  pqReadData(conn) < 0)
1663  return -2;
1664  continue;
1665  }
1666 
1667  /*
1668  * Drop zero-length messages (shouldn't happen anyway). Otherwise
1669  * pass the data back to the caller.
1670  */
1671  msgLength -= 4;
1672  if (msgLength > 0)
1673  {
1674  *buffer = (char *) malloc(msgLength + 1);
1675  if (*buffer == NULL)
1676  {
1678  libpq_gettext("out of memory\n"));
1679  return -2;
1680  }
1681  memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1682  (*buffer)[msgLength] = '\0'; /* Add terminating null */
1683 
1684  /* Mark message consumed */
1685  conn->inStart = conn->inCursor + msgLength;
1686 
1687  return msgLength;
1688  }
1689 
1690  /* Empty, so drop it and loop around for another */
1691  conn->inStart = conn->inCursor;
1692  }
1693 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:431
#define malloc(a)
Definition: header.h:50
#define FALSE
Definition: c.h:221
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
char * inBuffer
Definition: libpq-int.h:429
static int getCopyDataMessage(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define TRUE
Definition: c.h:217
int inCursor
Definition: libpq-int.h:432
#define libpq_gettext(x)
Definition: libpq-int.h:682
int pqGetErrorNotice3 ( PGconn conn,
bool  isError 
)

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

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

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

877 {
878  PGresult *res = NULL;
879  bool have_position = false;
880  PQExpBufferData workBuf;
881  char id;
882 
883  /*
884  * Since the fields might be pretty long, we create a temporary
885  * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
886  * for stuff that is expected to be short. We shouldn't use
887  * conn->errorMessage either, since this might be only a notice.
888  */
889  initPQExpBuffer(&workBuf);
890 
891  /*
892  * Make a PGresult to hold the accumulated fields. We temporarily lie
893  * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
894  * copy conn->errorMessage.
895  *
896  * NB: This allocation can fail, if you run out of memory. The rest of the
897  * function handles that gracefully, and we still try to set the error
898  * message as the connection's error message.
899  */
901  if (res)
903 
904  /*
905  * Read the fields and save into res.
906  *
907  * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
908  * we saw a PG_DIAG_STATEMENT_POSITION field.
909  */
910  for (;;)
911  {
912  if (pqGetc(&id, conn))
913  goto fail;
914  if (id == '\0')
915  break; /* terminator found */
916  if (pqGets(&workBuf, conn))
917  goto fail;
918  pqSaveMessageField(res, id, workBuf.data);
919  if (id == PG_DIAG_SQLSTATE)
920  strlcpy(conn->last_sqlstate, workBuf.data,
921  sizeof(conn->last_sqlstate));
922  else if (id == PG_DIAG_STATEMENT_POSITION)
923  have_position = true;
924  }
925 
926  /*
927  * Save the active query text, if any, into res as well; but only if we
928  * might need it for an error cursor display, which is only true if there
929  * is a PG_DIAG_STATEMENT_POSITION field.
930  */
931  if (have_position && conn->last_query && res)
932  res->errQuery = pqResultStrdup(res, conn->last_query);
933 
934  /*
935  * Now build the "overall" error message for PQresultErrorMessage.
936  */
937  resetPQExpBuffer(&workBuf);
938  pqBuildErrorMessage3(&workBuf, res, conn->verbosity, conn->show_context);
939 
940  /*
941  * Either save error as current async result, or just emit the notice.
942  */
943  if (isError)
944  {
945  if (res)
946  res->errMsg = pqResultStrdup(res, workBuf.data);
947  pqClearAsyncResult(conn);
948  conn->result = res;
949  if (PQExpBufferDataBroken(workBuf))
951  libpq_gettext("out of memory"));
952  else
953  appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
954  }
955  else
956  {
957  /* if we couldn't allocate the result set, just discard the NOTICE */
958  if (res)
959  {
960  /* We can cheat a little here and not copy the message. */
961  res->errMsg = workBuf.data;
962  if (res->noticeHooks.noticeRec != NULL)
963  (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
964  PQclear(res);
965  }
966  }
967 
968  termPQExpBuffer(&workBuf);
969  return 0;
970 
971 fail:
972  PQclear(res);
973  termPQExpBuffer(&workBuf);
974  return EOF;
975 }
PGContextVisibility show_context
Definition: libpq-int.h:425
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:165
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * errMsg
Definition: libpq-int.h:196
PGresult * result
Definition: libpq-int.h:450
PGNoticeHooks noticeHooks
Definition: libpq-int.h:186
PGVerbosity verbosity
Definition: libpq-int.h:424
PQnoticeReceiver noticeRec
Definition: libpq-int.h:152
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
char * last_query
Definition: libpq-int.h:383
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
char * errQuery
Definition: libpq-int.h:198
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:96
void pqSaveMessageField(PGresult *res, char code, const char *value)
Definition: fe-exec.c:891
PQExpBufferData errorMessage
Definition: libpq-int.h:491
void PQclear(PGresult *res)
Definition: fe-exec.c:650
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:229
void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition: fe-protocol3.c:982
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:705
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
ExecStatusType resultStatus
Definition: libpq-int.h:177
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
#define libpq_gettext(x)
Definition: libpq-int.h:682
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:602
void * noticeRecArg
Definition: libpq-int.h:153
char last_sqlstate[6]
Definition: libpq-int.h:384
bool pqGetHomeDirectory ( char *  buf,
int  bufsize 
)

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

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

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

6517 {
6518 #ifndef WIN32
6519  char pwdbuf[BUFSIZ];
6520  struct passwd pwdstr;
6521  struct passwd *pwd = NULL;
6522 
6523  (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
6524  if (pwd == NULL)
6525  return false;
6526  strlcpy(buf, pwd->pw_dir, bufsize);
6527  return true;
6528 #else
6529  char tmppath[MAX_PATH];
6530 
6531  ZeroMemory(tmppath, sizeof(tmppath));
6532  if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
6533  return false;
6534  snprintf(buf, bufsize, "%s/postgresql", tmppath);
6535  return true;
6536 #endif
6537 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static char * buf
Definition: pg_test_fsync.c:66
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
Definition: thread.c:95
int pqGetInt ( int *  result,
size_t  bytes,
PGconn conn 
)

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

References pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::noticeHooks, pg_conn::Pfdebug, and pqInternalNotice().

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

270 {
271  uint16 tmp2;
272  uint32 tmp4;
273 
274  switch (bytes)
275  {
276  case 2:
277  if (conn->inCursor + 2 > conn->inEnd)
278  return EOF;
279  memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
280  conn->inCursor += 2;
281  *result = (int) ntohs(tmp2);
282  break;
283  case 4:
284  if (conn->inCursor + 4 > conn->inEnd)
285  return EOF;
286  memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
287  conn->inCursor += 4;
288  *result = (int) ntohl(tmp4);
289  break;
290  default:
292  "integer of size %lu not supported by pqGetInt",
293  (unsigned long) bytes);
294  return EOF;
295  }
296 
297  if (conn->Pfdebug)
298  fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
299 
300  return 0;
301 }
int inEnd
Definition: libpq-int.h:433
return result
Definition: formatting.c:1633
FILE * Pfdebug
Definition: libpq-int.h:368
unsigned short uint16
Definition: c.h:267
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
unsigned int uint32
Definition: c.h:268
char * inBuffer
Definition: libpq-int.h:429
int inCursor
Definition: libpq-int.h:432
int pqGetline2 ( PGconn conn,
char *  s,
int  maxlen 
)

Definition at line 1235 of file fe-protocol2.c.

References pg_conn::asyncStatus, FALSE, pg_conn::inBuffer, pg_conn::inEnd, pg_conn::inStart, PGASYNC_COPY_OUT, PGINVALID_SOCKET, pqReadData(), pqWait(), result, pg_conn::sock, and TRUE.

Referenced by PQgetline().

1236 {
1237  int result = 1; /* return value if buffer overflows */
1238 
1239  if (conn->sock == PGINVALID_SOCKET ||
1240  conn->asyncStatus != PGASYNC_COPY_OUT)
1241  {
1242  *s = '\0';
1243  return EOF;
1244  }
1245 
1246  /*
1247  * Since this is a purely synchronous routine, we don't bother to maintain
1248  * conn->inCursor; there is no need to back up.
1249  */
1250  while (maxlen > 1)
1251  {
1252  if (conn->inStart < conn->inEnd)
1253  {
1254  char c = conn->inBuffer[conn->inStart++];
1255 
1256  if (c == '\n')
1257  {
1258  result = 0; /* success exit */
1259  break;
1260  }
1261  *s++ = c;
1262  maxlen--;
1263  }
1264  else
1265  {
1266  /* need to load more data */
1267  if (pqWait(TRUE, FALSE, conn) ||
1268  pqReadData(conn) < 0)
1269  {
1270  result = EOF;
1271  break;
1272  }
1273  }
1274  }
1275  *s = '\0';
1276 
1277  return result;
1278 }
int inEnd
Definition: libpq-int.h:433
int inStart
Definition: libpq-int.h:431
return result
Definition: formatting.c:1633
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define FALSE
Definition: c.h:221
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
char * c
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:429
#define TRUE
Definition: c.h:217
int pqGetline3 ( PGconn conn,
char *  s,
int  maxlen 
)

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

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

Referenced by PQgetline().

1702 {
1703  int status;
1704 
1705  if (conn->sock == PGINVALID_SOCKET ||
1706  (conn->asyncStatus != PGASYNC_COPY_OUT &&
1707  conn->asyncStatus != PGASYNC_COPY_BOTH) ||
1708  conn->copy_is_binary)
1709  {
1711  libpq_gettext("PQgetline: not doing text COPY OUT\n"));
1712  *s = '\0';
1713  return EOF;
1714  }
1715 
1716  while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1717  {
1718  /* need to load more data */
1719  if (pqWait(TRUE, FALSE, conn) ||
1720  pqReadData(conn) < 0)
1721  {
1722  *s = '\0';
1723  return EOF;
1724  }
1725  }
1726 
1727  if (status < 0)
1728  {
1729  /* End of copy detected; gin up old-style terminator */
1730  strcpy(s, "\\.");
1731  return 0;
1732  }
1733 
1734  /* Add null terminator, and strip trailing \n if present */
1735  if (s[status - 1] == '\n')
1736  {
1737  s[status - 1] = '\0';
1738  return 0;
1739  }
1740  else
1741  {
1742  s[status] = '\0';
1743  return 1;
1744  }
1745 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2469
char copy_is_binary
Definition: libpq-int.h:389
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define FALSE
Definition: c.h:221
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:986
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define TRUE
Definition: c.h:217
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
#define libpq_gettext(x)
Definition: libpq-int.h:682
int pqGetlineAsync2 ( PGconn conn,
char *  buffer,
int  bufsize 
)

Definition at line 1286 of file fe-protocol2.c.

References pg_conn::asyncStatus, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, and PGASYNC_COPY_OUT.

Referenced by PQgetlineAsync().

1287 {
1288  int avail;
1289 
1290  if (conn->asyncStatus != PGASYNC_COPY_OUT)
1291  return -1; /* we are not doing a copy... */
1292 
1293  /*
1294  * Move data from libpq's buffer to the caller's. We want to accept data
1295  * only in units of whole lines, not partial lines. This ensures that we
1296  * can recognize the terminator line "\\.\n". (Otherwise, if it happened
1297  * to cross a packet/buffer boundary, we might hand the first one or two
1298  * characters off to the caller, which we shouldn't.)
1299  */
1300 
1301  conn->inCursor = conn->inStart;
1302 
1303  avail = bufsize;
1304  while (avail > 0 && conn->inCursor < conn->inEnd)
1305  {
1306  char c = conn->inBuffer[conn->inCursor++];
1307 
1308  *buffer++ = c;
1309  --avail;
1310  if (c == '\n')
1311  {
1312  /* Got a complete line; mark the data removed from libpq */
1313  conn->inStart = conn->inCursor;
1314  /* Is it the endmarker line? */
1315  if (bufsize - avail == 3 && buffer[-3] == '\\' && buffer[-2] == '.')
1316  return -1;
1317  /* No, return the data line to the caller */
1318  return bufsize - avail;
1319  }
1320  }
1321 
1322  /*
1323  * We don't have a complete line. We'd prefer to leave it in libpq's
1324  * buffer until the rest arrives, but there is a special case: what if the
1325  * line is longer than the buffer the caller is offering us? In that case
1326  * we'd better hand over a partial line, else we'd get into an infinite
1327  * loop. Do this in a way that ensures we can't misrecognize a terminator
1328  * line later: leave last 3 characters in libpq buffer.
1329  */
1330  if (avail == 0 && bufsize > 3)
1331  {
1332  conn->inStart = conn->inCursor - 3;
1333  return bufsize - 3;
1334  }
1335  return 0;
1336 }
int inEnd
Definition: libpq-int.h:433
int inStart
Definition: libpq-int.h:431
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
char * c
char * inBuffer
Definition: libpq-int.h:429
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
int inCursor
Definition: libpq-int.h:432
int pqGetlineAsync3 ( PGconn conn,
char *  buffer,
int  bufsize 
)

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

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

Referenced by PQgetlineAsync().

1754 {
1755  int msgLength;
1756  int avail;
1757 
1758  if (conn->asyncStatus != PGASYNC_COPY_OUT
1759  && conn->asyncStatus != PGASYNC_COPY_BOTH)
1760  return -1; /* we are not doing a copy... */
1761 
1762  /*
1763  * Recognize the next input message. To make life simpler for async
1764  * callers, we keep returning 0 until the next message is fully available
1765  * even if it is not Copy Data. This should keep PQendcopy from blocking.
1766  * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1767  */
1768  msgLength = getCopyDataMessage(conn);
1769  if (msgLength < 0)
1770  return -1; /* end-of-copy or error */
1771  if (msgLength == 0)
1772  return 0; /* no data yet */
1773 
1774  /*
1775  * Move data from libpq's buffer to the caller's. In the case where a
1776  * prior call found the caller's buffer too small, we use
1777  * conn->copy_already_done to remember how much of the row was already
1778  * returned to the caller.
1779  */
1780  conn->inCursor += conn->copy_already_done;
1781  avail = msgLength - 4 - conn->copy_already_done;
1782  if (avail <= bufsize)
1783  {
1784  /* Able to consume the whole message */
1785  memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1786  /* Mark message consumed */
1787  conn->inStart = conn->inCursor + avail;
1788  /* Reset state for next time */
1789  conn->copy_already_done = 0;
1790  return avail;
1791  }
1792  else
1793  {
1794  /* We must return a partial message */
1795  memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1796  /* The message is NOT consumed from libpq's buffer */
1797  conn->copy_already_done += bufsize;
1798  return bufsize;
1799  }
1800 }
int inStart
Definition: libpq-int.h:431
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
char * inBuffer
Definition: libpq-int.h:429
static int getCopyDataMessage(PGconn *conn)
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
int copy_already_done
Definition: libpq-int.h:390
int inCursor
Definition: libpq-int.h:432
int pqGetnchar ( char *  s,
size_t  len,
PGconn conn 
)

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

References fputnbytes(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, and pg_conn::Pfdebug.

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

198 {
199  if (len > (size_t) (conn->inEnd - conn->inCursor))
200  return EOF;
201 
202  memcpy(s, conn->inBuffer + conn->inCursor, len);
203  /* no terminating null */
204 
205  conn->inCursor += len;
206 
207  if (conn->Pfdebug)
208  {
209  fprintf(conn->Pfdebug, "From backend (%lu)> ", (unsigned long) len);
210  fputnbytes(conn->Pfdebug, s, len);
211  fprintf(conn->Pfdebug, "\n");
212  }
213 
214  return 0;
215 }
int inEnd
Definition: libpq-int.h:433
FILE * Pfdebug
Definition: libpq-int.h:368
char * inBuffer
Definition: libpq-int.h:429
static void fputnbytes(FILE *f, const char *str, size_t n)
Definition: fe-misc.c:81
int inCursor
Definition: libpq-int.h:432
int pqGets ( PQExpBuffer  buf,
PGconn conn 
)

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

References pqGets_internal().

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

166 {
167  return pqGets_internal(buf, conn, true);
168 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:134
int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

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

References pqGets_internal().

Referenced by PQconnectPoll().

172 {
173  return pqGets_internal(buf, conn, false);
174 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:134
void pqHandleSendFailure ( PGconn conn)

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

References parseInput(), and pqReadData().

Referenced by pqFunctionCall2(), pqFunctionCall3(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), and PQsendQueryGuts().

1583 {
1584  /*
1585  * Accept and parse any available input data, ignoring I/O errors. Note
1586  * that if pqReadData decides the backend has closed the channel, it will
1587  * close our side of the socket --- that's just what we want here.
1588  */
1589  while (pqReadData(conn) > 0)
1590  parseInput(conn);
1591 
1592  /*
1593  * Be sure to parse available input messages even if we read no data.
1594  * (Note: calling parseInput within the above loop isn't really necessary,
1595  * but it prevents buffer bloat if there's a lot of data available.)
1596  */
1597  parseInput(conn);
1598 }
int pqReadData(PGconn *conn)
Definition: fe-misc.c:631
static void parseInput(PGconn *conn)
Definition: fe-exec.c:1667
void pqInternalNotice ( const PGNoticeHooks hooks,
const char *  fmt,
  ... 
)
int pqPacketSend ( PGconn conn,
char  pack_type,
const void *  buf,
size_t  buf_len 
)

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

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

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

3977 {
3978  /* Start the message. */
3979  if (pqPutMsgStart(pack_type, true, conn))
3980  return STATUS_ERROR;
3981 
3982  /* Send the message body. */
3983  if (pqPutnchar(buf, buf_len, conn))
3984  return STATUS_ERROR;
3985 
3986  /* Finish the message. */
3987  if (pqPutMsgEnd(conn))
3988  return STATUS_ERROR;
3989 
3990  /* Flush to ensure backend gets it. */
3991  if (pqFlush(conn))
3992  return STATUS_ERROR;
3993 
3994  return STATUS_OK;
3995 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:963
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:521
#define STATUS_ERROR
Definition: c.h:977
static char * buf
Definition: pg_test_fsync.c:66
#define STATUS_OK
Definition: c.h:976
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:248
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:589
void pqParseInput2 ( PGconn conn)

Definition at line 411 of file fe-protocol2.c.

References pg_conn::asyncStatus, pg_conn::be_key, pg_conn::be_pid, checkXactStatus(), pg_result::cmdStatus, CMDSTATUS_LEN, PQExpBufferData::data, pg_conn::errorMessage, FALSE, getAnotherTuple(), getNotify(), getRowDescriptions(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_gettext, pg_conn::noticeHooks, NULL, PGASYNC_BUSY, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, PGRES_COMMAND_OK, PGRES_EMPTY_QUERY, pqGetc(), pqGetErrorNotice2(), pqGetInt(), pqGets(), pqInternalNotice(), PQmakeEmptyPGresult(), pqSaveErrorResult(), printfPQExpBuffer(), pg_conn::result, strlcpy(), TRUE, and pg_conn::workBuffer.

Referenced by parseInput().

412 {
413  char id;
414 
415  /*
416  * Loop to parse successive complete messages available in the buffer.
417  */
418  for (;;)
419  {
420  /*
421  * Quit if in COPY_OUT state: we expect raw data from the server until
422  * PQendcopy is called. Don't try to parse it according to the normal
423  * protocol. (This is bogus. The data lines ought to be part of the
424  * protocol and have identifying leading characters.)
425  */
426  if (conn->asyncStatus == PGASYNC_COPY_OUT)
427  return;
428 
429  /*
430  * OK to try to read a message type code.
431  */
432  conn->inCursor = conn->inStart;
433  if (pqGetc(&id, conn))
434  return;
435 
436  /*
437  * NOTIFY and NOTICE messages can happen in any state besides COPY
438  * OUT; always process them right away.
439  *
440  * Most other messages should only be processed while in BUSY state.
441  * (In particular, in READY state we hold off further parsing until
442  * the application collects the current PGresult.)
443  *
444  * However, if the state is IDLE then we got trouble; we need to deal
445  * with the unexpected message somehow.
446  */
447  if (id == 'A')
448  {
449  if (getNotify(conn))
450  return;
451  }
452  else if (id == 'N')
453  {
454  if (pqGetErrorNotice2(conn, false))
455  return;
456  }
457  else if (conn->asyncStatus != PGASYNC_BUSY)
458  {
459  /* If not IDLE state, just wait ... */
460  if (conn->asyncStatus != PGASYNC_IDLE)
461  return;
462 
463  /*
464  * Unexpected message in IDLE state; need to recover somehow.
465  * ERROR messages are displayed using the notice processor;
466  * anything else is just dropped on the floor after displaying a
467  * suitable warning notice. (An ERROR is very possibly the
468  * backend telling us why it is about to close the connection, so
469  * we don't want to just discard it...)
470  */
471  if (id == 'E')
472  {
473  if (pqGetErrorNotice2(conn, false /* treat as notice */ ))
474  return;
475  }
476  else
477  {
479  "message type 0x%02x arrived from server while idle",
480  id);
481  /* Discard the unexpected message; good idea?? */
482  conn->inStart = conn->inEnd;
483  break;
484  }
485  }
486  else
487  {
488  /*
489  * In BUSY state, we can process everything.
490  */
491  switch (id)
492  {
493  case 'C': /* command complete */
494  if (pqGets(&conn->workBuffer, conn))
495  return;
496  if (conn->result == NULL)
497  {
498  conn->result = PQmakeEmptyPGresult(conn,
500  if (!conn->result)
501  {
503  libpq_gettext("out of memory"));
504  pqSaveErrorResult(conn);
505  }
506  }
507  if (conn->result)
508  {
509  strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
510  CMDSTATUS_LEN);
511  }
512  checkXactStatus(conn, conn->workBuffer.data);
513  conn->asyncStatus = PGASYNC_READY;
514  break;
515  case 'E': /* error return */
516  if (pqGetErrorNotice2(conn, true))
517  return;
518  conn->asyncStatus = PGASYNC_READY;
519  break;
520  case 'Z': /* backend is ready for new query */
521  conn->asyncStatus = PGASYNC_IDLE;
522  break;
523  case 'I': /* empty query */
524  /* read and throw away the closing '\0' */
525  if (pqGetc(&id, conn))
526  return;
527  if (id != '\0')
529  "unexpected character %c following empty query response (\"I\" message)",
530  id);
531  if (conn->result == NULL)
532  {
533  conn->result = PQmakeEmptyPGresult(conn,
535  if (!conn->result)
536  {
538  libpq_gettext("out of memory"));
539  pqSaveErrorResult(conn);
540  }
541  }
542  conn->asyncStatus = PGASYNC_READY;
543  break;
544  case 'K': /* secret key data from the backend */
545 
546  /*
547  * This is expected only during backend startup, but it's
548  * just as easy to handle it as part of the main loop.
549  * Save the data and continue processing.
550  */
551  if (pqGetInt(&(conn->be_pid), 4, conn))
552  return;
553  if (pqGetInt(&(conn->be_key), 4, conn))
554  return;
555  break;
556  case 'P': /* synchronous (normal) portal */
557  if (pqGets(&conn->workBuffer, conn))
558  return;
559  /* We pretty much ignore this message type... */
560  break;
561  case 'T': /* row descriptions (start of query results) */
562  if (conn->result == NULL)
563  {
564  /* First 'T' in a query sequence */
565  if (getRowDescriptions(conn))
566  return;
567  /* getRowDescriptions() moves inStart itself */
568  continue;
569  }
570  else
571  {
572  /*
573  * A new 'T' message is treated as the start of
574  * another PGresult. (It is not clear that this is
575  * really possible with the current backend.) We stop
576  * parsing until the application accepts the current
577  * result.
578  */
579  conn->asyncStatus = PGASYNC_READY;
580  return;
581  }
582  break;
583  case 'D': /* ASCII data tuple */
584  if (conn->result != NULL)
585  {
586  /* Read another tuple of a normal query response */
587  if (getAnotherTuple(conn, FALSE))
588  return;
589  /* getAnotherTuple() moves inStart itself */
590  continue;
591  }
592  else
593  {
595  "server sent data (\"D\" message) without prior row description (\"T\" message)");
596  /* Discard the unexpected message; good idea?? */
597  conn->inStart = conn->inEnd;
598  return;
599  }
600  break;
601  case 'B': /* Binary data tuple */
602  if (conn->result != NULL)
603  {
604  /* Read another tuple of a normal query response */
605  if (getAnotherTuple(conn, TRUE))
606  return;
607  /* getAnotherTuple() moves inStart itself */
608  continue;
609  }
610  else
611  {
613  "server sent binary data (\"B\" message) without prior row description (\"T\" message)");
614  /* Discard the unexpected message; good idea?? */
615  conn->inStart = conn->inEnd;
616  return;
617  }
618  break;
619  case 'G': /* Start Copy In */
621  break;
622  case 'H': /* Start Copy Out */
624  break;
625 
626  /*
627  * Don't need to process CopyBothResponse here because it
628  * never arrives from the server during protocol 2.0.
629  */
630  default:
633  "unexpected response from server; first received character was \"%c\"\n"),
634  id);
635  /* build an error result holding the error message */
636  pqSaveErrorResult(conn);
637  /* Discard the unexpected message; good idea?? */
638  conn->inStart = conn->inEnd;
639  conn->asyncStatus = PGASYNC_READY;
640  return;
641  } /* switch on protocol character */
642  }
643  /* Successfully consumed this message */
644  conn->inStart = conn->inCursor;
645  }
646 }
static void checkXactStatus(PGconn *conn, const char *cmdTag)
int inEnd
Definition: libpq-int.h:433
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:431
static int getRowDescriptions(PGconn *conn)
Definition: fe-protocol2.c:659
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:165
PQExpBufferData workBuffer
Definition: libpq-int.h:494
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:269
#define CMDSTATUS_LEN
Definition: libpq-int.h:86
PGresult * result
Definition: libpq-int.h:450
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define FALSE
Definition: c.h:221
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
static int getAnotherTuple(PGconn *conn, bool binary)
Definition: fe-protocol2.c:790
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:96
static int getNotify(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:491
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:178
int be_key
Definition: libpq-int.h:420
#define TRUE
Definition: c.h:217
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:432
int be_pid
Definition: libpq-int.h:419
#define libpq_gettext(x)
Definition: libpq-int.h:682
static int pqGetErrorNotice2(PGconn *conn, bool isError)
Definition: fe-protocol2.c:963
void pqParseInput3 ( PGconn conn)

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

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

Referenced by parseInput().

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

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

References appendPQExpBufferStr(), pg_conn::errorMessage, pg_conn::next_result, NULL, PGRES_FATAL_ERROR, PQmakeEmptyPGresult(), PQresultErrorMessage(), resetPQExpBuffer(), and pg_conn::result.

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

757 {
758  PGresult *res;
759 
760  /*
761  * conn->result is the PGresult to return. If it is NULL (which probably
762  * shouldn't happen) we assume there is an appropriate error message in
763  * conn->errorMessage.
764  */
765  res = conn->result;
766  if (!res)
768  else
769  {
770  /*
771  * Make sure PQerrorMessage agrees with result; it could be different
772  * if we have concatenated messages.
773  */
776  PQresultErrorMessage(res));
777  }
778 
779  /*
780  * Replace conn->result with next_result, if any. In the normal case
781  * there isn't a next result and we're just dropping ownership of the
782  * current result. In single-row mode this restores the situation to what
783  * it was before we created the current single-row result.
784  */
785  conn->result = conn->next_result;
786  conn->next_result = NULL;
787 
788  return res;
789 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
PGresult * result
Definition: libpq-int.h:450
PGresult * next_result
Definition: libpq-int.h:451
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:2612
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
int pqPutc ( char  c,
PGconn conn 
)

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

References pg_conn::Pfdebug, and pqPutMsgBytes().

Referenced by PQsendDescribe(), and PQsendQueryGuts().

115 {
116  if (pqPutMsgBytes(&c, 1, conn))
117  return EOF;
118 
119  if (conn->Pfdebug)
120  fprintf(conn->Pfdebug, "To backend> %c\n", c);
121 
122  return 0;
123 }
FILE * Pfdebug
Definition: libpq-int.h:368
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:566
char * c
int pqPutInt ( int  value,
size_t  bytes,
PGconn conn 
)

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

References pg_conn::noticeHooks, pg_conn::Pfdebug, pqInternalNotice(), and pqPutMsgBytes().

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

310 {
311  uint16 tmp2;
312  uint32 tmp4;
313 
314  switch (bytes)
315  {
316  case 2:
317  tmp2 = htons((uint16) value);
318  if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
319  return EOF;
320  break;
321  case 4:
322  tmp4 = htonl((uint32) value);
323  if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
324  return EOF;
325  break;
326  default:
328  "integer of size %lu not supported by pqPutInt",
329  (unsigned long) bytes);
330  return EOF;
331  }
332 
333  if (conn->Pfdebug)
334  fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
335 
336  return 0;
337 }
FILE * Pfdebug
Definition: libpq-int.h:368
unsigned short uint16
Definition: c.h:267
static struct @121 value
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:566
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
unsigned int uint32
Definition: c.h:268
int pqPutMsgEnd ( PGconn conn)

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

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

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall2(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), and sendTerminateConn().

590 {
591  if (conn->Pfdebug)
592  fprintf(conn->Pfdebug, "To backend> Msg complete, length %u\n",
593  conn->outMsgEnd - conn->outCount);
594 
595  /* Fill in length word if needed */
596  if (conn->outMsgStart >= 0)
597  {
598  uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
599 
600  msgLen = htonl(msgLen);
601  memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
602  }
603 
604  /* Make message eligible to send */
605  conn->outCount = conn->outMsgEnd;
606 
607  if (conn->outCount >= 8192)
608  {
609  int toSend = conn->outCount - (conn->outCount % 8192);
610 
611  if (pqSendSome(conn, toSend) < 0)
612  return EOF;
613  /* in nonblock mode, don't complain if unable to send it all */
614  }
615 
616  return 0;
617 }
int outCount
Definition: libpq-int.h:438
int outMsgEnd
Definition: libpq-int.h:443
FILE * Pfdebug
Definition: libpq-int.h:368
unsigned int uint32
Definition: c.h:268
int outMsgStart
Definition: libpq-int.h:441
char * outBuffer
Definition: libpq-int.h:436
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:831
int pqPutMsgStart ( char  msg_type,
bool  force_len,
PGconn conn 
)

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

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

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall2(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), and sendTerminateConn().

522 {
523  int lenPos;
524  int endPos;
525 
526  /* allow room for message type byte */
527  if (msg_type)
528  endPos = conn->outCount + 1;
529  else
530  endPos = conn->outCount;
531 
532  /* do we want a length word? */
533  if (force_len || PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
534  {
535  lenPos = endPos;
536  /* allow room for message length */
537  endPos += 4;
538  }
539  else
540  lenPos = -1;
541 
542  /* make sure there is room for message header */
543  if (pqCheckOutBufferSpace(endPos, conn))
544  return EOF;
545  /* okay, save the message type byte if any */
546  if (msg_type)
547  conn->outBuffer[conn->outCount] = msg_type;
548  /* set up the message pointers */
549  conn->outMsgStart = lenPos;
550  conn->outMsgEnd = endPos;
551  /* length word, if needed, will be filled in by pqPutMsgEnd */
552 
553  if (conn->Pfdebug)
554  fprintf(conn->Pfdebug, "To backend> Msg %c\n",
555  msg_type ? msg_type : ' ');
556 
557  return 0;
558 }
int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:346
int outCount
Definition: libpq-int.h:438
int outMsgEnd
Definition: libpq-int.h:443
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
FILE * Pfdebug
Definition: libpq-int.h:368
int outMsgStart
Definition: libpq-int.h:441
ProtocolVersion pversion
Definition: libpq-int.h:404
char * outBuffer
Definition: libpq-int.h:436
int pqPutnchar ( const char *  s,
size_t  len,
PGconn conn 
)

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

References fputnbytes(), pg_conn::Pfdebug, and pqPutMsgBytes().

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

249 {
250  if (pqPutMsgBytes(s, len, conn))
251  return EOF;
252 
253  if (conn->Pfdebug)
254  {
255  fprintf(conn->Pfdebug, "To backend> ");
256  fputnbytes(conn->Pfdebug, s, len);
257  fprintf(conn->Pfdebug, "\n");
258  }
259 
260  return 0;
261 }
FILE * Pfdebug
Definition: libpq-int.h:368
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:566
static void fputnbytes(FILE *f, const char *str, size_t n)
Definition: fe-misc.c:81
int pqPuts ( const char *  s,
PGconn conn 
)

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

References pg_conn::Pfdebug, and pqPutMsgBytes().

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

182 {
183  if (pqPutMsgBytes(s, strlen(s) + 1, conn))
184  return EOF;
185 
186  if (conn->Pfdebug)
187  fprintf(conn->Pfdebug, "To backend> \"%s\"\n", s);
188 
189  return 0;
190 }
FILE * Pfdebug
Definition: libpq-int.h:368
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:566
int pqReadData ( PGconn conn)

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

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

Referenced by PQconnectPoll(), PQconsumeInput(), pqFunctionCall2(), pqFunctionCall3(), pqGetCopyData2(), pqGetCopyData3(), pqGetline2(), pqGetline3(), PQgetResult(), pqHandleSendFailure(), pqSendSome(), and pqSetenvPoll().

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

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

References pqSocketCheck().

Referenced by pqReadData().

1024 {
1025  return pqSocketCheck(conn, 1, 0, (time_t) 0);
1026 }
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
Definition: fe-misc.c:1047
void* pqResultAlloc ( PGresult res,
size_t  nBytes,
bool  isBinary 
)

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

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

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

507 {
508  char *space;
509  PGresult_data *block;
510 
511  if (!res)
512  return NULL;
513 
514  if (nBytes <= 0)
515  return res->null_field;
516 
517  /*
518  * If alignment is needed, round up the current position to an alignment
519  * boundary.
520  */
521  if (isBinary)
522  {
523  int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
524 
525  if (offset)
526  {
527  res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
528  res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
529  }
530  }
531 
532  /* If there's enough space in the current block, no problem. */
533  if (nBytes <= (size_t) res->spaceLeft)
534  {
535  space = res->curBlock->space + res->curOffset;
536  res->curOffset += nBytes;
537  res->spaceLeft -= nBytes;
538  return space;
539  }
540 
541  /*
542  * If the requested object is very large, give it its own block; this
543  * avoids wasting what might be most of the current block to start a new
544  * block. (We'd have to special-case requests bigger than the block size
545  * anyway.) The object is always given binary alignment in this case.
546  */
547  if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
548  {
549  block = (PGresult_data *) malloc(nBytes + PGRESULT_BLOCK_OVERHEAD);
550  if (!block)
551  return NULL;
552  space = block->space + PGRESULT_BLOCK_OVERHEAD;
553  if (res->curBlock)
554  {
555  /*
556  * Tuck special block below the active block, so that we don't
557  * have to waste the free space in the active block.
558  */
559  block->next = res->curBlock->next;
560  res->curBlock->next = block;
561  }
562  else
563  {
564  /* Must set up the new block as the first active block. */
565  block->next = NULL;
566  res->curBlock = block;
567  res->spaceLeft = 0; /* be sure it's marked full */
568  }
569  return space;
570  }
571 
572  /* Otherwise, start a new block. */
574  if (!block)
575  return NULL;
576  block->next = res->curBlock;
577  res->curBlock = block;
578  if (isBinary)
579  {
580  /* object needs full alignment */
583  }
584  else
585  {
586  /* we can cram it right after the overhead pointer */
587  res->curOffset = sizeof(PGresult_data);
589  }
590 
591  space = block->space + res->curOffset;
592  res->curOffset += nBytes;
593  res->spaceLeft -= nBytes;
594  return space;
595 }
char space[1]
Definition: libpq-int.h:106
PGresult_data * next
Definition: libpq-int.h:105
union pgresult_data PGresult_data
Definition: libpq-int.h:101
int spaceLeft
Definition: libpq-int.h:210
char null_field[1]
Definition: libpq-int.h:201
#define malloc(a)
Definition: header.h:50
#define PGRESULT_ALIGN_BOUNDARY
Definition: fe-exec.c:128
int curOffset
Definition: libpq-int.h:209
#define PGRESULT_BLOCK_OVERHEAD
Definition: fe-exec.c:129
PGresult_data * curBlock
Definition: libpq-int.h:208
#define PGRESULT_SEP_ALLOC_THRESHOLD
Definition: fe-exec.c:130
#define NULL
Definition: c.h:229
#define PGRESULT_DATA_BLOCKSIZE
Definition: fe-exec.c:127
char* pqResultStrdup ( PGresult res,
const char *  str 
)

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

References FALSE, and pqResultAlloc().

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

603 {
604  char *space = (char *) pqResultAlloc(res, strlen(str) + 1, FALSE);
605 
606  if (space)
607  strcpy(space, str);
608  return space;
609 }
#define FALSE
Definition: c.h:221
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:506
int pqRowProcessor ( PGconn conn,
const char **  errmsgp 
)

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

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

Referenced by getAnotherTuple().

1031 {
1032  PGresult *res = conn->result;
1033  int nfields = res->numAttributes;
1034  const PGdataValue *columns = conn->rowBuf;
1035  PGresAttValue *tup;
1036  int i;
1037 
1038  /*
1039  * In single-row mode, make a new PGresult that will hold just this one
1040  * row; the original conn->result is left unchanged so that it can be used
1041  * again as the template for future rows.
1042  */
1043  if (conn->singleRowMode)
1044  {
1045  /* Copy everything that should be in the result at this point */
1046  res = PQcopyResult(res,
1049  if (!res)
1050  return 0;
1051  }
1052 
1053  /*
1054  * Basically we just allocate space in the PGresult for each field and
1055  * copy the data over.
1056  *
1057  * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1058  * caller will take to mean "out of memory". This is preferable to trying
1059  * to set up such a message here, because evidently there's not enough
1060  * memory for gettext() to do anything.
1061  */
1062  tup = (PGresAttValue *)
1063  pqResultAlloc(res, nfields * sizeof(PGresAttValue), TRUE);
1064  if (tup == NULL)
1065  goto fail;
1066 
1067  for (i = 0; i < nfields; i++)
1068  {
1069  int clen = columns[i].len;
1070 
1071  if (clen < 0)
1072  {
1073  /* null field */
1074  tup[i].len = NULL_LEN;
1075  tup[i].value = res->null_field;
1076  }
1077  else
1078  {
1079  bool isbinary = (res->attDescs[i].format != 0);
1080  char *val;
1081 
1082  val = (char *) pqResultAlloc(res, clen + 1, isbinary);
1083  if (val == NULL)
1084  goto fail;
1085 
1086  /* copy and zero-terminate the data (even if it's binary) */
1087  memcpy(val, columns[i].value, clen);
1088  val[clen] = '\0';
1089 
1090  tup[i].len = clen;
1091  tup[i].value = val;
1092  }
1093  }
1094 
1095  /* And add the tuple to the PGresult's tuple array */
1096  if (!pqAddTuple(res, tup))
1097  goto fail;
1098 
1099  /*
1100  * Success. In single-row mode, make the result available to the client
1101  * immediately.
1102  */
1103  if (conn->singleRowMode)
1104  {
1105  /* Change result status to special single-row value */
1107  /* Stash old result for re-use later */
1108  conn->next_result = conn->result;
1109  conn->result = res;
1110  /* And mark the result ready to return */
1111  conn->asyncStatus = PGASYNC_READY;
1112  }
1113 
1114  return 1;
1115 
1116 fail:
1117  /* release locally allocated PGresult, if we made one */
1118  if (res != conn->result)
1119  PQclear(res);
1120  return 0;
1121 }
bool singleRowMode
Definition: libpq-int.h:388
static bool pqAddTuple(PGresult *res, PGresAttValue *tup)
Definition: fe-exec.c:853
PGresult * PQcopyResult(const PGresult *src, int flags)
Definition: fe-exec.c:291
#define NULL_LEN
Definition: libpq-int.h:133
char null_field[1]
Definition: libpq-int.h:201
PGresAttDesc * attDescs
Definition: libpq-int.h:171
PGresult * result
Definition: libpq-int.h:450
PGresult * next_result
Definition: libpq-int.h:451
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:36
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:37
static struct @121 value
PGdataValue * rowBuf
Definition: libpq-int.h:446
int numAttributes
Definition: libpq-int.h:170
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:34
void PQclear(PGresult *res)
Definition: fe-exec.c:650
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:506
#define NULL
Definition: c.h:229
int i
char * value
Definition: libpq-int.h:138
#define TRUE
Definition: c.h:217
ExecStatusType resultStatus
Definition: libpq-int.h:177
long val
Definition: informix.c:689
void pqSaveErrorResult ( PGconn conn)

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

References PQExpBufferData::data, pg_result::errMsg, pg_conn::errorMessage, NULL, PGRES_FATAL_ERROR, pqCatenateResultError(), pqClearAsyncResult(), PQmakeEmptyPGresult(), pg_conn::result, and pg_result::resultStatus.

Referenced by getAnotherTuple(), getCopyResult(), getParamDescriptions(), getRowDescriptions(), handleSyncLoss(), pqFunctionCall2(), pqFunctionCall3(), PQgetResult(), pqParseInput2(), and pqParseInput3().

729 {
730  /*
731  * If no old async result, just let PQmakeEmptyPGresult make one. Likewise
732  * if old result is not an error message.
733  */
734  if (conn->result == NULL ||
736  conn->result->errMsg == NULL)
737  {
738  pqClearAsyncResult(conn);
740  }
741  else
742  {
743  /* Else, concatenate error message to existing async result. */
745  }
746 }
char * errMsg
Definition: libpq-int.h:196
PGresult * result
Definition: libpq-int.h:450
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
void pqCatenateResultError(PGresult *res, const char *msg)
Definition: fe-exec.c:631
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:705
ExecStatusType resultStatus
Definition: libpq-int.h:177
void void pqSaveMessageField ( PGresult res,
char  code,
const char *  value 
)

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

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

Referenced by pqGetErrorNotice2(), pqGetErrorNotice3(), and pqInternalNotice().

892 {
893  PGMessageField *pfield;
894 
895  pfield = (PGMessageField *)
896  pqResultAlloc(res,
897  offsetof(PGMessageField, contents) +
898  strlen(value) + 1,
899  TRUE);
900  if (!pfield)
901  return; /* out of memory? */
902  pfield->code = code;
903  strcpy(pfield->contents, value);
904  pfield->next = res->errFields;
905  res->errFields = pfield;
906 }
PGMessageField * errFields
Definition: libpq-int.h:197
struct pgMessageField * next
Definition: libpq-int.h:144
static struct @121 value
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:506
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:146
#define TRUE
Definition: c.h:217
#define offsetof(type, field)
Definition: c.h:555
void pqSaveParameterStatus ( PGconn conn,
const char *  name,
const char *  value 
)

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

References pg_conn::client_encoding, free, malloc, pgParameterStatus::name, pgParameterStatus::next, NULL, pg_conn::Pfdebug, pg_char_to_encoding(), PG_SQL_ASCII, pg_conn::pstatus, static_client_encoding, static_std_strings, pg_conn::std_strings, pg_conn::sversion, and pgParameterStatus::value.

Referenced by getParameterStatus(), PQsetClientEncoding(), and pqSetenvPoll().

913 {
914  pgParameterStatus *pstatus;
915  pgParameterStatus *prev;
916 
917  if (conn->Pfdebug)
918  fprintf(conn->Pfdebug, "pqSaveParameterStatus: '%s' = '%s'\n",
919  name, value);
920 
921  /*
922  * Forget any old information about the parameter
923  */
924  for (pstatus = conn->pstatus, prev = NULL;
925  pstatus != NULL;
926  prev = pstatus, pstatus = pstatus->next)
927  {
928  if (strcmp(pstatus->name, name) == 0)
929  {
930  if (prev)
931  prev->next = pstatus->next;
932  else
933  conn->pstatus = pstatus->next;
934  free(pstatus); /* frees name and value strings too */
935  break;
936  }
937  }
938 
939  /*
940  * Store new info as a single malloc block
941  */
942  pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
943  strlen(name) + strlen(value) + 2);
944  if (pstatus)
945  {
946  char *ptr;
947 
948  ptr = ((char *) pstatus) + sizeof(pgParameterStatus);
949  pstatus->name = ptr;
950  strcpy(ptr, name);
951  ptr += strlen(name) + 1;
952  pstatus->value = ptr;
953  strcpy(ptr, value);
954  pstatus->next = conn->pstatus;
955  conn->pstatus = pstatus;
956  }
957 
958  /*
959  * Special hacks: remember client_encoding and
960  * standard_conforming_strings, and convert server version to a numeric
961  * form. We keep the first two of these in static variables as well, so
962  * that PQescapeString and PQescapeBytea can behave somewhat sanely (at
963  * least in single-connection-using programs).
964  */
965  if (strcmp(name, "client_encoding") == 0)
966  {
968  /* if we don't recognize the encoding name, fall back to SQL_ASCII */
969  if (conn->client_encoding < 0)
972  }
973  else if (strcmp(name, "standard_conforming_strings") == 0)
974  {
975  conn->std_strings = (strcmp(value, "on") == 0);
977  }
978  else if (strcmp(name, "server_version") == 0)
979  {
980  int cnt;
981  int vmaj,
982  vmin,
983  vrev;
984 
985  cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);
986 
987  if (cnt == 3)
988  {
989  /* old style, e.g. 9.6.1 */
990  conn->sversion = (100 * vmaj + vmin) * 100 + vrev;
991  }
992  else if (cnt == 2)
993  {
994  if (vmaj >= 10)
995  {
996  /* new style, e.g. 10.1 */
997  conn->sversion = 100 * 100 * vmaj + vmin;
998  }
999  else
1000  {
1001  /* old style without minor version, e.g. 9.6devel */
1002  conn->sversion = (100 * vmaj + vmin) * 100;
1003  }
1004  }
1005  else if (cnt == 1)
1006  {
1007  /* new style without minor version, e.g. 10devel */
1008  conn->sversion = 100 * 100 * vmaj;
1009  }
1010  else
1011  conn->sversion = 0; /* unknown */
1012  }
1013 }
static bool static_std_strings
Definition: fe-exec.c:50
int pg_char_to_encoding(const char *name)
Definition: encnames.c:551
FILE * Pfdebug
Definition: libpq-int.h:368
#define malloc(a)
Definition: header.h:50
int sversion
Definition: libpq-int.h:405
struct pgParameterStatus pgParameterStatus
static struct @121 value
static int static_client_encoding
Definition: fe-exec.c:49
pgParameterStatus * pstatus
Definition: libpq-int.h:421
bool std_strings
Definition: libpq-int.h:423
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
struct pgParameterStatus * next
Definition: libpq-int.h:258
const char * name
Definition: encode.c:521
int client_encoding
Definition: libpq-int.h:422
void pqsecure_close ( PGconn )

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

References pgtls_close().

Referenced by pqDropConnection().

190 {
191 #ifdef USE_SSL
192  if (conn->ssl_in_use)
193  pgtls_close(conn);
194 #endif
195 }
PGconn * conn
Definition: streamutil.c:43
void pgtls_close(PGconn *conn)
void pqsecure_destroy ( void  )
int pqsecure_initialize ( PGconn )

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

References pgtls_init().

Referenced by PQconnectPoll().

161 {
162  int r = 0;
163 
164 #ifdef USE_SSL
165  r = pgtls_init(conn);
166 #endif
167 
168  return r;
169 }
PGconn * conn
Definition: streamutil.c:43
int pgtls_init(PGconn *conn)
PostgresPollingStatusType pqsecure_open_client ( PGconn )

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

References PGRES_POLLING_FAILED, and pgtls_open_client().

Referenced by PQconnectPoll().

176 {
177 #ifdef USE_SSL
178  return pgtls_open_client(conn);
179 #else
180  /* shouldn't get here */
181  return PGRES_POLLING_FAILED;
182 #endif
183 }
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
PGconn * conn
Definition: streamutil.c:43
ssize_t pqsecure_raw_read ( PGconn ,
void *  ptr,
size_t  len 
)

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

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

Referenced by my_sock_read(), and pqsecure_read().

225 {
226  ssize_t n;
227  int result_errno = 0;
228  char sebuf[256];
229 
230  n = recv(conn->sock, ptr, len, 0);
231 
232  if (n < 0)
233  {
234  result_errno = SOCK_ERRNO;
235 
236  /* Set error message if appropriate */
237  switch (result_errno)
238  {
239 #ifdef EAGAIN
240  case EAGAIN:
241 #endif
242 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
243  case EWOULDBLOCK:
244 #endif
245  case EINTR:
246  /* no error message, caller is expected to retry */
247  break;
248 
249 #ifdef ECONNRESET
250  case ECONNRESET:
253  "server closed the connection unexpectedly\n"
254  "\tThis probably means the server terminated abnormally\n"
255  "\tbefore or while processing the request.\n"));
256  break;
257 #endif
258 
259  default:
261  libpq_gettext("could not receive data from server: %s\n"),
262  SOCK_STRERROR(result_errno,
263  sebuf, sizeof(sebuf)));
264  break;
265  }
266  }
267 
268  /* ensure we return the intended errno to caller */
269  SOCK_ERRNO_SET(result_errno);
270 
271  return n;
272 }
#define EWOULDBLOCK
Definition: win32.h:291
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define recv(s, buf, len, flags)
Definition: win32.h:375
#define ECONNRESET
Definition: win32.h:295
#define EAGAIN
Definition: win32.h:283
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define SOCK_ERRNO
Definition: libpq-int.h:695
PGconn * conn
Definition: streamutil.c:43
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:697
pgsocket sock
Definition: libpq-int.h:400
#define EINTR
Definition: win32.h:285
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define libpq_gettext(x)
Definition: libpq-int.h:682
ssize_t pqsecure_raw_write ( PGconn ,
const void *  ptr,
size_t  len 
)

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

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

Referenced by my_sock_write(), and pqsecure_write().

302 {
303  ssize_t n;
304  int flags = 0;
305  int result_errno = 0;
306  char sebuf[256];
307 
308  DECLARE_SIGPIPE_INFO(spinfo);
309 
310 #ifdef MSG_NOSIGNAL
311  if (conn->sigpipe_flag)
312  flags |= MSG_NOSIGNAL;
313 
314 retry_masked:
315 #endif /* MSG_NOSIGNAL */
316 
317  DISABLE_SIGPIPE(conn, spinfo, return -1);
318 
319  n = send(conn->sock, ptr, len, flags);
320 
321  if (n < 0)
322  {
323  result_errno = SOCK_ERRNO;
324 
325  /*
326  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
327  * on this machine. So, clear sigpipe_flag so we don't try the flag
328  * again, and retry the send().
329  */
330 #ifdef MSG_NOSIGNAL
331  if (flags != 0 && result_errno == EINVAL)
332  {
333  conn->sigpipe_flag = false;
334  flags = 0;
335  goto retry_masked;
336  }
337 #endif /* MSG_NOSIGNAL */
338 
339  /* Set error message if appropriate */
340  switch (result_errno)
341  {
342 #ifdef EAGAIN
343  case EAGAIN:
344 #endif
345 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
346  case EWOULDBLOCK:
347 #endif
348  case EINTR:
349  /* no error message, caller is expected to retry */
350  break;
351 
352  case EPIPE:
353  /* Set flag for EPIPE */
354  REMEMBER_EPIPE(spinfo, true);
355  /* FALL THRU */
356 
357 #ifdef ECONNRESET
358  case ECONNRESET:
359 #endif
362  "server closed the connection unexpectedly\n"
363  "\tThis probably means the server terminated abnormally\n"
364  "\tbefore or while processing the request.\n"));
365  break;
366 
367  default:
369  libpq_gettext("could not send data to server: %s\n"),
370  SOCK_STRERROR(result_errno,
371  sebuf, sizeof(sebuf)));
372  break;
373  }
374  }
375 
376  RESTORE_SIGPIPE(conn, spinfo);
377 
378  /* ensure we return the intended errno to caller */
379  SOCK_ERRNO_SET(result_errno);
380 
381  return n;
382 }
#define send(s, buf, len, flags)
Definition: win32.h:376
#define EWOULDBLOCK
Definition: win32.h:291
bool sigpipe_flag
Definition: libpq-int.h:410
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:103
#define ECONNRESET
Definition: win32.h:295
#define EAGAIN
Definition: win32.h:283
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define SOCK_ERRNO
Definition: libpq-int.h:695
PGconn * conn
Definition: streamutil.c:43
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:113
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:697
pgsocket sock
Definition: libpq-int.h:400
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:111
#define EINTR
Definition: win32.h:285
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:105
#define libpq_gettext(x)
Definition: libpq-int.h:682
ssize_t pqsecure_read ( PGconn ,
void *  ptr,
size_t  len 
)

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

References pgtls_read(), and pqsecure_raw_read().

Referenced by pqReadData().

206 {
207  ssize_t n;
208 
209 #ifdef USE_SSL
210  if (conn->ssl_in_use)
211  {
212  n =