PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
libpq-int.h File Reference
#include "postgres_fe.h"
#include "libpq-events.h"
#include <time.h>
#include <sys/types.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 88 of file libpq-int.h.

Referenced by pqParseInput2(), and pqParseInput3().

#define libpq_gettext (   x)    (x)

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

Referenced by 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_sendauth(), pg_local_sendauth(), pg_password_sendauth(), pgpassfileWarning(), pgtls_read(), pgtls_write(), pqBuildErrorMessage3(), PQconnectPoll(), PQdisplayTuples(), 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(), 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 690 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 135 of file libpq-int.h.

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

#define pglock_thread ( )    ((void) 0)

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

Referenced by pg_fe_getauthname(), and pg_fe_sendauth().

#define pgunlock_thread ( )    ((void) 0)

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

Referenced by pg_fe_getauthname(), and pg_fe_sendauth().

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

Typedef Documentation

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

Enumeration Type Documentation

Enumerator
CHT_HOST_NAME 
CHT_HOST_ADDRESS 
CHT_UNIX_SOCKET 

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

Enumerator
PGASYNC_IDLE 
PGASYNC_BUSY 
PGASYNC_READY 
PGASYNC_COPY_IN 
PGASYNC_COPY_OUT 
PGASYNC_COPY_BOTH 

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

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

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

228 {
229  PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
230  PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
231  PGQUERY_PREPARE, /* Parse only (PQprepare) */
232  PGQUERY_DESCRIBE /* Describe Statement or Portal */
233 } PGQueryClass;
PGQueryClass
Definition: libpq-int.h:227
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 237 of file libpq-int.h.

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

Function Documentation

void pgtls_close ( PGconn conn)

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

References destroy_ssl_system(), and NULL.

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

1386 {
1387  bool destroy_needed = false;
1388 
1389  if (conn->ssl)
1390  {
1391  /*
1392  * We can't destroy everything SSL-related here due to the possible
1393  * later calls to OpenSSL routines which may need our thread
1394  * callbacks, so set a flag here and check at the end.
1395  */
1396  destroy_needed = true;
1397 
1398  SSL_shutdown(conn->ssl);
1399  SSL_free(conn->ssl);
1400  conn->ssl = NULL;
1401  conn->ssl_in_use = false;
1402  }
1403 
1404  if (conn->peer)
1405  {
1406  X509_free(conn->peer);
1407  conn->peer = NULL;
1408  }
1409 
1410 #ifdef USE_SSL_ENGINE
1411  if (conn->engine)
1412  {
1413  ENGINE_finish(conn->engine);
1414  ENGINE_free(conn->engine);
1415  conn->engine = NULL;
1416  }
1417 #endif
1418 
1419  /*
1420  * This will remove our SSL locking hooks, if this is the last SSL
1421  * connection, which means we must wait to call it until after all SSL
1422  * calls have been made, otherwise we can end up with a race condition and
1423  * possible deadlocks.
1424  *
1425  * See comments above destroy_ssl_system().
1426  */
1427  if (destroy_needed)
1429 }
#define NULL
Definition: c.h:226
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:36
#define malloc(a)
Definition: header.h:45
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:46
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:55
static bool pq_init_crypto_lib
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
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 certificate,
133  * 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:226
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:305
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define SOCK_ERRNO
Definition: libpq-int.h:702
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
static void SSLerrfree(char *buf)
PQExpBufferData errorMessage
Definition: libpq-int.h:498
static char * SSLerrmessage(unsigned long ecode)
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:305
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define SOCK_ERRNO
Definition: libpq-int.h:702
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
static void SSLerrfree(char *buf)
PQExpBufferData errorMessage
Definition: libpq-int.h:498
static char * SSLerrmessage(unsigned long ecode)
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:199
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:54
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:61
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:55
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:63
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:62
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:67
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:58
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:53
char * errMsg
Definition: libpq-int.h:198
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:66
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:51
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:57
char * errQuery
Definition: libpq-int.h:200
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:64
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:59
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:56
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define NULL
Definition: c.h:226
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:68
ExecStatusType resultStatus
Definition: libpq-int.h:179
long val
Definition: informix.c:689
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:60
#define libpq_gettext(x)
Definition: libpq-int.h:689
int client_encoding
Definition: libpq-int.h:191
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:342
#define MemSet(start, val, len)
Definition: c.h:852
#define SM_USER
Definition: pqcomm.h:134
char options[SM_OPTIONS]
Definition: pqcomm.h:147
#define malloc(a)
Definition: header.h:45
#define SM_TTY
Definition: pqcomm.h:139
char * pguser
Definition: libpq-int.h:344
char database[SM_DATABASE]
Definition: pqcomm.h:144
#define NULL
Definition: c.h:226
char * pgoptions
Definition: libpq-int.h:339
ProtocolVersion pversion
Definition: libpq-int.h:406
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:335
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:45
#define NULL
Definition: c.h:226
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:198
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 413 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().

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

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

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

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

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

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

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

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

