LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-misc.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 294 398 73.9 %
Date: 2024-04-26 08:11:58 Functions: 32 35 91.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  *   FILE
       4             :  *      fe-misc.c
       5             :  *
       6             :  *   DESCRIPTION
       7             :  *       miscellaneous useful functions
       8             :  *
       9             :  * The communication routines here are analogous to the ones in
      10             :  * backend/libpq/pqcomm.c and backend/libpq/pqformat.c, but operate
      11             :  * in the considerably different environment of the frontend libpq.
      12             :  * In particular, we work with a bare nonblock-mode socket, rather than
      13             :  * a stdio stream, so that we can avoid unwanted blocking of the application.
      14             :  *
      15             :  * XXX: MOVE DEBUG PRINTOUT TO HIGHER LEVEL.  As is, block and restart
      16             :  * will cause repeat printouts.
      17             :  *
      18             :  * We must speak the same transmitted data representations as the backend
      19             :  * routines.
      20             :  *
      21             :  *
      22             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
      23             :  * Portions Copyright (c) 1994, Regents of the University of California
      24             :  *
      25             :  * IDENTIFICATION
      26             :  *    src/interfaces/libpq/fe-misc.c
      27             :  *
      28             :  *-------------------------------------------------------------------------
      29             :  */
      30             : 
      31             : #include "postgres_fe.h"
      32             : 
      33             : #include <signal.h>
      34             : #include <time.h>
      35             : 
      36             : #ifdef WIN32
      37             : #include "win32.h"
      38             : #else
      39             : #include <unistd.h>
      40             : #include <sys/select.h>
      41             : #include <sys/time.h>
      42             : #endif
      43             : 
      44             : #ifdef HAVE_POLL_H
      45             : #include <poll.h>
      46             : #endif
      47             : 
      48             : #include "libpq-fe.h"
      49             : #include "libpq-int.h"
      50             : #include "mb/pg_wchar.h"
      51             : #include "pg_config_paths.h"
      52             : #include "port/pg_bswap.h"
      53             : 
      54             : static int  pqPutMsgBytes(const void *buf, size_t len, PGconn *conn);
      55             : static int  pqSendSome(PGconn *conn, int len);
      56             : static int  pqSocketCheck(PGconn *conn, int forRead, int forWrite,
      57             :                           time_t end_time);
      58             : 
      59             : /*
      60             :  * PQlibVersion: return the libpq version number
      61             :  */
      62             : int
      63           0 : PQlibVersion(void)
      64             : {
      65           0 :     return PG_VERSION_NUM;
      66             : }
      67             : 
      68             : 
      69             : /*
      70             :  * pqGetc: get 1 character from the connection
      71             :  *
      72             :  *  All these routines return 0 on success, EOF on error.
      73             :  *  Note that for the Get routines, EOF only means there is not enough
      74             :  *  data in the buffer, not that there is necessarily a hard error.
      75             :  */
      76             : int
      77    17740386 : pqGetc(char *result, PGconn *conn)
      78             : {
      79    17740386 :     if (conn->inCursor >= conn->inEnd)
      80     2983270 :         return EOF;
      81             : 
      82    14757116 :     *result = conn->inBuffer[conn->inCursor++];
      83             : 
      84    14757116 :     return 0;
      85             : }
      86             : 
      87             : 
      88             : /*
      89             :  * pqPutc: write 1 char to the current message
      90             :  */
      91             : int
      92       20310 : pqPutc(char c, PGconn *conn)
      93             : {
      94       20310 :     if (pqPutMsgBytes(&c, 1, conn))
      95           0 :         return EOF;
      96             : 
      97       20310 :     return 0;
      98             : }
      99             : 
     100             : 
     101             : /*
     102             :  * pqGets[_append]:
     103             :  * get a null-terminated string from the connection,
     104             :  * and store it in an expansible PQExpBuffer.
     105             :  * If we run out of memory, all of the string is still read,
     106             :  * but the excess characters are silently discarded.
     107             :  */
     108             : static int
     109     2507822 : pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
     110             : {
     111             :     /* Copy conn data to locals for faster search loop */
     112     2507822 :     char       *inBuffer = conn->inBuffer;
     113     2507822 :     int         inCursor = conn->inCursor;
     114     2507822 :     int         inEnd = conn->inEnd;
     115             :     int         slen;
     116             : 
     117    30740740 :     while (inCursor < inEnd && inBuffer[inCursor])
     118    28232918 :         inCursor++;
     119             : 
     120     2507822 :     if (inCursor >= inEnd)
     121           0 :         return EOF;
     122             : 
     123     2507822 :     slen = inCursor - conn->inCursor;
     124             : 
     125     2507822 :     if (resetbuffer)
     126     2507822 :         resetPQExpBuffer(buf);
     127             : 
     128     2507822 :     appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
     129             : 
     130     2507822 :     conn->inCursor = ++inCursor;
     131             : 
     132     2507822 :     return 0;
     133             : }
     134             : 
     135             : int
     136     2507822 : pqGets(PQExpBuffer buf, PGconn *conn)
     137             : {
     138     2507822 :     return pqGets_internal(buf, conn, true);
     139             : }
     140             : 
     141             : int
     142           0 : pqGets_append(PQExpBuffer buf, PGconn *conn)
     143             : {
     144           0 :     return pqGets_internal(buf, conn, false);
     145             : }
     146             : 
     147             : 
     148             : /*
     149             :  * pqPuts: write a null-terminated string to the current message
     150             :  */
     151             : int
     152      640280 : pqPuts(const char *s, PGconn *conn)
     153             : {
     154      640280 :     if (pqPutMsgBytes(s, strlen(s) + 1, conn))
     155           0 :         return EOF;
     156             : 
     157      640280 :     return 0;
     158             : }
     159             : 
     160             : /*
     161             :  * pqGetnchar:
     162             :  *  get a string of exactly len bytes in buffer s, no null termination
     163             :  */
     164             : int
     165         874 : pqGetnchar(char *s, size_t len, PGconn *conn)
     166             : {
     167         874 :     if (len > (size_t) (conn->inEnd - conn->inCursor))
     168           0 :         return EOF;
     169             : 
     170         874 :     memcpy(s, conn->inBuffer + conn->inCursor, len);
     171             :     /* no terminating null */
     172             : 
     173         874 :     conn->inCursor += len;
     174             : 
     175         874 :     return 0;
     176             : }
     177             : 
     178             : /*
     179             :  * pqSkipnchar:
     180             :  *  skip over len bytes in input buffer.
     181             :  *
     182             :  * Note: this is primarily useful for its debug output, which should
     183             :  * be exactly the same as for pqGetnchar.  We assume the data in question
     184             :  * will actually be used, but just isn't getting copied anywhere as yet.
     185             :  */
     186             : int
     187    27527180 : pqSkipnchar(size_t len, PGconn *conn)
     188             : {
     189    27527180 :     if (len > (size_t) (conn->inEnd - conn->inCursor))
     190           0 :         return EOF;
     191             : 
     192    27527180 :     conn->inCursor += len;
     193             : 
     194    27527180 :     return 0;
     195             : }
     196             : 
     197             : /*
     198             :  * pqPutnchar:
     199             :  *  write exactly len bytes to the current message
     200             :  */
     201             : int
     202      623142 : pqPutnchar(const char *s, size_t len, PGconn *conn)
     203             : {
     204      623142 :     if (pqPutMsgBytes(s, len, conn))
     205           0 :         return EOF;
     206             : 
     207      623142 :     return 0;
     208             : }
     209             : 
     210             : /*
     211             :  * pqGetInt
     212             :  *  read a 2 or 4 byte integer and convert from network byte order
     213             :  *  to local byte order
     214             :  */
     215             : int
     216    54583036 : pqGetInt(int *result, size_t bytes, PGconn *conn)
     217             : {
     218             :     uint16      tmp2;
     219             :     uint32      tmp4;
     220             : 
     221    54583036 :     switch (bytes)
     222             :     {
     223     9153350 :         case 2:
     224     9153350 :             if (conn->inCursor + 2 > conn->inEnd)
     225           0 :                 return EOF;
     226     9153350 :             memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
     227     9153350 :             conn->inCursor += 2;
     228     9153350 :             *result = (int) pg_ntoh16(tmp2);
     229     9153350 :             break;
     230    45429686 :         case 4:
     231    45429686 :             if (conn->inCursor + 4 > conn->inEnd)
     232        3948 :                 return EOF;
     233    45425738 :             memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
     234    45425738 :             conn->inCursor += 4;
     235    45425738 :             *result = (int) pg_ntoh32(tmp4);
     236    45425738 :             break;
     237           0 :         default:
     238           0 :             pqInternalNotice(&conn->noticeHooks,
     239             :                              "integer of size %lu not supported by pqGetInt",
     240             :                              (unsigned long) bytes);
     241           0 :             return EOF;
     242             :     }
     243             : 
     244    54579088 :     return 0;
     245             : }
     246             : 
     247             : /*
     248             :  * pqPutInt
     249             :  * write an integer of 2 or 4 bytes, converting from host byte order
     250             :  * to network byte order.
     251             :  */
     252             : int
     253      163346 : pqPutInt(int value, size_t bytes, PGconn *conn)
     254             : {
     255             :     uint16      tmp2;
     256             :     uint32      tmp4;
     257             : 
     258      163346 :     switch (bytes)
     259             :     {
     260      105982 :         case 2:
     261      105982 :             tmp2 = pg_hton16((uint16) value);
     262      105982 :             if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
     263           0 :                 return EOF;
     264      105982 :             break;
     265       57364 :         case 4:
     266       57364 :             tmp4 = pg_hton32((uint32) value);
     267       57364 :             if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
     268           0 :                 return EOF;
     269       57364 :             break;
     270           0 :         default:
     271           0 :             pqInternalNotice(&conn->noticeHooks,
     272             :                              "integer of size %lu not supported by pqPutInt",
     273             :                              (unsigned long) bytes);
     274           0 :             return EOF;
     275             :     }
     276             : 
     277      163346 :     return 0;
     278             : }
     279             : 
     280             : /*
     281             :  * Make sure conn's output buffer can hold bytes_needed bytes (caller must
     282             :  * include already-stored data into the value!)
     283             :  *
     284             :  * Returns 0 on success, EOF if failed to enlarge buffer
     285             :  */
     286             : int
     287     2698312 : pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
     288             : {
     289     2698312 :     int         newsize = conn->outBufSize;
     290             :     char       *newbuf;
     291             : 
     292             :     /* Quick exit if we have enough space */
     293     2698312 :     if (bytes_needed <= (size_t) newsize)
     294     2698274 :         return 0;
     295             : 
     296             :     /*
     297             :      * If we need to enlarge the buffer, we first try to double it in size; if
     298             :      * that doesn't work, enlarge in multiples of 8K.  This avoids thrashing
     299             :      * the malloc pool by repeated small enlargements.
     300             :      *
     301             :      * Note: tests for newsize > 0 are to catch integer overflow.
     302             :      */
     303             :     do
     304             :     {
     305          98 :         newsize *= 2;
     306          98 :     } while (newsize > 0 && bytes_needed > (size_t) newsize);
     307             : 
     308          38 :     if (newsize > 0 && bytes_needed <= (size_t) newsize)
     309             :     {
     310          38 :         newbuf = realloc(conn->outBuffer, newsize);
     311          38 :         if (newbuf)
     312             :         {
     313             :             /* realloc succeeded */
     314          38 :             conn->outBuffer = newbuf;
     315          38 :             conn->outBufSize = newsize;
     316          38 :             return 0;
     317             :         }
     318             :     }
     319             : 
     320           0 :     newsize = conn->outBufSize;
     321             :     do
     322             :     {
     323           0 :         newsize += 8192;
     324           0 :     } while (newsize > 0 && bytes_needed > (size_t) newsize);
     325             : 
     326           0 :     if (newsize > 0 && bytes_needed <= (size_t) newsize)
     327             :     {
     328           0 :         newbuf = realloc(conn->outBuffer, newsize);
     329           0 :         if (newbuf)
     330             :         {
     331             :             /* realloc succeeded */
     332           0 :             conn->outBuffer = newbuf;
     333           0 :             conn->outBufSize = newsize;
     334           0 :             return 0;
     335             :         }
     336             :     }
     337             : 
     338             :     /* realloc failed. Probably out of memory */
     339           0 :     appendPQExpBufferStr(&conn->errorMessage,
     340             :                          "cannot allocate memory for output buffer\n");
     341           0 :     return EOF;
     342             : }
     343             : 
     344             : /*
     345             :  * Make sure conn's input buffer can hold bytes_needed bytes (caller must
     346             :  * include already-stored data into the value!)
     347             :  *
     348             :  * Returns 0 on success, EOF if failed to enlarge buffer
     349             :  */
     350             : int
     351      231058 : pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
     352             : {
     353      231058 :     int         newsize = conn->inBufSize;
     354             :     char       *newbuf;
     355             : 
     356             :     /* Quick exit if we have enough space */
     357      231058 :     if (bytes_needed <= (size_t) newsize)
     358      102372 :         return 0;
     359             : 
     360             :     /*
     361             :      * Before concluding that we need to enlarge the buffer, left-justify
     362             :      * whatever is in it and recheck.  The caller's value of bytes_needed
     363             :      * includes any data to the left of inStart, but we can delete that in
     364             :      * preference to enlarging the buffer.  It's slightly ugly to have this
     365             :      * function do this, but it's better than making callers worry about it.
     366             :      */
     367      128686 :     bytes_needed -= conn->inStart;
     368             : 
     369      128686 :     if (conn->inStart < conn->inEnd)
     370             :     {
     371      128686 :         if (conn->inStart > 0)
     372             :         {
     373      128188 :             memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
     374      128188 :                     conn->inEnd - conn->inStart);
     375      128188 :             conn->inEnd -= conn->inStart;
     376      128188 :             conn->inCursor -= conn->inStart;
     377      128188 :             conn->inStart = 0;
     378             :         }
     379             :     }
     380             :     else
     381             :     {
     382             :         /* buffer is logically empty, reset it */
     383           0 :         conn->inStart = conn->inCursor = conn->inEnd = 0;
     384             :     }
     385             : 
     386             :     /* Recheck whether we have enough space */
     387      128686 :     if (bytes_needed <= (size_t) newsize)
     388      127436 :         return 0;
     389             : 
     390             :     /*
     391             :      * If we need to enlarge the buffer, we first try to double it in size; if
     392             :      * that doesn't work, enlarge in multiples of 8K.  This avoids thrashing
     393             :      * the malloc pool by repeated small enlargements.
     394             :      *
     395             :      * Note: tests for newsize > 0 are to catch integer overflow.
     396             :      */
     397             :     do
     398             :     {
     399        2250 :         newsize *= 2;
     400        2250 :     } while (newsize > 0 && bytes_needed > (size_t) newsize);
     401             : 
     402        1250 :     if (newsize > 0 && bytes_needed <= (size_t) newsize)
     403             :     {
     404        1250 :         newbuf = realloc(conn->inBuffer, newsize);
     405        1250 :         if (newbuf)
     406             :         {
     407             :             /* realloc succeeded */
     408        1250 :             conn->inBuffer = newbuf;
     409        1250 :             conn->inBufSize = newsize;
     410        1250 :             return 0;
     411             :         }
     412             :     }
     413             : 
     414           0 :     newsize = conn->inBufSize;
     415             :     do
     416             :     {
     417           0 :         newsize += 8192;
     418           0 :     } while (newsize > 0 && bytes_needed > (size_t) newsize);
     419             : 
     420           0 :     if (newsize > 0 && bytes_needed <= (size_t) newsize)
     421             :     {
     422           0 :         newbuf = realloc(conn->inBuffer, newsize);
     423           0 :         if (newbuf)
     424             :         {
     425             :             /* realloc succeeded */
     426           0 :             conn->inBuffer = newbuf;
     427           0 :             conn->inBufSize = newsize;
     428           0 :             return 0;
     429             :         }
     430             :     }
     431             : 
     432             :     /* realloc failed. Probably out of memory */
     433           0 :     appendPQExpBufferStr(&conn->errorMessage,
     434             :                          "cannot allocate memory for input buffer\n");
     435           0 :     return EOF;
     436             : }
     437             : 
     438             : /*
     439             :  * pqPutMsgStart: begin construction of a message to the server
     440             :  *
     441             :  * msg_type is the message type byte, or 0 for a message without type byte
     442             :  * (only startup messages have no type byte)
     443             :  *
     444             :  * Returns 0 on success, EOF on error
     445             :  *
     446             :  * The idea here is that we construct the message in conn->outBuffer,
     447             :  * beginning just past any data already in outBuffer (ie, at
     448             :  * outBuffer+outCount).  We enlarge the buffer as needed to hold the message.
     449             :  * When the message is complete, we fill in the length word (if needed) and
     450             :  * then advance outCount past the message, making it eligible to send.
     451             :  *
     452             :  * The state variable conn->outMsgStart points to the incomplete message's
     453             :  * length word: it is either outCount or outCount+1 depending on whether
     454             :  * there is a type byte.  The state variable conn->outMsgEnd is the end of
     455             :  * the data collected so far.
     456             :  */
     457             : int
     458     1251204 : pqPutMsgStart(char msg_type, PGconn *conn)
     459             : {
     460             :     int         lenPos;
     461             :     int         endPos;
     462             : 
     463             :     /* allow room for message type byte */
     464     1251204 :     if (msg_type)
     465     1228542 :         endPos = conn->outCount + 1;
     466             :     else
     467       22662 :         endPos = conn->outCount;
     468             : 
     469             :     /* do we want a length word? */
     470     1251204 :     lenPos = endPos;
     471             :     /* allow room for message length */
     472     1251204 :     endPos += 4;
     473             : 
     474             :     /* make sure there is room for message header */
     475     1251204 :     if (pqCheckOutBufferSpace(endPos, conn))
     476           0 :         return EOF;
     477             :     /* okay, save the message type byte if any */
     478     1251204 :     if (msg_type)
     479     1228542 :         conn->outBuffer[conn->outCount] = msg_type;
     480             :     /* set up the message pointers */
     481     1251204 :     conn->outMsgStart = lenPos;
     482     1251204 :     conn->outMsgEnd = endPos;
     483             :     /* length word, if needed, will be filled in by pqPutMsgEnd */
     484             : 
     485     1251204 :     return 0;
     486             : }
     487             : 
     488             : /*
     489             :  * pqPutMsgBytes: add bytes to a partially-constructed message
     490             :  *
     491             :  * Returns 0 on success, EOF on error
     492             :  */
     493             : static int
     494     1447078 : pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
     495             : {
     496             :     /* make sure there is room for it */
     497     1447078 :     if (pqCheckOutBufferSpace(conn->outMsgEnd + len, conn))
     498           0 :         return EOF;
     499             :     /* okay, save the data */
     500     1447078 :     memcpy(conn->outBuffer + conn->outMsgEnd, buf, len);
     501     1447078 :     conn->outMsgEnd += len;
     502             :     /* no Pfdebug call here, caller should do it */
     503     1447078 :     return 0;
     504             : }
     505             : 
     506             : /*
     507             :  * pqPutMsgEnd: finish constructing a message and possibly send it
     508             :  *
     509             :  * Returns 0 on success, EOF on error
     510             :  *
     511             :  * We don't actually send anything here unless we've accumulated at least
     512             :  * 8K worth of data (the typical size of a pipe buffer on Unix systems).
     513             :  * This avoids sending small partial packets.  The caller must use pqFlush
     514             :  * when it's important to flush all the data out to the server.
     515             :  */
     516             : int
     517     1251204 : pqPutMsgEnd(PGconn *conn)
     518             : {
     519             :     /* Fill in length word if needed */
     520     1251204 :     if (conn->outMsgStart >= 0)
     521             :     {
     522     1251204 :         uint32      msgLen = conn->outMsgEnd - conn->outMsgStart;
     523             : 
     524     1251204 :         msgLen = pg_hton32(msgLen);
     525     1251204 :         memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
     526             :     }
     527             : 
     528             :     /* trace client-to-server message */
     529     1251204 :     if (conn->Pfdebug)
     530             :     {
     531         394 :         if (conn->outCount < conn->outMsgStart)
     532         394 :             pqTraceOutputMessage(conn, conn->outBuffer + conn->outCount, true);
     533             :         else
     534           0 :             pqTraceOutputNoTypeByteMessage(conn,
     535           0 :                                            conn->outBuffer + conn->outMsgStart);
     536             :     }
     537             : 
     538             :     /* Make message eligible to send */
     539     1251204 :     conn->outCount = conn->outMsgEnd;
     540             : 
     541     1251204 :     if (conn->outCount >= 8192)
     542             :     {
     543        2010 :         int         toSend = conn->outCount - (conn->outCount % 8192);
     544             : 
     545        2010 :         if (pqSendSome(conn, toSend) < 0)
     546           0 :             return EOF;
     547             :         /* in nonblock mode, don't complain if unable to send it all */
     548             :     }
     549             : 
     550     1251204 :     return 0;
     551             : }
     552             : 
     553             : /* ----------
     554             :  * pqReadData: read more data, if any is available
     555             :  * Possible return values:
     556             :  *   1: successfully loaded at least one more byte
     557             :  *   0: no data is presently available, but no error detected
     558             :  *  -1: error detected (including EOF = connection closure);
     559             :  *      conn->errorMessage set
     560             :  * NOTE: callers must not assume that pointers or indexes into conn->inBuffer
     561             :  * remain valid across this call!
     562             :  * ----------
     563             :  */
     564             : int
     565     1668120 : pqReadData(PGconn *conn)
     566             : {
     567     1668120 :     int         someread = 0;
     568             :     int         nread;
     569             : 
     570     1668120 :     if (conn->sock == PGINVALID_SOCKET)
     571             :     {
     572           4 :         libpq_append_conn_error(conn, "connection not open");
     573           4 :         return -1;
     574             :     }
     575             : 
     576             :     /* Left-justify any data in the buffer to make room */
     577     1668116 :     if (conn->inStart < conn->inEnd)
     578             :     {
     579      227186 :         if (conn->inStart > 0)
     580             :         {
     581       79328 :             memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
     582       79328 :                     conn->inEnd - conn->inStart);
     583       79328 :             conn->inEnd -= conn->inStart;
     584       79328 :             conn->inCursor -= conn->inStart;
     585       79328 :             conn->inStart = 0;
     586             :         }
     587             :     }
     588             :     else
     589             :     {
     590             :         /* buffer is logically empty, reset it */
     591     1440930 :         conn->inStart = conn->inCursor = conn->inEnd = 0;
     592             :     }
     593             : 
     594             :     /*
     595             :      * If the buffer is fairly full, enlarge it. We need to be able to enlarge
     596             :      * the buffer in case a single message exceeds the initial buffer size. We
     597             :      * enlarge before filling the buffer entirely so as to avoid asking the
     598             :      * kernel for a partial packet. The magic constant here should be large
     599             :      * enough for a TCP packet or Unix pipe bufferload.  8K is the usual pipe
     600             :      * buffer size, so...
     601             :      */
     602     1668116 :     if (conn->inBufSize - conn->inEnd < 8192)
     603             :     {
     604           2 :         if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
     605             :         {
     606             :             /*
     607             :              * We don't insist that the enlarge worked, but we need some room
     608             :              */
     609           0 :             if (conn->inBufSize - conn->inEnd < 100)
     610           0 :                 return -1;      /* errorMessage already set */
     611             :         }
     612             :     }
     613             : 
     614             :     /* OK, try to read some data */
     615     1668116 : retry3:
     616     3413424 :     nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
     617     1706712 :                           conn->inBufSize - conn->inEnd);
     618     1706712 :     if (nread < 0)
     619             :     {
     620      566328 :         switch (SOCK_ERRNO)
     621             :         {
     622           0 :             case EINTR:
     623           0 :                 goto retry3;
     624             : 
     625             :                 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
     626             : #ifdef EAGAIN
     627      566316 :             case EAGAIN:
     628      566316 :                 return someread;
     629             : #endif
     630             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
     631             :             case EWOULDBLOCK:
     632             :                 return someread;
     633             : #endif
     634             : 
     635             :                 /* We might get ECONNRESET etc here if connection failed */
     636          12 :             case ALL_CONNECTION_FAILURE_ERRNOS:
     637          12 :                 goto definitelyFailed;
     638             : 
     639           0 :             default:
     640             :                 /* pqsecure_read set the error message for us */
     641           0 :                 return -1;
     642             :         }
     643             :     }
     644     1140384 :     if (nread > 0)
     645             :     {
     646     1139830 :         conn->inEnd += nread;
     647             : 
     648             :         /*
     649             :          * Hack to deal with the fact that some kernels will only give us back
     650             :          * 1 packet per recv() call, even if we asked for more and there is
     651             :          * more available.  If it looks like we are reading a long message,
     652             :          * loop back to recv() again immediately, until we run out of data or
     653             :          * buffer space.  Without this, the block-and-restart behavior of
     654             :          * libpq's higher levels leads to O(N^2) performance on long messages.
     655             :          *
     656             :          * Since we left-justified the data above, conn->inEnd gives the
     657             :          * amount of data already read in the current message.  We consider
     658             :          * the message "long" once we have acquired 32k ...
     659             :          */
     660     1139830 :         if (conn->inEnd > 32768 &&
     661      153238 :             (conn->inBufSize - conn->inEnd) >= 8192)
     662             :         {
     663       38596 :             someread = 1;
     664       38596 :             goto retry3;
     665             :         }
     666     1101234 :         return 1;
     667             :     }
     668             : 
     669         554 :     if (someread)
     670           0 :         return 1;               /* got a zero read after successful tries */
     671             : 
     672             :     /*
     673             :      * A return value of 0 could mean just that no data is now available, or
     674             :      * it could mean EOF --- that is, the server has closed the connection.
     675             :      * Since we have the socket in nonblock mode, the only way to tell the
     676             :      * difference is to see if select() is saying that the file is ready.
     677             :      * Grumble.  Fortunately, we don't expect this path to be taken much,
     678             :      * since in normal practice we should not be trying to read data unless
     679             :      * the file selected for reading already.
     680             :      *
     681             :      * In SSL mode it's even worse: SSL_read() could say WANT_READ and then
     682             :      * data could arrive before we make the pqReadReady() test, but the second
     683             :      * SSL_read() could still say WANT_READ because the data received was not
     684             :      * a complete SSL record.  So we must play dumb and assume there is more
     685             :      * data, relying on the SSL layer to detect true EOF.
     686             :      */
     687             : 
     688             : #ifdef USE_SSL
     689         554 :     if (conn->ssl_in_use)
     690         368 :         return 0;
     691             : #endif
     692             : 
     693         186 :     switch (pqReadReady(conn))
     694             :     {
     695           0 :         case 0:
     696             :             /* definitely no data available */
     697           0 :             return 0;
     698         186 :         case 1:
     699             :             /* ready for read */
     700         186 :             break;
     701           0 :         default:
     702             :             /* we override pqReadReady's message with something more useful */
     703           0 :             goto definitelyEOF;
     704             :     }
     705             : 
     706             :     /*
     707             :      * Still not sure that it's EOF, because some data could have just
     708             :      * arrived.
     709             :      */
     710         186 : retry4:
     711         372 :     nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
     712         186 :                           conn->inBufSize - conn->inEnd);
     713         186 :     if (nread < 0)
     714             :     {
     715           0 :         switch (SOCK_ERRNO)
     716             :         {
     717           0 :             case EINTR:
     718           0 :                 goto retry4;
     719             : 
     720             :                 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
     721             : #ifdef EAGAIN
     722           0 :             case EAGAIN:
     723           0 :                 return 0;
     724             : #endif
     725             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
     726             :             case EWOULDBLOCK:
     727             :                 return 0;
     728             : #endif
     729             : 
     730             :                 /* We might get ECONNRESET etc here if connection failed */
     731           0 :             case ALL_CONNECTION_FAILURE_ERRNOS:
     732           0 :                 goto definitelyFailed;
     733             : 
     734           0 :             default:
     735             :                 /* pqsecure_read set the error message for us */
     736           0 :                 return -1;
     737             :         }
     738             :     }
     739         186 :     if (nread > 0)
     740             :     {
     741           0 :         conn->inEnd += nread;
     742           0 :         return 1;
     743             :     }
     744             : 
     745             :     /*
     746             :      * OK, we are getting a zero read even though select() says ready. This
     747             :      * means the connection has been closed.  Cope.
     748             :      */
     749         186 : definitelyEOF:
     750         186 :     libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
     751             :                             "\tThis probably means the server terminated abnormally\n"
     752             :                             "\tbefore or while processing the request.");
     753             : 
     754             :     /* Come here if lower-level code already set a suitable errorMessage */
     755         198 : definitelyFailed:
     756             :     /* Do *not* drop any already-read data; caller still wants it */
     757         198 :     pqDropConnection(conn, false);
     758         198 :     conn->status = CONNECTION_BAD;   /* No more connection to backend */
     759         198 :     return -1;
     760             : }
     761             : 
     762             : /*
     763             :  * pqSendSome: send data waiting in the output buffer.
     764             :  *
     765             :  * len is how much to try to send (typically equal to outCount, but may
     766             :  * be less).
     767             :  *
     768             :  * Return 0 on success, -1 on failure and 1 when not all data could be sent
     769             :  * because the socket would block and the connection is non-blocking.
     770             :  *
     771             :  * Note that this is also responsible for consuming data from the socket
     772             :  * (putting it in conn->inBuffer) in any situation where we can't send
     773             :  * all the specified data immediately.
     774             :  *
     775             :  * If a socket-level write failure occurs, conn->write_failed is set and the
     776             :  * error message is saved in conn->write_err_msg, but we clear the output
     777             :  * buffer and return zero anyway; this is because callers should soldier on
     778             :  * until we have read what we can from the server and checked for an error
     779             :  * message.  write_err_msg should be reported only when we are unable to
     780             :  * obtain a server error first.  Much of that behavior is implemented at
     781             :  * lower levels, but this function deals with some edge cases.
     782             :  */
     783             : static int
     784      783936 : pqSendSome(PGconn *conn, int len)
     785             : {
     786      783936 :     char       *ptr = conn->outBuffer;
     787      783936 :     int         remaining = conn->outCount;
     788      783936 :     int         result = 0;
     789             : 
     790             :     /*
     791             :      * If we already had a write failure, we will never again try to send data
     792             :      * on that connection.  Even if the kernel would let us, we've probably
     793             :      * lost message boundary sync with the server.  conn->write_failed
     794             :      * therefore persists until the connection is reset, and we just discard
     795             :      * all data presented to be written.  However, as long as we still have a
     796             :      * valid socket, we should continue to absorb data from the backend, so
     797             :      * that we can collect any final error messages.
     798             :      */
     799      783936 :     if (conn->write_failed)
     800             :     {
     801             :         /* conn->write_err_msg should be set up already */
     802           0 :         conn->outCount = 0;
     803             :         /* Absorb input data if any, and detect socket closure */
     804           0 :         if (conn->sock != PGINVALID_SOCKET)
     805             :         {
     806           0 :             if (pqReadData(conn) < 0)
     807           0 :                 return -1;
     808             :         }
     809           0 :         return 0;
     810             :     }
     811             : 
     812      783936 :     if (conn->sock == PGINVALID_SOCKET)
     813             :     {
     814           0 :         conn->write_failed = true;
     815             :         /* Store error message in conn->write_err_msg, if possible */
     816             :         /* (strdup failure is OK, we'll cope later) */
     817           0 :         conn->write_err_msg = strdup(libpq_gettext("connection not open\n"));
     818             :         /* Discard queued data; no chance it'll ever be sent */
     819           0 :         conn->outCount = 0;
     820           0 :         return 0;
     821             :     }
     822             : 
     823             :     /* while there's still data to send */
     824     1567902 :     while (len > 0)
     825             :     {
     826             :         int         sent;
     827             : 
     828             : #ifndef WIN32
     829      783972 :         sent = pqsecure_write(conn, ptr, len);
     830             : #else
     831             : 
     832             :         /*
     833             :          * Windows can fail on large sends, per KB article Q201213. The
     834             :          * failure-point appears to be different in different versions of
     835             :          * Windows, but 64k should always be safe.
     836             :          */
     837             :         sent = pqsecure_write(conn, ptr, Min(len, 65536));
     838             : #endif
     839             : 
     840      783972 :         if (sent < 0)
     841             :         {
     842             :             /* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble */
     843          42 :             switch (SOCK_ERRNO)
     844             :             {
     845             : #ifdef EAGAIN
     846          42 :                 case EAGAIN:
     847          42 :                     break;
     848             : #endif
     849             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
     850             :                 case EWOULDBLOCK:
     851             :                     break;
     852             : #endif
     853           0 :                 case EINTR:
     854           0 :                     continue;
     855             : 
     856           0 :                 default:
     857             :                     /* Discard queued data; no chance it'll ever be sent */
     858           0 :                     conn->outCount = 0;
     859             : 
     860             :                     /* Absorb input data if any, and detect socket closure */
     861           0 :                     if (conn->sock != PGINVALID_SOCKET)
     862             :                     {
     863           0 :                         if (pqReadData(conn) < 0)
     864           0 :                             return -1;
     865             :                     }
     866             : 
     867             :                     /*
     868             :                      * Lower-level code should already have filled
     869             :                      * conn->write_err_msg (and set conn->write_failed) or
     870             :                      * conn->errorMessage.  In the former case, we pretend
     871             :                      * there's no problem; the write_failed condition will be
     872             :                      * dealt with later.  Otherwise, report the error now.
     873             :                      */
     874           0 :                     if (conn->write_failed)
     875           0 :                         return 0;
     876             :                     else
     877           0 :                         return -1;
     878             :             }
     879             :         }
     880             :         else
     881             :         {
     882      783930 :             ptr += sent;
     883      783930 :             len -= sent;
     884      783930 :             remaining -= sent;
     885             :         }
     886             : 
     887      783972 :         if (len > 0)
     888             :         {
     889             :             /*
     890             :              * We didn't send it all, wait till we can send more.
     891             :              *
     892             :              * There are scenarios in which we can't send data because the
     893             :              * communications channel is full, but we cannot expect the server
     894             :              * to clear the channel eventually because it's blocked trying to
     895             :              * send data to us.  (This can happen when we are sending a large
     896             :              * amount of COPY data, and the server has generated lots of
     897             :              * NOTICE responses.)  To avoid a deadlock situation, we must be
     898             :              * prepared to accept and buffer incoming data before we try
     899             :              * again.  Furthermore, it is possible that such incoming data
     900             :              * might not arrive until after we've gone to sleep.  Therefore,
     901             :              * we wait for either read ready or write ready.
     902             :              *
     903             :              * In non-blocking mode, we don't wait here directly, but return 1
     904             :              * to indicate that data is still pending.  The caller should wait
     905             :              * for both read and write ready conditions, and call
     906             :              * PQconsumeInput() on read ready, but just in case it doesn't, we
     907             :              * call pqReadData() ourselves before returning.  That's not
     908             :              * enough if the data has not arrived yet, but it's the best we
     909             :              * can do, and works pretty well in practice.  (The documentation
     910             :              * used to say that you only need to wait for write-ready, so
     911             :              * there are still plenty of applications like that out there.)
     912             :              *
     913             :              * Note that errors here don't result in write_failed becoming
     914             :              * set.
     915             :              */
     916          42 :             if (pqReadData(conn) < 0)
     917             :             {
     918           0 :                 result = -1;    /* error message already set up */
     919           0 :                 break;
     920             :             }
     921             : 
     922          42 :             if (pqIsnonblocking(conn))
     923             :             {
     924           6 :                 result = 1;
     925           6 :                 break;
     926             :             }
     927             : 
     928          36 :             if (pqWait(true, true, conn))
     929             :             {
     930           0 :                 result = -1;
     931           0 :                 break;
     932             :             }
     933             :         }
     934             :     }
     935             : 
     936             :     /* shift the remaining contents of the buffer */
     937      783936 :     if (remaining > 0)
     938        2010 :         memmove(conn->outBuffer, ptr, remaining);
     939      783936 :     conn->outCount = remaining;
     940             : 
     941      783936 :     return result;
     942             : }
     943             : 
     944             : 
     945             : /*
     946             :  * pqFlush: send any data waiting in the output buffer
     947             :  *
     948             :  * Return 0 on success, -1 on failure and 1 when not all data could be sent
     949             :  * because the socket would block and the connection is non-blocking.
     950             :  * (See pqSendSome comments about how failure should be handled.)
     951             :  */
     952             : int
     953     1413694 : pqFlush(PGconn *conn)
     954             : {
     955     1413694 :     if (conn->outCount > 0)
     956             :     {
     957      781926 :         if (conn->Pfdebug)
     958         108 :             fflush(conn->Pfdebug);
     959             : 
     960      781926 :         return pqSendSome(conn, conn->outCount);
     961             :     }
     962             : 
     963      631768 :     return 0;
     964             : }
     965             : 
     966             : 
     967             : /*
     968             :  * pqWait: wait until we can read or write the connection socket
     969             :  *
     970             :  * JAB: If SSL enabled and used and forRead, buffered bytes short-circuit the
     971             :  * call to select().
     972             :  *
     973             :  * We also stop waiting and return if the kernel flags an exception condition
     974             :  * on the socket.  The actual error condition will be detected and reported
     975             :  * when the caller tries to read or write the socket.
     976             :  */
     977             : int
     978      790210 : pqWait(int forRead, int forWrite, PGconn *conn)
     979             : {
     980      790210 :     return pqWaitTimed(forRead, forWrite, conn, (time_t) -1);
     981             : }
     982             : 
     983             : /*
     984             :  * pqWaitTimed: wait, but not past finish_time.
     985             :  *
     986             :  * finish_time = ((time_t) -1) disables the wait limit.
     987             :  *
     988             :  * Returns -1 on failure, 0 if the socket is readable/writable, 1 if it timed out.
     989             :  */
     990             : int
     991      833390 : pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
     992             : {
     993             :     int         result;
     994             : 
     995      833390 :     result = pqSocketCheck(conn, forRead, forWrite, finish_time);
     996             : 
     997      833390 :     if (result < 0)
     998           4 :         return -1;              /* errorMessage is already set */
     999             : 
    1000      833386 :     if (result == 0)
    1001             :     {
    1002           0 :         libpq_append_conn_error(conn, "timeout expired");
    1003           0 :         return 1;
    1004             :     }
    1005             : 
    1006      833386 :     return 0;
    1007             : }
    1008             : 
    1009             : /*
    1010             :  * pqReadReady: is select() saying the file is ready to read?
    1011             :  * Returns -1 on failure, 0 if not ready, 1 if ready.
    1012             :  */
    1013             : int
    1014         186 : pqReadReady(PGconn *conn)
    1015             : {
    1016         186 :     return pqSocketCheck(conn, 1, 0, (time_t) 0);
    1017             : }
    1018             : 
    1019             : /*
    1020             :  * pqWriteReady: is select() saying the file is ready to write?
    1021             :  * Returns -1 on failure, 0 if not ready, 1 if ready.
    1022             :  */
    1023             : int
    1024           0 : pqWriteReady(PGconn *conn)
    1025             : {
    1026           0 :     return pqSocketCheck(conn, 0, 1, (time_t) 0);
    1027             : }
    1028             : 
    1029             : /*
    1030             :  * Checks a socket, using poll or select, for data to be read, written,
    1031             :  * or both.  Returns >0 if one or more conditions are met, 0 if it timed
    1032             :  * out, -1 if an error occurred.
    1033             :  *
    1034             :  * If SSL is in use, the SSL buffer is checked prior to checking the socket
    1035             :  * for read data directly.
    1036             :  */
    1037             : static int
    1038      833576 : pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
    1039             : {
    1040             :     int         result;
    1041             : 
    1042      833576 :     if (!conn)
    1043           0 :         return -1;
    1044      833576 :     if (conn->sock == PGINVALID_SOCKET)
    1045             :     {
    1046           4 :         libpq_append_conn_error(conn, "invalid socket");
    1047           4 :         return -1;
    1048             :     }
    1049             : 
    1050             : #ifdef USE_SSL
    1051             :     /* Check for SSL library buffering read bytes */
    1052      833572 :     if (forRead && conn->ssl_in_use && pgtls_read_pending(conn))
    1053             :     {
    1054             :         /* short-circuit the select */
    1055           0 :         return 1;
    1056             :     }
    1057             : #endif
    1058             : 
    1059             :     /* We will retry as long as we get EINTR */
    1060             :     do
    1061      833576 :         result = PQsocketPoll(conn->sock, forRead, forWrite, end_time);
    1062      833576 :     while (result < 0 && SOCK_ERRNO == EINTR);
    1063             : 
    1064      833572 :     if (result < 0)
    1065             :     {
    1066             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    1067             : 
    1068           0 :         libpq_append_conn_error(conn, "%s() failed: %s", "select",
    1069           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1070             :     }
    1071             : 
    1072      833572 :     return result;
    1073             : }
    1074             : 
    1075             : 
    1076             : /*
    1077             :  * Check a file descriptor for read and/or write data, possibly waiting.
    1078             :  * If neither forRead nor forWrite are set, immediately return a timeout
    1079             :  * condition (without waiting).  Return >0 if condition is met, 0
    1080             :  * if a timeout occurred, -1 if an error or interrupt occurred.
    1081             :  *
    1082             :  * Timeout is infinite if end_time is -1.  Timeout is immediate (no blocking)
    1083             :  * if end_time is 0 (or indeed, any time before now).
    1084             :  */
    1085             : int
    1086      834180 : PQsocketPoll(int sock, int forRead, int forWrite, time_t end_time)
    1087             : {
    1088             :     /* We use poll(2) if available, otherwise select(2) */
    1089             : #ifdef HAVE_POLL
    1090             :     struct pollfd input_fd;
    1091             :     int         timeout_ms;
    1092             : 
    1093      834180 :     if (!forRead && !forWrite)
    1094           0 :         return 0;
    1095             : 
    1096      834180 :     input_fd.fd = sock;
    1097      834180 :     input_fd.events = POLLERR;
    1098      834180 :     input_fd.revents = 0;
    1099             : 
    1100      834180 :     if (forRead)
    1101      812488 :         input_fd.events |= POLLIN;
    1102      834180 :     if (forWrite)
    1103       21728 :         input_fd.events |= POLLOUT;
    1104             : 
    1105             :     /* Compute appropriate timeout interval */
    1106      834180 :     if (end_time == ((time_t) -1))
    1107      833362 :         timeout_ms = -1;
    1108             :     else
    1109             :     {
    1110         818 :         time_t      now = time(NULL);
    1111             : 
    1112         818 :         if (end_time > now)
    1113         632 :             timeout_ms = (end_time - now) * 1000;
    1114             :         else
    1115         186 :             timeout_ms = 0;
    1116             :     }
    1117             : 
    1118      834180 :     return poll(&input_fd, 1, timeout_ms);
    1119             : #else                           /* !HAVE_POLL */
    1120             : 
    1121             :     fd_set      input_mask;
    1122             :     fd_set      output_mask;
    1123             :     fd_set      except_mask;
    1124             :     struct timeval timeout;
    1125             :     struct timeval *ptr_timeout;
    1126             : 
    1127             :     if (!forRead && !forWrite)
    1128             :         return 0;
    1129             : 
    1130             :     FD_ZERO(&input_mask);
    1131             :     FD_ZERO(&output_mask);
    1132             :     FD_ZERO(&except_mask);
    1133             :     if (forRead)
    1134             :         FD_SET(sock, &input_mask);
    1135             : 
    1136             :     if (forWrite)
    1137             :         FD_SET(sock, &output_mask);
    1138             :     FD_SET(sock, &except_mask);
    1139             : 
    1140             :     /* Compute appropriate timeout interval */
    1141             :     if (end_time == ((time_t) -1))
    1142             :         ptr_timeout = NULL;
    1143             :     else
    1144             :     {
    1145             :         time_t      now = time(NULL);
    1146             : 
    1147             :         if (end_time > now)
    1148             :             timeout.tv_sec = end_time - now;
    1149             :         else
    1150             :             timeout.tv_sec = 0;
    1151             :         timeout.tv_usec = 0;
    1152             :         ptr_timeout = &timeout;
    1153             :     }
    1154             : 
    1155             :     return select(sock + 1, &input_mask, &output_mask,
    1156             :                   &except_mask, ptr_timeout);
    1157             : #endif                          /* HAVE_POLL */
    1158             : }
    1159             : 
    1160             : 
    1161             : /*
    1162             :  * A couple of "miscellaneous" multibyte related functions. They used
    1163             :  * to be in fe-print.c but that file is doomed.
    1164             :  */
    1165             : 
    1166             : /*
    1167             :  * Returns the byte length of the character beginning at s, using the
    1168             :  * specified encoding.
    1169             :  *
    1170             :  * Caution: when dealing with text that is not certainly valid in the
    1171             :  * specified encoding, the result may exceed the actual remaining
    1172             :  * string length.  Callers that are not prepared to deal with that
    1173             :  * should use PQmblenBounded() instead.
    1174             :  */
    1175             : int
    1176    50245574 : PQmblen(const char *s, int encoding)
    1177             : {
    1178    50245574 :     return pg_encoding_mblen(encoding, s);
    1179             : }
    1180             : 
    1181             : /*
    1182             :  * Returns the byte length of the character beginning at s, using the
    1183             :  * specified encoding; but not more than the distance to end of string.
    1184             :  */
    1185             : int
    1186      743074 : PQmblenBounded(const char *s, int encoding)
    1187             : {
    1188      743074 :     return strnlen(s, pg_encoding_mblen(encoding, s));
    1189             : }
    1190             : 
    1191             : /*
    1192             :  * Returns the display length of the character beginning at s, using the
    1193             :  * specified encoding.
    1194             :  */
    1195             : int
    1196    50246796 : PQdsplen(const char *s, int encoding)
    1197             : {
    1198    50246796 :     return pg_encoding_dsplen(encoding, s);
    1199             : }
    1200             : 
    1201             : /*
    1202             :  * Get encoding id from environment variable PGCLIENTENCODING.
    1203             :  */
    1204             : int
    1205       14894 : PQenv2encoding(void)
    1206             : {
    1207             :     char       *str;
    1208       14894 :     int         encoding = PG_SQL_ASCII;
    1209             : 
    1210       14894 :     str = getenv("PGCLIENTENCODING");
    1211       14894 :     if (str && *str != '\0')
    1212             :     {
    1213          12 :         encoding = pg_char_to_encoding(str);
    1214          12 :         if (encoding < 0)
    1215           0 :             encoding = PG_SQL_ASCII;
    1216             :     }
    1217       14894 :     return encoding;
    1218             : }
    1219             : 
    1220             : 
    1221             : #ifdef ENABLE_NLS
    1222             : 
    1223             : static void
    1224       49720 : libpq_binddomain(void)
    1225             : {
    1226             :     /*
    1227             :      * At least on Windows, there are gettext implementations that fail if
    1228             :      * multiple threads call bindtextdomain() concurrently.  Use a mutex and
    1229             :      * flag variable to ensure that we call it just once per process.  It is
    1230             :      * not known that similar bugs exist on non-Windows platforms, but we
    1231             :      * might as well do it the same way everywhere.
    1232             :      */
    1233             :     static volatile bool already_bound = false;
    1234             :     static pthread_mutex_t binddomain_mutex = PTHREAD_MUTEX_INITIALIZER;
    1235             : 
    1236       49720 :     if (!already_bound)
    1237             :     {
    1238             :         /* bindtextdomain() does not preserve errno */
    1239             : #ifdef WIN32
    1240             :         int         save_errno = GetLastError();
    1241             : #else
    1242       18810 :         int         save_errno = errno;
    1243             : #endif
    1244             : 
    1245       18810 :         (void) pthread_mutex_lock(&binddomain_mutex);
    1246             : 
    1247       18810 :         if (!already_bound)
    1248             :         {
    1249             :             const char *ldir;
    1250             : 
    1251             :             /*
    1252             :              * No relocatable lookup here because the calling executable could
    1253             :              * be anywhere
    1254             :              */
    1255       18810 :             ldir = getenv("PGLOCALEDIR");
    1256       18810 :             if (!ldir)
    1257         210 :                 ldir = LOCALEDIR;
    1258       18810 :             bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir);
    1259       18810 :             already_bound = true;
    1260             :         }
    1261             : 
    1262       18810 :         (void) pthread_mutex_unlock(&binddomain_mutex);
    1263             : 
    1264             : #ifdef WIN32
    1265             :         SetLastError(save_errno);
    1266             : #else
    1267       18810 :         errno = save_errno;
    1268             : #endif
    1269             :     }
    1270       49720 : }
    1271             : 
    1272             : char *
    1273       49706 : libpq_gettext(const char *msgid)
    1274             : {
    1275       49706 :     libpq_binddomain();
    1276       49706 :     return dgettext(PG_TEXTDOMAIN("libpq"), msgid);
    1277             : }
    1278             : 
    1279             : char *
    1280          14 : libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n)
    1281             : {
    1282          14 :     libpq_binddomain();
    1283          14 :     return dngettext(PG_TEXTDOMAIN("libpq"), msgid, msgid_plural, n);
    1284             : }
    1285             : 
    1286             : #endif                          /* ENABLE_NLS */
    1287             : 
    1288             : 
    1289             : /*
    1290             :  * Append a formatted string to the given buffer, after translating it.  A
    1291             :  * newline is automatically appended; the format should not end with a
    1292             :  * newline.
    1293             :  */
    1294             : void
    1295          50 : libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...)
    1296             : {
    1297          50 :     int         save_errno = errno;
    1298             :     bool        done;
    1299             :     va_list     args;
    1300             : 
    1301             :     Assert(fmt[strlen(fmt) - 1] != '\n');
    1302             : 
    1303          50 :     if (PQExpBufferBroken(errorMessage))
    1304           0 :         return;                 /* already failed */
    1305             : 
    1306             :     /* Loop in case we have to retry after enlarging the buffer. */
    1307             :     do
    1308             :     {
    1309          50 :         errno = save_errno;
    1310          50 :         va_start(args, fmt);
    1311          50 :         done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
    1312          50 :         va_end(args);
    1313          50 :     } while (!done);
    1314             : 
    1315          50 :     appendPQExpBufferChar(errorMessage, '\n');
    1316             : }
    1317             : 
    1318             : /*
    1319             :  * Append a formatted string to the error message buffer of the given
    1320             :  * connection, after translating it.  A newline is automatically appended; the
    1321             :  * format should not end with a newline.
    1322             :  */
    1323             : void
    1324         840 : libpq_append_conn_error(PGconn *conn, const char *fmt,...)
    1325             : {
    1326         840 :     int         save_errno = errno;
    1327             :     bool        done;
    1328             :     va_list     args;
    1329             : 
    1330             :     Assert(fmt[strlen(fmt) - 1] != '\n');
    1331             : 
    1332         840 :     if (PQExpBufferBroken(&conn->errorMessage))
    1333           0 :         return;                 /* already failed */
    1334             : 
    1335             :     /* Loop in case we have to retry after enlarging the buffer. */
    1336             :     do
    1337             :     {
    1338         850 :         errno = save_errno;
    1339         850 :         va_start(args, fmt);
    1340         850 :         done = appendPQExpBufferVA(&conn->errorMessage, libpq_gettext(fmt), args);
    1341         850 :         va_end(args);
    1342         850 :     } while (!done);
    1343             : 
    1344         840 :     appendPQExpBufferChar(&conn->errorMessage, '\n');
    1345             : }

Generated by: LCOV version 1.14