1 /*-------------------------------------------------------------------------
7 * miscellaneous useful functions
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.
15 * XXX: MOVE DEBUG PRINTOUT TO HIGHER LEVEL. As is, block and restart
16 * will cause repeat printouts.
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.
23 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
24 * Portions Copyright (c) 1994, Regents of the University of California
28 * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.73 2002/06/14 04:23:17 momjian Exp $
30 *-------------------------------------------------------------------------
33 #include "postgres_fe.h"
46 #ifdef HAVE_SYS_SELECT_H
47 #include <sys/select.h>
51 #include "libpq-int.h"
55 #include "mb/pg_wchar.h"
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);
62 #define DONOTICE(conn,message) \
63 ((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
65 static int pqPutBytes(const char *s, size_t nbytes, PGconn *conn);
70 * get a character from the connection
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.
77 pqGetc(char *result, PGconn *conn)
79 if (conn->inCursor >= conn->inEnd)
82 *result = conn->inBuffer[conn->inCursor++];
85 fprintf(conn->Pfdebug, "From backend> %c\n", *result);
92 * write 1 char to the connection
95 pqPutc(char c, PGconn *conn)
97 if (pqPutBytes(&c, 1, conn) == EOF)
101 fprintf(conn->Pfdebug, "To backend> %c\n", c);
108 * pqPutBytes: local routine to write N bytes to the connection,
112 pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
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.
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
125 size_t avail, remaining;
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;
135 /* if the data didn't fit completely into the buffer, try to
136 * flush the buffer */
139 int send_result = pqSendSome(conn);
141 /* if there were errors, report them */
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
152 /* try to grow the buffer.
153 * FIXME: The new size could be chosen more
156 size_t buflen = conn->outCount + nbytes;
157 if (buflen > conn->outBufSize)
159 char * newbuf = realloc(conn->outBuffer, buflen);
162 /* realloc failed. Probably out of memory */
163 printfPQExpBuffer(&conn->errorMessage,
164 "cannot allocate memory for output buffer\n");
167 conn->outBuffer = newbuf;
168 conn->outBufSize = buflen;
170 /* put the data into it */
171 memcpy(conn->outBuffer + conn->outCount, s, nbytes);
172 conn->outCount += nbytes;
174 /* report success. */
179 /* pqSendSome was able to send all data. Continue with the next
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.
194 pqGets(PQExpBuffer buf, PGconn *conn)
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;
202 while (inCursor < inEnd && inBuffer[inCursor])
205 if (inCursor >= inEnd)
208 slen = inCursor - conn->inCursor;
210 resetPQExpBuffer(buf);
211 appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
213 conn->inCursor = ++inCursor;
216 fprintf(conn->Pfdebug, "From backend> \"%s\"\n",
224 pqPuts(const char *s, PGconn *conn)
226 if (pqPutBytes(s, strlen(s) + 1, conn))
230 fprintf(conn->Pfdebug, "To backend> %s\n", s);
237 * get a string of exactly len bytes in buffer s, no null termination
240 pqGetnchar(char *s, size_t len, PGconn *conn)
242 if (len < 0 || len > conn->inEnd - conn->inCursor)
245 memcpy(s, conn->inBuffer + conn->inCursor, len);
246 /* no terminating null */
248 conn->inCursor += len;
251 fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long) len, (int) len, s);
258 * send a string of exactly len bytes, no null termination needed
261 pqPutnchar(const char *s, size_t len, PGconn *conn)
263 if (pqPutBytes(s, len, conn))
267 fprintf(conn->Pfdebug, "To backend> %.*s\n", (int) len, s);
274 * read a 2 or 4 byte integer and convert from network byte order
275 * to local byte order
278 pqGetInt(int *result, size_t bytes, PGconn *conn)
287 if (conn->inCursor + 2 > conn->inEnd)
289 memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
291 *result = (int) ntohs(tmp2);
294 if (conn->inCursor + 4 > conn->inEnd)
296 memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
298 *result = (int) ntohl(tmp4);
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);
309 fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
316 * send an integer of 2 or 4 bytes, converting from host byte order
317 * to network byte order.
320 pqPutInt(int value, size_t bytes, PGconn *conn)
329 tmp2 = htons((uint16) value);
330 if (pqPutBytes((const char *) &tmp2, 2, conn))
334 tmp4 = htonl((uint32) value);
335 if (pqPutBytes((const char *) &tmp4, 4, conn))
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);
347 fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
353 * pqReadReady: is select() saying the file is ready to read?
354 * Returns -1 on failure, 0 if not ready, 1 if ready.
357 pqReadReady(PGconn *conn)
360 struct timeval timeout;
362 if (!conn || conn->sock < 0)
366 FD_ZERO(&input_mask);
367 FD_SET(conn->sock, &input_mask);
370 if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
373 if (SOCK_ERRNO == EINTR)
374 /* Interrupted system call - we'll just try again */
377 printfPQExpBuffer(&conn->errorMessage,
378 libpq_gettext("select() failed: %s\n"),
379 SOCK_STRERROR(SOCK_ERRNO));
383 return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
387 * pqWriteReady: is select() saying the file is ready to write?
388 * Returns -1 on failure, 0 if not ready, 1 if ready.
391 pqWriteReady(PGconn *conn)
394 struct timeval timeout;
396 if (!conn || conn->sock < 0)
400 FD_ZERO(&input_mask);
401 FD_SET(conn->sock, &input_mask);
404 if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
407 if (SOCK_ERRNO == EINTR)
408 /* Interrupted system call - we'll just try again */
411 printfPQExpBuffer(&conn->errorMessage,
412 libpq_gettext("select() failed: %s\n"),
413 SOCK_STRERROR(SOCK_ERRNO));
416 return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
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!
431 pqReadData(PGconn *conn)
438 printfPQExpBuffer(&conn->errorMessage,
439 libpq_gettext("connection not open\n"));
443 /* Left-justify any data in the buffer to make room */
444 if (conn->inStart < conn->inEnd)
446 if (conn->inStart > 0)
448 memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
449 conn->inEnd - conn->inStart);
450 conn->inEnd -= conn->inStart;
451 conn->inCursor -= conn->inStart;
457 /* buffer is logically empty, reset it */
458 conn->inStart = conn->inCursor = conn->inEnd = 0;
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...
469 if (conn->inBufSize - conn->inEnd < 8192)
471 int newSize = conn->inBufSize * 2;
472 char *newBuf = (char *) realloc(conn->inBuffer, newSize);
476 conn->inBuffer = newBuf;
477 conn->inBufSize = newSize;
481 /* OK, try to read some data */
483 nread = secure_read(conn, conn->inBuffer + conn->inEnd,
484 conn->inBufSize - conn->inEnd);
487 if (SOCK_ERRNO == EINTR)
489 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
491 if (SOCK_ERRNO == EAGAIN)
494 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
495 if (SOCK_ERRNO == EWOULDBLOCK)
498 /* We might get ECONNRESET here if using TCP and backend died */
500 if (SOCK_ERRNO == ECONNRESET)
501 goto definitelyFailed;
503 printfPQExpBuffer(&conn->errorMessage,
504 libpq_gettext("could not receive data from server: %s\n"),
505 SOCK_STRERROR(SOCK_ERRNO));
510 conn->inEnd += nread;
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.
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 ...
525 if (conn->inEnd > 32768 &&
526 (conn->inBufSize - conn->inEnd) >= 8192)
535 return 1; /* got a zero read after successful tries */
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.
546 switch (pqReadReady(conn))
549 /* definitely no data available */
555 goto definitelyFailed;
559 * Still not sure that it's EOF, because some data could have just
563 nread = secure_read(conn, conn->inBuffer + conn->inEnd,
564 conn->inBufSize - conn->inEnd);
567 if (SOCK_ERRNO == EINTR)
569 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
571 if (SOCK_ERRNO == EAGAIN)
574 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
575 if (SOCK_ERRNO == EWOULDBLOCK)
578 /* We might get ECONNRESET here if using TCP and backend died */
580 if (SOCK_ERRNO == ECONNRESET)
581 goto definitelyFailed;
583 printfPQExpBuffer(&conn->errorMessage,
584 libpq_gettext("could not receive data from server: %s\n"),
585 SOCK_STRERROR(SOCK_ERRNO));
590 conn->inEnd += nread;
595 * OK, we are getting a zero read even though select() says ready.
596 * This means the connection has been closed. Cope.
599 printfPQExpBuffer(&conn->errorMessage,
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 */
607 closesocket(conn->sock);
617 * pqSendSome: send any data waiting in the output buffer.
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.
623 pqSendSome(PGconn *conn)
625 char *ptr = conn->outBuffer;
626 int len = conn->outCount;
630 printfPQExpBuffer(&conn->errorMessage,
631 libpq_gettext("connection not open\n"));
636 * don't try to send zero data, allows us to use this function without
637 * too much worry about overhead
642 /* while there's still data to send */
647 sent = secure_write(conn, ptr, len);
652 * Anything except EAGAIN or EWOULDBLOCK is trouble. If it's
653 * EPIPE or ECONNRESET, assume we've lost the backend
654 * connection permanently.
662 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
673 printfPQExpBuffer(&conn->errorMessage,
675 "server closed the connection unexpectedly\n"
676 "\tThis probably means the server terminated abnormally\n"
677 "\tbefore or while processing the request.\n"));
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
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... */
705 /* We didn't send it all, wait till we can send more */
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.
712 /* can't do anything for our SSL users yet */
713 if (conn->ssl == NULL)
716 if (pqIsnonblocking(conn))
718 /* shift the contents of the buffer */
719 memmove(conn->outBuffer, ptr, len);
720 conn->outCount = len;
727 if (pqWait(FALSE, TRUE, conn))
735 fflush(conn->Pfdebug);
743 * pqFlush: send any data waiting in the output buffer
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
751 pqFlush(PGconn *conn)
753 if (pqSendSome(conn))
761 * pqWait: wait until we can read or write the connection socket
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.
768 pqWait(int forRead, int forWrite, PGconn *conn)
776 printfPQExpBuffer(&conn->errorMessage,
777 libpq_gettext("connection not open\n"));
781 if (forRead || forWrite)
784 FD_ZERO(&input_mask);
785 FD_ZERO(&output_mask);
786 FD_ZERO(&except_mask);
788 FD_SET(conn->sock, &input_mask);
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)
795 if (SOCK_ERRNO == EINTR)
797 printfPQExpBuffer(&conn->errorMessage,
798 libpq_gettext("select() failed: %s\n"),
799 SOCK_STRERROR(SOCK_ERRNO));
810 * A couple of "miscellaneous" multibyte related functions. They used
811 * to be in fe-print.c but that file is doomed.
816 * returns the byte length of the word beginning s, using the
817 * specified encoding.
820 PQmblen(const unsigned char *s, int encoding)
822 return (pg_encoding_mblen(encoding, s));
826 * Get encoding id from environment variable PGCLIENTENCODING.
832 int encoding = PG_SQL_ASCII;
834 str = getenv("PGCLIENTENCODING");
835 if (str && *str != '\0')
836 encoding = pg_char_to_encoding(str);
842 /* Provide a default definition in case someone calls it anyway */
844 PQmblen(const unsigned char *s, int encoding)
855 #endif /* MULTIBYTE */
860 libpq_gettext(const char *msgid)
862 static int already_bound = 0;
867 bindtextdomain("libpq", LOCALEDIR);
870 return dgettext("libpq", msgid);
872 #endif /* ENABLE_NLS */