411 {
412  /* Drop any SSL state */
413  pqsecure_close(conn);
414  /* Close the socket itself */
415  if (conn->sock != PGINVALID_SOCKET)
416  closesocket(conn->sock);
417  conn->sock = PGINVALID_SOCKET;
418  /* Optionally discard any unread data */
419  if (flushInput)
420  conn->inStart = conn->inCursor = conn->inEnd = 0;
421  /* Always discard any unsent data */
422  conn->outCount = 0;
423 }
int inEnd
Definition: libpq-int.h:437
int inStart
Definition: libpq-int.h:435
#define closesocket
Definition: port.h:328
int outCount
Definition: libpq-int.h:442
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:189
pgsocket sock
Definition: libpq-int.h:402
#define PGINVALID_SOCKET
Definition: port.h:24
int inCursor
Definition: libpq-int.h:436
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(), 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:966
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int PQresetStart(PGconn *conn)
Definition: fe-connect.c:3572
#define pqIsnonblocking(conn)
Definition: libpq-int.h:683
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
PGNoticeHooks noticeHooks
Definition: libpq-int.h:372
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
PQExpBufferData errorMessage
Definition: libpq-int.h:498
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:179
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
#define libpq_gettext(x)
Definition: libpq-int.h:689
void PQreset(PGconn *conn)
Definition: fe-connect.c:3531
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(), 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:966
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define pqIsnonblocking(conn)
Definition: libpq-int.h:683
PGQueryClass queryclass
Definition: libpq-int.h:383
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:524
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
PGNoticeHooks noticeHooks
Definition: libpq-int.h:372
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
PQExpBufferData errorMessage
Definition: libpq-int.h:498
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:592
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
ExecStatusType resultStatus
Definition: libpq-int.h:179
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
#define libpq_gettext(x)
Definition: libpq-int.h:689
int pqFlush ( PGconn conn)

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

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

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

