]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-misc.c
UPDATED PATCH:
[postgresql] / src / interfaces / libpq / fe-misc.c
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/pqcomprim.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.  Note that this module supports *only* network byte order
20  * for transmitted ints, whereas the backend modules (as of this writing)
21  * still handle either network or little-endian byte order.
22  *
23  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
24  * Portions Copyright (c) 1994, Regents of the University of California
25  *
26  *
27  * IDENTIFICATION
28  *        $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.73 2002/06/14 04:23:17 momjian Exp $
29  *
30  *-------------------------------------------------------------------------
31  */
32
33 #include "postgres_fe.h"
34
35 #include <errno.h>
36 #include <signal.h>
37 #include <time.h>
38
39 #ifdef WIN32
40 #include "win32.h"
41 #else
42 #include <unistd.h>
43 #include <sys/time.h>
44 #endif
45
46 #ifdef HAVE_SYS_SELECT_H
47 #include <sys/select.h>
48 #endif
49
50 #include "libpq-fe.h"
51 #include "libpq-int.h"
52 #include "pqsignal.h"
53
54 #ifdef MULTIBYTE
55 #include "mb/pg_wchar.h"
56 #endif
57
58 extern void secure_close(PGconn *);
59 extern ssize_t secure_read(PGconn *, void *, size_t);
60 extern ssize_t secure_write(PGconn *, const void *, size_t);
61
62 #define DONOTICE(conn,message) \
63         ((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
64
65 static int      pqPutBytes(const char *s, size_t nbytes, PGconn *conn);
66
67
68 /*
69  * pqGetc:
70  *      get a 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 pqGetc(char *result, PGconn *conn)
78 {
79         if (conn->inCursor >= conn->inEnd)
80                 return EOF;
81
82         *result = conn->inBuffer[conn->inCursor++];
83
84         if (conn->Pfdebug)
85                 fprintf(conn->Pfdebug, "From backend> %c\n", *result);
86
87         return 0;
88 }
89
90
91 /*
92  * write 1 char to the connection
93  */
94 int
95 pqPutc(char c, PGconn *conn)
96 {
97         if (pqPutBytes(&c, 1, conn) == EOF)
98                 return EOF;
99
100         if (conn->Pfdebug)
101                 fprintf(conn->Pfdebug, "To backend> %c\n", c);
102
103         return 0;
104 }
105
106
107 /*
108  * pqPutBytes: local routine to write N bytes to the connection,
109  * with buffering
110  */
111 static int
112 pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
113 {
114         /* Strategy to handle blocking and non-blocking connections: Fill
115          * the output buffer and flush it repeatedly until either all data
116          * has been sent or is at least queued in the buffer.
117          *
118          * For non-blocking connections, grow the buffer if not all data
119          * fits into it and the buffer can't be sent because the socket
120          * would block.
121          */
122
123         while (nbytes)
124         {
125                 size_t avail, remaining;
126
127                 /* fill the output buffer */
128                 avail = Max(conn->outBufSize - conn->outCount, 0);
129                 remaining = Min(avail, nbytes);
130                 memcpy(conn->outBuffer + conn->outCount, s, remaining);
131                 conn->outCount += remaining;
132                 s += remaining;
133                 nbytes -= remaining;
134
135                 /* if the data didn't fit completely into the buffer, try to
136                  * flush the buffer */
137                 if (nbytes)
138                 {
139                         int send_result = pqSendSome(conn);
140
141                         /* if there were errors, report them */
142                         if (send_result < 0)
143                                 return EOF;
144
145                         /* if not all data could be sent, increase the output
146                          * buffer, put the rest of s into it and return
147                          * successfully. This case will only happen in a
148                          * non-blocking connection
149                          */
150                         if (send_result > 0)
151                         {
152                                 /* try to grow the buffer.
153                                  * FIXME: The new size could be chosen more
154                                  * intelligently.
155                                  */
156                                 size_t buflen = conn->outCount + nbytes;
157                                 if (buflen > conn->outBufSize)
158                                 {
159                                         char * newbuf = realloc(conn->outBuffer, buflen);
160                                         if (!newbuf)
161                                         {
162                                                 /* realloc failed. Probably out of memory */
163                                                 printfPQExpBuffer(&conn->errorMessage,
164                                                                 "cannot allocate memory for output buffer\n");
165                                                 return EOF;
166                                         }
167                                         conn->outBuffer = newbuf;
168                                         conn->outBufSize = buflen;
169                                 }
170                                 /* put the data into it */
171                                 memcpy(conn->outBuffer + conn->outCount, s, nbytes);
172                                 conn->outCount += nbytes;
173
174                                 /* report success. */
175                                 return 0;
176                         }
177                 }
178
179                 /* pqSendSome was able to send all data. Continue with the next
180                  * chunk of s. */
181         } /* while */
182
183         return 0;
184 }
185
186 /*
187  * pqGets:
188  * get a null-terminated string from the connection,
189  * and store it in an expansible PQExpBuffer.
190  * If we run out of memory, all of the string is still read,
191  * but the excess characters are silently discarded.
192  */
193 int
194 pqGets(PQExpBuffer buf, PGconn *conn)
195 {
196         /* Copy conn data to locals for faster search loop */
197         char       *inBuffer = conn->inBuffer;
198         int                     inCursor = conn->inCursor;
199         int                     inEnd = conn->inEnd;
200         int                     slen;
201
202         while (inCursor < inEnd && inBuffer[inCursor])
203                 inCursor++;
204
205         if (inCursor >= inEnd)
206                 return EOF;
207
208         slen = inCursor - conn->inCursor;
209
210         resetPQExpBuffer(buf);
211         appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
212
213         conn->inCursor = ++inCursor;
214
215         if (conn->Pfdebug)
216                 fprintf(conn->Pfdebug, "From backend> \"%s\"\n",
217                                 buf->data);
218
219         return 0;
220 }
221
222
223 int
224 pqPuts(const char *s, PGconn *conn)
225 {
226         if (pqPutBytes(s, strlen(s) + 1, conn))
227                 return EOF;
228
229         if (conn->Pfdebug)
230                 fprintf(conn->Pfdebug, "To backend> %s\n", s);
231
232         return 0;
233 }
234
235 /*
236  * pqGetnchar:
237  *      get a string of exactly len bytes in buffer s, no null termination
238  */
239 int
240 pqGetnchar(char *s, size_t len, PGconn *conn)
241 {
242         if (len < 0 || len > conn->inEnd - conn->inCursor)
243                 return EOF;
244
245         memcpy(s, conn->inBuffer + conn->inCursor, len);
246         /* no terminating null */
247
248         conn->inCursor += len;
249
250         if (conn->Pfdebug)
251                 fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long) len, (int) len, s);
252
253         return 0;
254 }
255
256 /*
257  * pqPutnchar:
258  *      send a string of exactly len bytes, no null termination needed
259  */
260 int
261 pqPutnchar(const char *s, size_t len, PGconn *conn)
262 {
263         if (pqPutBytes(s, len, conn))
264                 return EOF;
265
266         if (conn->Pfdebug)
267                 fprintf(conn->Pfdebug, "To backend> %.*s\n", (int) len, s);
268
269         return 0;
270 }
271
272 /*
273  * pgGetInt
274  *      read a 2 or 4 byte integer and convert from network byte order
275  *      to local byte order
276  */
277 int
278 pqGetInt(int *result, size_t bytes, PGconn *conn)
279 {
280         uint16          tmp2;
281         uint32          tmp4;
282         char            noticeBuf[64];
283
284         switch (bytes)
285         {
286                 case 2:
287                         if (conn->inCursor + 2 > conn->inEnd)
288                                 return EOF;
289                         memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
290                         conn->inCursor += 2;
291                         *result = (int) ntohs(tmp2);
292                         break;
293                 case 4:
294                         if (conn->inCursor + 4 > conn->inEnd)
295                                 return EOF;
296                         memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
297                         conn->inCursor += 4;
298                         *result = (int) ntohl(tmp4);
299                         break;
300                 default:
301                         snprintf(noticeBuf, sizeof(noticeBuf),
302                                          libpq_gettext("integer of size %lu not supported by pqGetInt\n"),
303                                          (unsigned long) bytes);
304                         DONOTICE(conn, noticeBuf);
305                         return EOF;
306         }
307
308         if (conn->Pfdebug)
309                 fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
310
311         return 0;
312 }
313
314 /*
315  * pgPutInt
316  * send an integer of 2 or 4 bytes, converting from host byte order
317  * to network byte order.
318  */
319 int
320 pqPutInt(int value, size_t bytes, PGconn *conn)
321 {
322         uint16          tmp2;
323         uint32          tmp4;
324         char            noticeBuf[64];
325
326         switch (bytes)
327         {
328                 case 2:
329                         tmp2 = htons((uint16) value);
330                         if (pqPutBytes((const char *) &tmp2, 2, conn))
331                                 return EOF;
332                         break;
333                 case 4:
334                         tmp4 = htonl((uint32) value);
335                         if (pqPutBytes((const char *) &tmp4, 4, conn))
336                                 return EOF;
337                         break;
338                 default:
339                         snprintf(noticeBuf, sizeof(noticeBuf),
340                                          libpq_gettext("integer of size %lu not supported by pqPutInt\n"),
341                                          (unsigned long) bytes);
342                         DONOTICE(conn, noticeBuf);
343                         return EOF;
344         }
345
346         if (conn->Pfdebug)
347                 fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
348
349         return 0;
350 }
351
352 /*
353  * pqReadReady: is select() saying the file is ready to read?
354  * Returns -1 on failure, 0 if not ready, 1 if ready.
355  */
356 int
357 pqReadReady(PGconn *conn)
358 {
359         fd_set          input_mask;
360         struct timeval timeout;
361
362         if (!conn || conn->sock < 0)
363                 return -1;
364
365 retry1:
366         FD_ZERO(&input_mask);
367         FD_SET(conn->sock, &input_mask);
368         timeout.tv_sec = 0;
369         timeout.tv_usec = 0;
370         if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
371                            &timeout) < 0)
372         {
373                 if (SOCK_ERRNO == EINTR)
374                         /* Interrupted system call - we'll just try again */
375                         goto retry1;
376
377                 printfPQExpBuffer(&conn->errorMessage,
378                                                   libpq_gettext("select() failed: %s\n"),
379                                                   SOCK_STRERROR(SOCK_ERRNO));
380                 return -1;
381         }
382
383         return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
384 }
385
386 /*
387  * pqWriteReady: is select() saying the file is ready to write?
388  * Returns -1 on failure, 0 if not ready, 1 if ready.
389  */
390 int
391 pqWriteReady(PGconn *conn)
392 {
393         fd_set          input_mask;
394         struct timeval timeout;
395
396         if (!conn || conn->sock < 0)
397                 return -1;
398
399 retry2:
400         FD_ZERO(&input_mask);
401         FD_SET(conn->sock, &input_mask);
402         timeout.tv_sec = 0;
403         timeout.tv_usec = 0;
404         if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
405                            &timeout) < 0)
406         {
407                 if (SOCK_ERRNO == EINTR)
408                         /* Interrupted system call - we'll just try again */
409                         goto retry2;
410
411                 printfPQExpBuffer(&conn->errorMessage,
412                                                   libpq_gettext("select() failed: %s\n"),
413                                                   SOCK_STRERROR(SOCK_ERRNO));
414                 return -1;
415         }
416         return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
417 }
418
419 /* ----------
420  * pqReadData: read more data, if any is available
421  * Possible return values:
422  *       1: successfully loaded at least one more byte
423  *       0: no data is presently available, but no error detected
424  *      -1: error detected (including EOF = connection closure);
425  *              conn->errorMessage set
426  * NOTE: callers must not assume that pointers or indexes into conn->inBuffer
427  * remain valid across this call!
428  * ----------
429  */
430 int
431 pqReadData(PGconn *conn)
432 {
433         int                     someread = 0;
434         int                     nread;
435
436         if (conn->sock < 0)
437         {
438                 printfPQExpBuffer(&conn->errorMessage,
439                                                   libpq_gettext("connection not open\n"));
440                 return -1;
441         }
442
443         /* Left-justify any data in the buffer to make room */
444         if (conn->inStart < conn->inEnd)
445         {
446                 if (conn->inStart > 0)
447                 {
448                         memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
449                                         conn->inEnd - conn->inStart);
450                         conn->inEnd -= conn->inStart;
451                         conn->inCursor -= conn->inStart;
452                         conn->inStart = 0;
453                 }
454         }
455         else
456         {
457                 /* buffer is logically empty, reset it */
458                 conn->inStart = conn->inCursor = conn->inEnd = 0;
459         }
460
461         /*
462          * If the buffer is fairly full, enlarge it. We need to be able to
463          * enlarge the buffer in case a single message exceeds the initial
464          * buffer size.  We enlarge before filling the buffer entirely so as
465          * to avoid asking the kernel for a partial packet. The magic constant
466          * here should be large enough for a TCP packet or Unix pipe
467          * bufferload.  8K is the usual pipe buffer size, so...
468          */
469         if (conn->inBufSize - conn->inEnd < 8192)
470         {
471                 int                     newSize = conn->inBufSize * 2;
472                 char       *newBuf = (char *) realloc(conn->inBuffer, newSize);
473
474                 if (newBuf)
475                 {
476                         conn->inBuffer = newBuf;
477                         conn->inBufSize = newSize;
478                 }
479         }
480
481         /* OK, try to read some data */
482 retry3:
483         nread = secure_read(conn, conn->inBuffer + conn->inEnd,
484                                                 conn->inBufSize - conn->inEnd);
485         if (nread < 0)
486         {
487                 if (SOCK_ERRNO == EINTR)
488                         goto retry3;
489                 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
490 #ifdef EAGAIN
491                 if (SOCK_ERRNO == EAGAIN)
492                         return someread;
493 #endif
494 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
495                 if (SOCK_ERRNO == EWOULDBLOCK)
496                         return someread;
497 #endif
498                 /* We might get ECONNRESET here if using TCP and backend died */
499 #ifdef ECONNRESET
500                 if (SOCK_ERRNO == ECONNRESET)
501                         goto definitelyFailed;
502 #endif
503                 printfPQExpBuffer(&conn->errorMessage,
504                            libpq_gettext("could not receive data from server: %s\n"),
505                                                   SOCK_STRERROR(SOCK_ERRNO));
506                 return -1;
507         }
508         if (nread > 0)
509         {
510                 conn->inEnd += nread;
511
512                 /*
513                  * Hack to deal with the fact that some kernels will only give us
514                  * back 1 packet per recv() call, even if we asked for more and
515                  * there is more available.  If it looks like we are reading a
516                  * long message, loop back to recv() again immediately, until we
517                  * run out of data or buffer space.  Without this, the
518                  * block-and-restart behavior of libpq's higher levels leads to
519                  * O(N^2) performance on long messages.
520                  *
521                  * Since we left-justified the data above, conn->inEnd gives the
522                  * amount of data already read in the current message.  We
523                  * consider the message "long" once we have acquired 32k ...
524                  */
525                 if (conn->inEnd > 32768 &&
526                         (conn->inBufSize - conn->inEnd) >= 8192)
527                 {
528                         someread = 1;
529                         goto retry3;
530                 }
531                 return 1;
532         }
533
534         if (someread)
535                 return 1;                               /* got a zero read after successful tries */
536
537         /*
538          * A return value of 0 could mean just that no data is now available,
539          * or it could mean EOF --- that is, the server has closed the
540          * connection. Since we have the socket in nonblock mode, the only way
541          * to tell the difference is to see if select() is saying that the
542          * file is ready. Grumble.      Fortunately, we don't expect this path to
543          * be taken much, since in normal practice we should not be trying to
544          * read data unless the file selected for reading already.
545          */
546         switch (pqReadReady(conn))
547         {
548                 case 0:
549                         /* definitely no data available */
550                         return 0;
551                 case 1:
552                         /* ready for read */
553                         break;
554                 default:
555                         goto definitelyFailed;
556         }
557
558         /*
559          * Still not sure that it's EOF, because some data could have just
560          * arrived.
561          */
562 retry4:
563         nread = secure_read(conn, conn->inBuffer + conn->inEnd,
564                                                 conn->inBufSize - conn->inEnd);
565         if (nread < 0)
566         {
567                 if (SOCK_ERRNO == EINTR)
568                         goto retry4;
569                 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
570 #ifdef EAGAIN
571                 if (SOCK_ERRNO == EAGAIN)
572                         return 0;
573 #endif
574 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
575                 if (SOCK_ERRNO == EWOULDBLOCK)
576                         return 0;
577 #endif
578                 /* We might get ECONNRESET here if using TCP and backend died */
579 #ifdef ECONNRESET
580                 if (SOCK_ERRNO == ECONNRESET)
581                         goto definitelyFailed;
582 #endif
583                 printfPQExpBuffer(&conn->errorMessage,
584                            libpq_gettext("could not receive data from server: %s\n"),
585                                                   SOCK_STRERROR(SOCK_ERRNO));
586                 return -1;
587         }
588         if (nread > 0)
589         {
590                 conn->inEnd += nread;
591                 return 1;
592         }
593
594         /*
595          * OK, we are getting a zero read even though select() says ready.
596          * This means the connection has been closed.  Cope.
597          */
598 definitelyFailed:
599         printfPQExpBuffer(&conn->errorMessage,
600                                           libpq_gettext(
601                                                         "server closed the connection unexpectedly\n"
602                            "\tThis probably means the server terminated abnormally\n"
603                                                  "\tbefore or while processing the request.\n"));
604         conn->status = CONNECTION_BAD;          /* No more connection to backend */
605         secure_close(conn);
606 #ifdef WIN32
607         closesocket(conn->sock);
608 #else
609         close(conn->sock);
610 #endif
611         conn->sock = -1;
612
613         return -1;
614 }
615
616 /*
617  * pqSendSome: send any data waiting in the output buffer.
618  *
619  * Return 0 on sucess, -1 on failure and 1 when data remains because the
620  * socket would block and the connection is non-blocking.
621  */
622 int
623 pqSendSome(PGconn *conn)
624 {
625         char       *ptr = conn->outBuffer;
626         int                     len = conn->outCount;
627
628         if (conn->sock < 0)
629         {
630                 printfPQExpBuffer(&conn->errorMessage,
631                                                   libpq_gettext("connection not open\n"));
632                 return -1;
633         }
634
635         /*
636          * don't try to send zero data, allows us to use this function without
637          * too much worry about overhead
638          */
639         if (len == 0)
640                 return (0);
641
642         /* while there's still data to send */
643         while (len > 0)
644         {
645                 int                     sent;
646
647                 sent = secure_write(conn, ptr, len);
648
649                 if (sent < 0)
650                 {
651                         /*
652                          * Anything except EAGAIN or EWOULDBLOCK is trouble. If it's
653                          * EPIPE or ECONNRESET, assume we've lost the backend
654                          * connection permanently.
655                          */
656                         switch (SOCK_ERRNO)
657                         {
658 #ifdef EAGAIN
659                                 case EAGAIN:
660                                         break;
661 #endif
662 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
663                                 case EWOULDBLOCK:
664                                         break;
665 #endif
666                                 case EINTR:
667                                         continue;
668
669                                 case EPIPE:
670 #ifdef ECONNRESET
671                                 case ECONNRESET:
672 #endif
673                                         printfPQExpBuffer(&conn->errorMessage,
674                                                                           libpq_gettext(
675                                                         "server closed the connection unexpectedly\n"
676                                    "\tThis probably means the server terminated abnormally\n"
677                                                  "\tbefore or while processing the request.\n"));
678
679                                         /*
680                                          * We used to close the socket here, but that's a bad
681                                          * idea since there might be unread data waiting
682                                          * (typically, a WARNING message from the backend
683                                          * telling us it's committing hara-kiri...).  Leave
684                                          * the socket open until pqReadData finds no more data
685                                          * can be read.
686                                          */
687                                         return -1;
688
689                                 default:
690                                         printfPQExpBuffer(&conn->errorMessage,
691                                         libpq_gettext("could not send data to server: %s\n"),
692                                                                           SOCK_STRERROR(SOCK_ERRNO));
693                                         /* We don't assume it's a fatal error... */
694                                         return -1;
695                         }
696                 }
697                 else
698                 {
699                         ptr += sent;
700                         len -= sent;
701                 }
702
703                 if (len > 0)
704                 {
705                         /* We didn't send it all, wait till we can send more */
706
707                         /*
708                          * if the socket is in non-blocking mode we may need to abort
709                          * here and return 1 to indicate that data is still pending.
710                          */
711 #ifdef USE_SSL
712                         /* can't do anything for our SSL users yet */
713                         if (conn->ssl == NULL)
714                         {
715 #endif
716                                 if (pqIsnonblocking(conn))
717                                 {
718                                         /* shift the contents of the buffer */
719                                         memmove(conn->outBuffer, ptr, len);
720                                         conn->outCount = len;
721                                         return 1;
722                                 }
723 #ifdef USE_SSL
724                         }
725 #endif
726
727                         if (pqWait(FALSE, TRUE, conn))
728                                 return -1;
729                 }
730         }
731
732         conn->outCount = 0;
733
734         if (conn->Pfdebug)
735                 fflush(conn->Pfdebug);
736
737         return 0;
738 }
739
740
741
742 /*
743  * pqFlush: send any data waiting in the output buffer
744  *
745  * Implemented in terms of pqSendSome to recreate the old behavior which
746  * returned 0 if all data was sent or EOF. EOF was sent regardless of
747  * whether an error occurred or not all data was sent on a non-blocking
748  * socket.
749  */
750 int
751 pqFlush(PGconn *conn)
752 {
753         if (pqSendSome(conn))
754         {
755                 return EOF;
756         }
757         return 0;
758 }
759
760 /*
761  * pqWait: wait until we can read or write the connection socket
762  *
763  * We also stop waiting and return if the kernel flags an exception condition
764  * on the socket.  The actual error condition will be detected and reported
765  * when the caller tries to read or write the socket.
766  */
767 int
768 pqWait(int forRead, int forWrite, PGconn *conn)
769 {
770         fd_set          input_mask;
771         fd_set          output_mask;
772         fd_set          except_mask;
773
774         if (conn->sock < 0)
775         {
776                 printfPQExpBuffer(&conn->errorMessage,
777                                                   libpq_gettext("connection not open\n"));
778                 return EOF;
779         }
780
781         if (forRead || forWrite)
782         {
783 retry5:
784                 FD_ZERO(&input_mask);
785                 FD_ZERO(&output_mask);
786                 FD_ZERO(&except_mask);
787                 if (forRead)
788                         FD_SET(conn->sock, &input_mask);
789                 if (forWrite)
790                         FD_SET(conn->sock, &output_mask);
791                 FD_SET(conn->sock, &except_mask);
792                 if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
793                                    (struct timeval *) NULL) < 0)
794                 {
795                         if (SOCK_ERRNO == EINTR)
796                                 goto retry5;
797                         printfPQExpBuffer(&conn->errorMessage,
798                                                           libpq_gettext("select() failed: %s\n"),
799                                                           SOCK_STRERROR(SOCK_ERRNO));
800                         return EOF;
801                 }
802         }
803
804         return 0;
805 }
806
807
808
809 /*
810  * A couple of "miscellaneous" multibyte related functions. They used
811  * to be in fe-print.c but that file is doomed.
812  */
813
814 #ifdef MULTIBYTE
815 /*
816  * returns the byte length of the word beginning s, using the
817  * specified encoding.
818  */
819 int
820 PQmblen(const unsigned char *s, int encoding)
821 {
822         return (pg_encoding_mblen(encoding, s));
823 }
824
825 /*
826  * Get encoding id from environment variable PGCLIENTENCODING.
827  */
828 int
829 PQenv2encoding(void)
830 {
831         char       *str;
832         int                     encoding = PG_SQL_ASCII;
833
834         str = getenv("PGCLIENTENCODING");
835         if (str && *str != '\0')
836                 encoding = pg_char_to_encoding(str);
837         return (encoding);
838 }
839
840 #else
841
842 /* Provide a default definition in case someone calls it anyway */
843 int
844 PQmblen(const unsigned char *s, int encoding)
845 {
846         (void) s;
847         (void) encoding;
848         return 1;
849 }
850 int
851 PQenv2encoding(void)
852 {
853         return 0;
854 }
855 #endif   /* MULTIBYTE */
856
857
858 #ifdef ENABLE_NLS
859 char *
860 libpq_gettext(const char *msgid)
861 {
862         static int      already_bound = 0;
863
864         if (!already_bound)
865         {
866                 already_bound = 1;
867                 bindtextdomain("libpq", LOCALEDIR);
868         }
869
870         return dgettext("libpq", msgid);
871 }
872 #endif   /* ENABLE_NLS */