967 {
968  if (conn->Pfdebug)
969  fflush(conn->Pfdebug);
970 
971  if (conn->outCount > 0)
972  return pqSendSome(conn, conn->outCount);
973 
974  return 0;
975 }
int outCount
Definition: libpq-int.h:442
FILE * Pfdebug
Definition: libpq-int.h:369
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:834
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:966
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:435
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:524
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:272
ExecStatusType
Definition: libpq-fe.h:82
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:200
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:756
PGresult * result
Definition: libpq-int.h:454
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:312
#define FALSE
Definition: c.h:218
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
int pqPuts(const char *s, PGconn *conn)
Definition: fe-misc.c:184
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:99
static int getNotify(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:251
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:592
int i
#define TRUE
Definition: c.h:214
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:436
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:966
int inEnd
Definition: libpq-int.h:437
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:435
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:413
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:524
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:272
ExecStatusType
Definition: libpq-fe.h:82
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:200
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:756
PGresult * result
Definition: libpq-int.h:454
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:312
#define FALSE
Definition: c.h:218
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:876
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:99
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:41
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:251
static int getReadyForQuery(PGconn *conn)
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:592
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:214
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:436
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:689
int integer
Definition: libpq-fe.h:227
int pqGetc ( char *  result,
PGconn conn 
)

Definition at line 99 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().

100 {
101  if (conn->inCursor >= conn->inEnd)
102  return EOF;
103 
104  *result = conn->inBuffer[conn->inCursor++];
105 
106  if (conn->Pfdebug)
107  fprintf(conn->Pfdebug, "From backend> %c\n", *result);
108 
109  return 0;
110 }
int inEnd
Definition: libpq-int.h:437
FILE * Pfdebug
Definition: libpq-int.h:369
char * inBuffer
Definition: libpq-int.h:433
int inCursor
Definition: libpq-int.h:436
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:437
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:435
#define malloc(a)
Definition: header.h:45
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define FALSE
Definition: c.h:218
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
char * c
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
char * inBuffer
Definition: libpq-int.h:433
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
#define TRUE
Definition: c.h:214
int inCursor
Definition: libpq-int.h:436
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:435
#define malloc(a)
Definition: header.h:45
#define FALSE
Definition: c.h:218
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
char * inBuffer
Definition: libpq-int.h:433
static int getCopyDataMessage(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
#define TRUE
Definition: c.h:214
int inCursor
Definition: libpq-int.h:436
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:429
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:168
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:53
char * errMsg
Definition: libpq-int.h:198
PGresult * result
Definition: libpq-int.h:454
PGNoticeHooks noticeHooks
Definition: libpq-int.h:188
PGVerbosity verbosity
Definition: libpq-int.h:428
PQnoticeReceiver noticeRec
Definition: libpq-int.h:154
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
char * last_query
Definition: libpq-int.h:384
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:57
char * errQuery
Definition: libpq-int.h:200
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:99
void pqSaveMessageField(PGresult *res, char code, const char *value)
Definition: fe-exec.c:891
PQExpBufferData errorMessage
Definition: libpq-int.h:498
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:226
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:179
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
#define libpq_gettext(x)
Definition: libpq-int.h:689
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:602
void * noticeRecArg
Definition: libpq-int.h:155
char last_sqlstate[6]
Definition: libpq-int.h:385
bool pqGetHomeDirectory ( char *  buf,
int  bufsize 
)

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

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

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

6380 {
6381 #ifndef WIN32
6382  char pwdbuf[BUFSIZ];
6383  struct passwd pwdstr;
6384  struct passwd *pwd = NULL;
6385 
6386  (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
6387  if (pwd == NULL)
6388  return false;
6389  strlcpy(buf, pwd->pw_dir, bufsize);
6390  return true;
6391 #else
6392  char tmppath[MAX_PATH];
6393 
6394  ZeroMemory(tmppath, sizeof(tmppath));
6395  if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
6396  return false;
6397  snprintf(buf, bufsize, "%s/postgresql", tmppath);
6398  return true;
6399 #endif
6400 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static char * buf
Definition: pg_test_fsync.c:65
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
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 272 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().

273 {
274  uint16 tmp2;
275  uint32 tmp4;
276 
277  switch (bytes)
278  {
279  case 2:
280  if (conn->inCursor + 2 > conn->inEnd)
281  return EOF;
282  memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
283  conn->inCursor += 2;
284  *result = (int) ntohs(tmp2);
285  break;
286  case 4:
287  if (conn->inCursor + 4 > conn->inEnd)
288  return EOF;
289  memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
290  conn->inCursor += 4;
291  *result = (int) ntohl(tmp4);
292  break;
293  default:
295  "integer of size %lu not supported by pqGetInt",
296  (unsigned long) bytes);
297  return EOF;
298  }
299 
300  if (conn->Pfdebug)
301  fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
302 
303  return 0;
304 }
int inEnd
Definition: libpq-int.h:437
FILE * Pfdebug
Definition: libpq-int.h:369
unsigned short uint16
Definition: c.h:264
PGNoticeHooks noticeHooks
Definition: libpq-int.h:372
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:801
unsigned int uint32
Definition: c.h:265
char * inBuffer
Definition: libpq-int.h:433
int inCursor
Definition: libpq-int.h:436
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(), 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:437
int inStart
Definition: libpq-int.h:435
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define FALSE
Definition: c.h:218
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
char * c
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
pgsocket sock
Definition: libpq-int.h:402
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:433
#define TRUE
Definition: c.h:214
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:390
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define FALSE
Definition: c.h:218
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:989
pgsocket sock
Definition: libpq-int.h:402
#define PGINVALID_SOCKET
Definition: port.h:24
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define TRUE
Definition: c.h:214
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:437
int inStart
Definition: libpq-int.h:435
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
char * c
char * inBuffer
Definition: libpq-int.h:433
int inCursor
Definition: libpq-int.h:436
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:435
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
char * inBuffer
Definition: libpq-int.h:433
static int getCopyDataMessage(PGconn *conn)
int copy_already_done
Definition: libpq-int.h:391
int inCursor
Definition: libpq-int.h:436
int pqGetnchar ( char *  s,
size_t  len,
PGconn conn 
)

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

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

Referenced by getAnotherTuple(), PQconnectPoll(), pqFunctionCall2(), and pqFunctionCall3().

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

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

References pqGets_internal().

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

169 {
170  return pqGets_internal(buf, conn, true);
171 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:137
int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

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

References pqGets_internal().

Referenced by PQconnectPoll().

175 {
176  return pqGets_internal(buf, conn, false);
177 }
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:137
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:634
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 3862 of file fe-connect.c.

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

Referenced by pg_password_sendauth(), and PQconnectPoll().

3864 {
3865  /* Start the message. */
3866  if (pqPutMsgStart(pack_type, true, conn))
3867  return STATUS_ERROR;
3868 
3869  /* Send the message body. */
3870  if (pqPutnchar(buf, buf_len, conn))
3871  return STATUS_ERROR;
3872 
3873  /* Finish the message. */
3874  if (pqPutMsgEnd(conn))
3875  return STATUS_ERROR;
3876 
3877  /* Flush to ensure backend gets it. */
3878  if (pqFlush(conn))
3879  return STATUS_ERROR;
3880 
3881  return STATUS_OK;
3882 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:966
int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn)
Definition: fe-misc.c:524
#define STATUS_ERROR
Definition: c.h:971
static char * buf
Definition: pg_test_fsync.c:65
#define STATUS_OK
Definition: c.h:970
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:251
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:592
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:437
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:435
static int getRowDescriptions(PGconn *conn)
Definition: fe-protocol2.c:659
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:168
PQExpBufferData workBuffer
Definition: libpq-int.h:501
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:272
#define CMDSTATUS_LEN
Definition: libpq-int.h:88
PGresult * result
Definition: libpq-int.h:454
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define FALSE
Definition: c.h:218
PGNoticeHooks noticeHooks
Definition: libpq-int.h:372
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:99
static int getNotify(PGconn *conn)
PQExpBufferData errorMessage
Definition: libpq-int.h:498
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:180
int be_key
Definition: libpq-int.h:423
#define TRUE
Definition: c.h:214
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:728
int inCursor
Definition: libpq-int.h:436
int be_pid
Definition: libpq-int.h:422
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:437
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:435
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:168
PQExpBufferData workBuffer
Definition: libpq-int.h:501
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:413
PGQueryClass queryclass
Definition: libpq-int.h:383
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:272
static int getParamDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:651
#define CMDSTATUS_LEN
Definition: libpq-int.h:88
PGresult * result
Definition: libpq-int.h:454
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
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:372
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:99
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:41
PQExpBufferData errorMessage
Definition: libpq-int.h:498
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
static int getReadyForQuery(PGconn *conn)
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:180
int be_key
Definition: libpq-int.h:423
int copy_already_done
Definition: libpq-int.h:391
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:436
int be_pid
Definition: libpq-int.h:422
ExecStatusType resultStatus
Definition: libpq-int.h:179
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:454
PGresult * next_result
Definition: libpq-int.h:455
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
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 117 of file fe-misc.c.

References pg_conn::Pfdebug, and pqPutMsgBytes().

Referenced by PQsendDescribe(), and PQsendQueryGuts().

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

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

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

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

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

Definition at line 592 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 pqEndcopy3(), pqFunctionCall2(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), and sendTerminateConn().

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

Definition at line 524 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 pqEndcopy3(), pqFunctionCall2(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQputCopyEnd(), PQsendDescribe(), PQsendPrepare(), PQsendQuery(), PQsendQueryGuts(), and sendTerminateConn().

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

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

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

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

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

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

References pg_conn::Pfdebug, and pqPutMsgBytes().

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

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

Definition at line 634 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().

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

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

References pqSocketCheck().

Referenced by pqReadData().

1029 {
1030  return pqSocketCheck(conn, 1, 0, (time_t) 0);
1031 }
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
Definition: fe-misc.c:1052
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:108
PGresult_data * next
Definition: libpq-int.h:107
union pgresult_data PGresult_data
Definition: libpq-int.h:103
int spaceLeft
Definition: libpq-int.h:212
char null_field[1]
Definition: libpq-int.h:203
#define malloc(a)
Definition: header.h:45
#define PGRESULT_ALIGN_BOUNDARY
Definition: fe-exec.c:128
int curOffset
Definition: libpq-int.h:211
#define PGRESULT_BLOCK_OVERHEAD
Definition: fe-exec.c:129
PGresult_data * curBlock
Definition: libpq-int.h:210
#define PGRESULT_SEP_ALLOC_THRESHOLD
Definition: fe-exec.c:130
#define NULL
Definition: c.h:226
#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:218
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 }
static struct @76 value
bool singleRowMode
Definition: libpq-int.h:389
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:135
char null_field[1]
Definition: libpq-int.h:203
PGresAttDesc * attDescs
Definition: libpq-int.h:173
PGresult * result
Definition: libpq-int.h:454
PGresult * next_result
Definition: libpq-int.h:455
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:36
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:37
PGdataValue * rowBuf
Definition: libpq-int.h:450
int numAttributes
Definition: libpq-int.h:172
#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:226
int i
char * value
Definition: libpq-int.h:140
#define TRUE
Definition: c.h:214
ExecStatusType resultStatus
Definition: libpq-int.h:179
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:198
PGresult * result
Definition: libpq-int.h:454
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:140
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
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:179
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 }
static struct @76 value
PGMessageField * errFields
Definition: libpq-int.h:199
struct pgMessageField * next
Definition: libpq-int.h:146
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:506
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:148
#define TRUE
Definition: c.h:214
#define offsetof(type, field)
Definition: c.h:550
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
static struct @76 value
int pg_char_to_encoding(const char *name)
Definition: encnames.c:475
FILE * Pfdebug
Definition: libpq-int.h:369
#define malloc(a)
Definition: header.h:45
int sversion
Definition: libpq-int.h:407
struct pgParameterStatus pgParameterStatus
static int static_client_encoding
Definition: fe-exec.c:49
pgParameterStatus * pstatus
Definition: libpq-int.h:425
bool std_strings
Definition: libpq-int.h:427
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
struct pgParameterStatus * next
Definition: libpq-int.h:260
const char * name
Definition: encode.c:521
int client_encoding
Definition: libpq-int.h:426
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:45
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:45
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:45
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:301
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define recv(s, buf, len, flags)
Definition: win32.h:385
#define ECONNRESET
Definition: win32.h:305
#define EAGAIN
Definition: win32.h:293
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define SOCK_ERRNO
Definition: libpq-int.h:702
PGconn * conn
Definition: streamutil.c:45
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
pgsocket sock
Definition: libpq-int.h:402
#define EINTR
Definition: win32.h:295
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define libpq_gettext(x)
Definition: libpq-int.h:689
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:386
#define EWOULDBLOCK
Definition: win32.h:301
bool sigpipe_flag
Definition: libpq-int.h:413
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:305
#define EAGAIN
Definition: win32.h:293
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define SOCK_ERRNO
Definition: libpq-int.h:702
PGconn * conn
Definition: streamutil.c:45
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:113
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
pgsocket sock
Definition: libpq-int.h:402
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:111
#define EINTR
Definition: win32.h:295
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:105
#define libpq_gettext(x)
Definition: libpq-int.h:689
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 = pgtls_read(conn, ptr, len);
213  }
214  else
215 #endif
216  {
217  n = pqsecure_raw_read(conn, ptr, len);
218  }
219 
220  return n;
221 }
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:224
PGconn * conn
Definition: streamutil.c:45
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_write ( PGconn ,
const void *  ptr,
size_t  len 
)

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

References pgtls_write(), and pqsecure_raw_write().

Referenced by pqSendSome().

283 {
284  ssize_t n;
285 
286 #ifdef USE_SSL
287  if (conn->ssl_in_use)
288  {
289  n = pgtls_write(conn, ptr, len);
290  }
291  else
292 #endif
293  {
294  n = pqsecure_raw_write(conn, ptr, len);
295  }
296 
297  return n;
298 }
PGconn * conn
Definition: streamutil.c:45
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:301