fe-misc.c 23.8 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3 4
 *	 FILE
 *		fe-misc.c
5
 *
6 7
 *	 DESCRIPTION
 *		 miscellaneous useful functions
Bruce Momjian's avatar
Bruce Momjian committed
8 9 10 11 12 13 14 15 16 17 18
 *
 * The communication routines here are analogous to the ones in
 * backend/libpq/pqcomm.c and backend/libpq/pqcomprim.c, but operate
 * in the considerably different environment of the frontend libpq.
 * In particular, we work with a bare nonblock-mode socket, rather than
 * a stdio stream, so that we can avoid unwanted blocking of the application.
 *
 * XXX: MOVE DEBUG PRINTOUT TO HIGHER LEVEL.  As is, block and restart
 * will cause repeat printouts.
 *
 * We must speak the same transmitted data representations as the backend
19 20
 * routines.
 *
21
 *
Bruce Momjian's avatar
Bruce Momjian committed
22
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
Bruce Momjian's avatar
Add:  
Bruce Momjian committed
23
 * Portions Copyright (c) 1994, Regents of the University of California
24 25
 *
 * IDENTIFICATION
26
 *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.89 2003/04/19 00:02:30 tgl Exp $
27 28 29 30
 *
 *-------------------------------------------------------------------------
 */

31
#include "postgres_fe.h"
32

33 34 35
#include <errno.h>
#include <signal.h>
#include <time.h>
36 37
#include <netinet/in.h>
#include <arpa/inet.h>
38

Bruce Momjian's avatar
Bruce Momjian committed
39 40
#ifdef WIN32
#include "win32.h"
41 42
#else
#include <unistd.h>
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
43
#include <sys/time.h>
Bruce Momjian's avatar
Bruce Momjian committed
44
#endif
45

46 47 48 49 50 51
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
Bruce Momjian's avatar
Bruce Momjian committed
52 53 54
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
55

56 57 58
#include "libpq-fe.h"
#include "libpq-int.h"
#include "pqsignal.h"
59 60
#include "mb/pg_wchar.h"

61 62 63
#define DONOTICE(conn,message) \
	((*(conn)->noticeHook) ((conn)->noticeArg, (message)))

64 65
static int	pqPutMsgBytes(const void *buf, size_t len, PGconn *conn);
static int	pqSendSome(PGconn *conn, int len);
66 67 68
static int	pqSocketCheck(PGconn *conn, int forRead, int forWrite,
						  time_t end_time);
static int	pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time);
69

70

71
/*
72
 * pqGetc: get 1 character from the connection
73
 *
74 75 76
 *	All these routines return 0 on success, EOF on error.
 *	Note that for the Get routines, EOF only means there is not enough
 *	data in the buffer, not that there is necessarily a hard error.
77
 */
78
int
Bruce Momjian's avatar
Bruce Momjian committed
79
pqGetc(char *result, PGconn *conn)
80
{
Bruce Momjian's avatar
Bruce Momjian committed
81 82
	if (conn->inCursor >= conn->inEnd)
		return EOF;
83

Bruce Momjian's avatar
Bruce Momjian committed
84
	*result = conn->inBuffer[conn->inCursor++];
85

Bruce Momjian's avatar
Bruce Momjian committed
86 87
	if (conn->Pfdebug)
		fprintf(conn->Pfdebug, "From backend> %c\n", *result);
88

Bruce Momjian's avatar
Bruce Momjian committed
89
	return 0;
90 91
}

Bruce Momjian's avatar
Bruce Momjian committed
92

93
/*
94
 * pqPutc: write 1 char to the current message
95 96 97 98
 */
int
pqPutc(char c, PGconn *conn)
{
99
	if (pqPutMsgBytes(&c, 1, conn))
100 101 102 103 104 105 106 107 108
		return EOF;

	if (conn->Pfdebug)
		fprintf(conn->Pfdebug, "To backend> %c\n", c);

	return 0;
}


109 110 111 112 113 114 115
/*
 * pqGets:
 * get a null-terminated string from the connection,
 * and store it in an expansible PQExpBuffer.
 * If we run out of memory, all of the string is still read,
 * but the excess characters are silently discarded.
 */
116
int
117
pqGets(PQExpBuffer buf, PGconn *conn)
Bruce Momjian's avatar
Bruce Momjian committed
118 119
{
	/* Copy conn data to locals for faster search loop */
120 121 122 123
	char	   *inBuffer = conn->inBuffer;
	int			inCursor = conn->inCursor;
	int			inEnd = conn->inEnd;
	int			slen;
Bruce Momjian's avatar
Bruce Momjian committed
124 125 126 127 128 129 130 131

	while (inCursor < inEnd && inBuffer[inCursor])
		inCursor++;

	if (inCursor >= inEnd)
		return EOF;

	slen = inCursor - conn->inCursor;
132 133 134

	resetPQExpBuffer(buf);
	appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
Bruce Momjian's avatar
Bruce Momjian committed
135 136 137 138

	conn->inCursor = ++inCursor;

	if (conn->Pfdebug)
139 140
		fprintf(conn->Pfdebug, "From backend> \"%s\"\n",
				buf->data);
Bruce Momjian's avatar
Bruce Momjian committed
141 142 143 144

	return 0;
}

145

146 147 148
/*
 * pqPuts: write a null-terminated string to the current message
 */
Bruce Momjian's avatar
Bruce Momjian committed
149 150
int
pqPuts(const char *s, PGconn *conn)
151
{
152
	if (pqPutMsgBytes(s, strlen(s) + 1, conn))
Bruce Momjian's avatar
Bruce Momjian committed
153 154 155
		return EOF;

	if (conn->Pfdebug)
156
		fprintf(conn->Pfdebug, "To backend> '%s'\n", s);
157

Bruce Momjian's avatar
Bruce Momjian committed
158
	return 0;
159 160
}

161 162
/*
 * pqGetnchar:
163
 *	get a string of exactly len bytes in buffer s, no null termination
164
 */
165
int
Bruce Momjian's avatar
Bruce Momjian committed
166
pqGetnchar(char *s, size_t len, PGconn *conn)
167
{
168
	if (len < 0 || len > (size_t) (conn->inEnd - conn->inCursor))
Bruce Momjian's avatar
Bruce Momjian committed
169 170 171
		return EOF;

	memcpy(s, conn->inBuffer + conn->inCursor, len);
172
	/* no terminating null */
173

Bruce Momjian's avatar
Bruce Momjian committed
174
	conn->inCursor += len;
175

Bruce Momjian's avatar
Bruce Momjian committed
176
	if (conn->Pfdebug)
177
		fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long) len, (int) len, s);
178

Bruce Momjian's avatar
Bruce Momjian committed
179
	return 0;
180 181
}

182 183
/*
 * pqPutnchar:
184
 *	write exactly len bytes to the current message
185
 */
186
int
Bruce Momjian's avatar
Bruce Momjian committed
187
pqPutnchar(const char *s, size_t len, PGconn *conn)
188
{
189
	if (pqPutMsgBytes(s, len, conn))
Bruce Momjian's avatar
Bruce Momjian committed
190
		return EOF;
191

Bruce Momjian's avatar
Bruce Momjian committed
192
	if (conn->Pfdebug)
193
		fprintf(conn->Pfdebug, "To backend> %.*s\n", (int) len, s);
194

Bruce Momjian's avatar
Bruce Momjian committed
195
	return 0;
196 197
}

198 199
/*
 * pgGetInt
200 201
 *	read a 2 or 4 byte integer and convert from network byte order
 *	to local byte order
202
 */
203
int
Bruce Momjian's avatar
Bruce Momjian committed
204
pqGetInt(int *result, size_t bytes, PGconn *conn)
205
{
206 207
	uint16		tmp2;
	uint32		tmp4;
208
	char		noticeBuf[64];
209 210 211

	switch (bytes)
	{
212
		case 2:
Bruce Momjian's avatar
Bruce Momjian committed
213 214 215 216 217
			if (conn->inCursor + 2 > conn->inEnd)
				return EOF;
			memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
			conn->inCursor += 2;
			*result = (int) ntohs(tmp2);
218 219
			break;
		case 4:
Bruce Momjian's avatar
Bruce Momjian committed
220 221 222 223 224
			if (conn->inCursor + 4 > conn->inEnd)
				return EOF;
			memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
			conn->inCursor += 4;
			*result = (int) ntohl(tmp4);
225 226
			break;
		default:
227 228 229
			snprintf(noticeBuf, sizeof(noticeBuf),
					 libpq_gettext("integer of size %lu not supported by pqGetInt\n"),
					 (unsigned long) bytes);
230
			DONOTICE(conn, noticeBuf);
Bruce Momjian's avatar
Bruce Momjian committed
231
			return EOF;
232 233
	}

Bruce Momjian's avatar
Bruce Momjian committed
234
	if (conn->Pfdebug)
235
		fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
236

Bruce Momjian's avatar
Bruce Momjian committed
237
	return 0;
238 239
}

240 241
/*
 * pgPutInt
242
 * write an integer of 2 or 4 bytes, converting from host byte order
243 244
 * to network byte order.
 */
245
int
Bruce Momjian's avatar
Bruce Momjian committed
246
pqPutInt(int value, size_t bytes, PGconn *conn)
247
{
248 249
	uint16		tmp2;
	uint32		tmp4;
250
	char		noticeBuf[64];
251 252 253

	switch (bytes)
	{
254
		case 2:
Bruce Momjian's avatar
Bruce Momjian committed
255
			tmp2 = htons((uint16) value);
256
			if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
Bruce Momjian's avatar
Bruce Momjian committed
257
				return EOF;
258 259
			break;
		case 4:
Bruce Momjian's avatar
Bruce Momjian committed
260
			tmp4 = htonl((uint32) value);
261
			if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
Bruce Momjian's avatar
Bruce Momjian committed
262
				return EOF;
263 264
			break;
		default:
265 266 267
			snprintf(noticeBuf, sizeof(noticeBuf),
					 libpq_gettext("integer of size %lu not supported by pqPutInt\n"),
					 (unsigned long) bytes);
268
			DONOTICE(conn, noticeBuf);
Bruce Momjian's avatar
Bruce Momjian committed
269
			return EOF;
270 271
	}

Bruce Momjian's avatar
Bruce Momjian committed
272
	if (conn->Pfdebug)
273
		fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
274

Bruce Momjian's avatar
Bruce Momjian committed
275
	return 0;
276
}
277

278
/*
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
 * Make sure conn's output buffer can hold bytes_needed bytes (caller must
 * include existing outCount into the value!)
 *
 * Returns 0 on success, EOF on error
 */
static int
checkOutBufferSpace(int bytes_needed, PGconn *conn)
{
	int			newsize = conn->outBufSize;
	char	   *newbuf;

	if (bytes_needed <= newsize)
		return 0;
	/*
	 * If we need to enlarge the buffer, we first try to double it in size;
	 * if that doesn't work, enlarge in multiples of 8K.  This avoids
	 * thrashing the malloc pool by repeated small enlargements.
	 *
	 * Note: tests for newsize > 0 are to catch integer overflow.
	 */
	do {
		newsize *= 2;
	} while (bytes_needed > newsize && newsize > 0);

	if (bytes_needed <= newsize)
	{
		newbuf = realloc(conn->outBuffer, newsize);
		if (newbuf)
		{
			/* realloc succeeded */
			conn->outBuffer = newbuf;
			conn->outBufSize = newsize;
			return 0;
		}
	}

	newsize = conn->outBufSize;
	do {
		newsize += 8192;
	} while (bytes_needed > newsize && newsize > 0);

	if (bytes_needed <= newsize)
	{
		newbuf = realloc(conn->outBuffer, newsize);
		if (newbuf)
		{
			/* realloc succeeded */
			conn->outBuffer = newbuf;
			conn->outBufSize = newsize;
			return 0;
		}
	}

	/* realloc failed. Probably out of memory */
	printfPQExpBuffer(&conn->errorMessage,
					  "cannot allocate memory for output buffer\n");
	return EOF;
}

/*
 * pqPutMsgStart: begin construction of a message to the server
 *
 * msg_type is the message type byte, or 0 for a message without type byte
 * (only startup messages have no type byte)
 *
 * Returns 0 on success, EOF on error
 *
 * The idea here is that we construct the message in conn->outBuffer,
 * beginning just past any data already in outBuffer (ie, at
 * outBuffer+outCount).  We enlarge the buffer as needed to hold the message.
 * When the message is complete, we fill in the length word and then advance
 * outCount past the message, making it eligible to send.  The state
 * variable conn->outMsgStart points to the incomplete message's length word
 * (it is either outCount or outCount+1 depending on whether there is a
 * type byte).  The state variable conn->outMsgEnd is the end of the data
 * collected so far.
Bruce Momjian's avatar
Bruce Momjian committed
355
 */
356
int
357
pqPutMsgStart(char msg_type, PGconn *conn)
Bruce Momjian's avatar
Bruce Momjian committed
358
{
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
	int			lenPos;

	/* where the message length word will go */
	if (msg_type)
		lenPos = conn->outCount + 1;
	else
		lenPos = conn->outCount;
	/* make sure there is room for it */
	if (checkOutBufferSpace(lenPos + 4, conn))
		return EOF;
	/* okay, save the message type byte if any */
	if (msg_type)
		conn->outBuffer[conn->outCount] = msg_type;
	/* set up the message pointers */
	conn->outMsgStart = lenPos;
	conn->outMsgEnd = lenPos + 4;
	/* length word will be filled in by pqPutMsgEnd */

	if (conn->Pfdebug)
		fprintf(conn->Pfdebug, "To backend> Msg %c\n",
				msg_type ? msg_type : ' ');

	return 0;
382 383
}

384
/*
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
 * pqPutMsgBytes: add bytes to a partially-constructed message
 *
 * Returns 0 on success, EOF on error
 */
static int
pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
{
	/* make sure there is room for it */
	if (checkOutBufferSpace(conn->outMsgEnd + len, conn))
		return EOF;
	/* okay, save the data */
	memcpy(conn->outBuffer + conn->outMsgEnd, buf, len);
	conn->outMsgEnd += len;
	/* no Pfdebug call here, caller should do it */
	return 0;
}

/*
 * pqPutMsgEnd: finish constructing a message and possibly send it
 *
 * Returns 0 on success, EOF on error
 *
 * We don't actually send anything here unless we've accumulated at least
 * 8K worth of data (the typical size of a pipe buffer on Unix systems).
 * This avoids sending small partial packets.  The caller must use pqFlush
 * when it's important to flush all the data out to the server.
411 412
 */
int
413
pqPutMsgEnd(PGconn *conn)
414
{
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
	uint32		msgLen = conn->outMsgEnd - conn->outMsgStart;

	if (conn->Pfdebug)
		fprintf(conn->Pfdebug, "To backend> Msg complete, length %u\n",
				msgLen);

	msgLen = htonl(msgLen);
	memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
	conn->outCount = conn->outMsgEnd;

	if (conn->outCount >= 8192)
	{
		int		toSend = conn->outCount - (conn->outCount % 8192);

		if (pqSendSome(conn, toSend) < 0)
			return EOF;
		/* in nonblock mode, don't complain if unable to send it all */
	}

	return 0;
Bruce Momjian's avatar
Bruce Momjian committed
435 436
}

437 438
/* ----------
 * pqReadData: read more data, if any is available
Bruce Momjian's avatar
Bruce Momjian committed
439
 * Possible return values:
440 441 442 443
 *	 1: successfully loaded at least one more byte
 *	 0: no data is presently available, but no error detected
 *	-1: error detected (including EOF = connection closure);
 *		conn->errorMessage set
Bruce Momjian's avatar
Bruce Momjian committed
444 445
 * NOTE: callers must not assume that pointers or indexes into conn->inBuffer
 * remain valid across this call!
446
 * ----------
Bruce Momjian's avatar
Bruce Momjian committed
447
 */
448
int
Bruce Momjian's avatar
Bruce Momjian committed
449
pqReadData(PGconn *conn)
450
{
451
	int			someread = 0;
452
	int			nread;
Bruce Momjian's avatar
Bruce Momjian committed
453 454 455

	if (conn->sock < 0)
	{
456
		printfPQExpBuffer(&conn->errorMessage,
457
						  libpq_gettext("connection not open\n"));
Bruce Momjian's avatar
Bruce Momjian committed
458 459
		return -1;
	}
460

Bruce Momjian's avatar
Bruce Momjian committed
461 462 463
	/* Left-justify any data in the buffer to make room */
	if (conn->inStart < conn->inEnd)
	{
464 465 466 467 468 469 470 471
		if (conn->inStart > 0)
		{
			memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
					conn->inEnd - conn->inStart);
			conn->inEnd -= conn->inStart;
			conn->inCursor -= conn->inStart;
			conn->inStart = 0;
		}
Bruce Momjian's avatar
Bruce Momjian committed
472 473
	}
	else
474 475
	{
		/* buffer is logically empty, reset it */
Bruce Momjian's avatar
Bruce Momjian committed
476
		conn->inStart = conn->inCursor = conn->inEnd = 0;
477
	}
478 479 480 481 482 483

	/*
	 * If the buffer is fairly full, enlarge it. We need to be able to
	 * enlarge the buffer in case a single message exceeds the initial
	 * buffer size.  We enlarge before filling the buffer entirely so as
	 * to avoid asking the kernel for a partial packet. The magic constant
484
	 * here should be large enough for a TCP packet or Unix pipe
485
	 * bufferload.	8K is the usual pipe buffer size, so...
Bruce Momjian's avatar
Bruce Momjian committed
486
	 */
487
	if (conn->inBufSize - conn->inEnd < 8192)
Bruce Momjian's avatar
Bruce Momjian committed
488
	{
489 490 491
		int			newSize = conn->inBufSize * 2;
		char	   *newBuf = (char *) realloc(conn->inBuffer, newSize);

Bruce Momjian's avatar
Bruce Momjian committed
492 493 494 495 496 497
		if (newBuf)
		{
			conn->inBuffer = newBuf;
			conn->inBufSize = newSize;
		}
	}
498

Bruce Momjian's avatar
Bruce Momjian committed
499
	/* OK, try to read some data */
500
retry3:
501
	nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
Bruce Momjian's avatar
Bruce Momjian committed
502
						  conn->inBufSize - conn->inEnd);
Bruce Momjian's avatar
Bruce Momjian committed
503 504
	if (nread < 0)
	{
505
		if (SOCK_ERRNO == EINTR)
506
			goto retry3;
507 508
		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
509
		if (SOCK_ERRNO == EAGAIN)
510
			return someread;
511 512
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
513
		if (SOCK_ERRNO == EWOULDBLOCK)
514
			return someread;
515 516 517
#endif
		/* We might get ECONNRESET here if using TCP and backend died */
#ifdef ECONNRESET
518
		if (SOCK_ERRNO == ECONNRESET)
519
			goto definitelyFailed;
520
#endif
521
		printfPQExpBuffer(&conn->errorMessage,
522
			   libpq_gettext("could not receive data from server: %s\n"),
523
						  SOCK_STRERROR(SOCK_ERRNO));
Bruce Momjian's avatar
Bruce Momjian committed
524 525 526 527 528
		return -1;
	}
	if (nread > 0)
	{
		conn->inEnd += nread;
529

530 531
		/*
		 * Hack to deal with the fact that some kernels will only give us
532 533 534 535 536 537
		 * back 1 packet per recv() call, even if we asked for more and
		 * there is more available.  If it looks like we are reading a
		 * long message, loop back to recv() again immediately, until we
		 * run out of data or buffer space.  Without this, the
		 * block-and-restart behavior of libpq's higher levels leads to
		 * O(N^2) performance on long messages.
538 539
		 *
		 * Since we left-justified the data above, conn->inEnd gives the
540 541
		 * amount of data already read in the current message.	We
		 * consider the message "long" once we have acquired 32k ...
542 543 544 545 546
		 */
		if (conn->inEnd > 32768 &&
			(conn->inBufSize - conn->inEnd) >= 8192)
		{
			someread = 1;
547
			goto retry3;
548
		}
Bruce Momjian's avatar
Bruce Momjian committed
549 550
		return 1;
	}
551

552 553 554
	if (someread)
		return 1;				/* got a zero read after successful tries */

555 556 557 558 559 560 561 562
	/*
	 * A return value of 0 could mean just that no data is now available,
	 * or it could mean EOF --- that is, the server has closed the
	 * connection. Since we have the socket in nonblock mode, the only way
	 * to tell the difference is to see if select() is saying that the
	 * file is ready. Grumble.	Fortunately, we don't expect this path to
	 * be taken much, since in normal practice we should not be trying to
	 * read data unless the file selected for reading already.
Bruce Momjian's avatar
Bruce Momjian committed
563
	 */
564 565 566 567 568 569 570 571 572 573 574
	switch (pqReadReady(conn))
	{
		case 0:
			/* definitely no data available */
			return 0;
		case 1:
			/* ready for read */
			break;
		default:
			goto definitelyFailed;
	}
Bruce Momjian's avatar
Bruce Momjian committed
575

576 577 578
	/*
	 * Still not sure that it's EOF, because some data could have just
	 * arrived.
Bruce Momjian's avatar
Bruce Momjian committed
579
	 */
580
retry4:
581 582
	nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
						  conn->inBufSize - conn->inEnd);
Bruce Momjian's avatar
Bruce Momjian committed
583 584
	if (nread < 0)
	{
585
		if (SOCK_ERRNO == EINTR)
586
			goto retry4;
587 588
		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
589
		if (SOCK_ERRNO == EAGAIN)
590 591 592
			return 0;
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
593
		if (SOCK_ERRNO == EWOULDBLOCK)
594
			return 0;
595 596 597
#endif
		/* We might get ECONNRESET here if using TCP and backend died */
#ifdef ECONNRESET
598
		if (SOCK_ERRNO == ECONNRESET)
599
			goto definitelyFailed;
600
#endif
601
		printfPQExpBuffer(&conn->errorMessage,
602
			   libpq_gettext("could not receive data from server: %s\n"),
603
						  SOCK_STRERROR(SOCK_ERRNO));
Bruce Momjian's avatar
Bruce Momjian committed
604 605 606 607 608 609 610 611
		return -1;
	}
	if (nread > 0)
	{
		conn->inEnd += nread;
		return 1;
	}

612 613
	/*
	 * OK, we are getting a zero read even though select() says ready.
Bruce Momjian's avatar
Bruce Momjian committed
614 615
	 * This means the connection has been closed.  Cope.
	 */
616
definitelyFailed:
617
	printfPQExpBuffer(&conn->errorMessage,
618
					  libpq_gettext(
619 620 621
							"server closed the connection unexpectedly\n"
			   "\tThis probably means the server terminated abnormally\n"
						 "\tbefore or while processing the request.\n"));
622
	conn->status = CONNECTION_BAD;		/* No more connection to backend */
623
	pqsecure_close(conn);
Bruce Momjian's avatar
Bruce Momjian committed
624 625 626
#ifdef WIN32
	closesocket(conn->sock);
#else
Bruce Momjian's avatar
Bruce Momjian committed
627
	close(conn->sock);
Bruce Momjian's avatar
Bruce Momjian committed
628
#endif
Bruce Momjian's avatar
Bruce Momjian committed
629
	conn->sock = -1;
630

Bruce Momjian's avatar
Bruce Momjian committed
631
	return -1;
632 633
}

634
/*
635 636 637 638
 * pqSendSome: send data waiting in the output buffer.
 *
 * len is how much to try to send (typically equal to outCount, but may
 * be less).
639
 *
640 641
 * Return 0 on success, -1 on failure and 1 when not all data could be sent
 * because the socket would block and the connection is non-blocking.
Bruce Momjian's avatar
Bruce Momjian committed
642
 */
643 644
static int
pqSendSome(PGconn *conn, int len)
645
{
646
	char	   *ptr = conn->outBuffer;
647 648
	int			remaining = conn->outCount;
	int			result = 0;
Bruce Momjian's avatar
Bruce Momjian committed
649 650 651

	if (conn->sock < 0)
	{
652
		printfPQExpBuffer(&conn->errorMessage,
653
						  libpq_gettext("connection not open\n"));
654
		return -1;
Bruce Momjian's avatar
Bruce Momjian committed
655
	}
656

657
	/* while there's still data to send */
Bruce Momjian's avatar
Bruce Momjian committed
658 659
	while (len > 0)
	{
660
		int			sent;
661

662
		sent = pqsecure_write(conn, ptr, len);
663

Bruce Momjian's avatar
Bruce Momjian committed
664 665
		if (sent < 0)
		{
666
			/*
Bruce Momjian's avatar
Bruce Momjian committed
667 668 669
			 * Anything except EAGAIN or EWOULDBLOCK is trouble. If it's
			 * EPIPE or ECONNRESET, assume we've lost the backend
			 * connection permanently.
670
			 */
671
			switch (SOCK_ERRNO)
Bruce Momjian's avatar
Bruce Momjian committed
672 673 674 675 676 677 678 679 680
			{
#ifdef EAGAIN
				case EAGAIN:
					break;
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
				case EWOULDBLOCK:
					break;
#endif
681 682
				case EINTR:
					continue;
683

684 685 686 687
				case EPIPE:
#ifdef ECONNRESET
				case ECONNRESET:
#endif
688
					printfPQExpBuffer(&conn->errorMessage,
689
									  libpq_gettext(
690
							"server closed the connection unexpectedly\n"
Bruce Momjian's avatar
Bruce Momjian committed
691
													"\tThis probably means the server terminated abnormally\n"
692
						 "\tbefore or while processing the request.\n"));
693

694 695 696
					/*
					 * We used to close the socket here, but that's a bad
					 * idea since there might be unread data waiting
697
					 * (typically, a NOTICE message from the backend
698 699
					 * telling us it's committing hara-kiri...).  Leave
					 * the socket open until pqReadData finds no more data
700
					 * can be read.  But abandon attempt to send data.
701
					 */
702
					conn->outCount = 0;
703
					return -1;
704

Bruce Momjian's avatar
Bruce Momjian committed
705
				default:
706
					printfPQExpBuffer(&conn->errorMessage,
707
					libpq_gettext("could not send data to server: %s\n"),
708
									  SOCK_STRERROR(SOCK_ERRNO));
709
					/* We don't assume it's a fatal error... */
710
					conn->outCount = 0;
711
					return -1;
Bruce Momjian's avatar
Bruce Momjian committed
712 713 714 715 716 717
			}
		}
		else
		{
			ptr += sent;
			len -= sent;
718
			remaining -= sent;
Bruce Momjian's avatar
Bruce Momjian committed
719
		}
720

Bruce Momjian's avatar
Bruce Momjian committed
721 722 723
		if (len > 0)
		{
			/* We didn't send it all, wait till we can send more */
724

725 726
			/*
			 * if the socket is in non-blocking mode we may need to abort
727
			 * here and return 1 to indicate that data is still pending.
728 729 730
			 */
#ifdef USE_SSL
			/* can't do anything for our SSL users yet */
731
			if (conn->ssl == NULL)
732 733 734 735
			{
#endif
				if (pqIsnonblocking(conn))
				{
736 737
					result = 1;
					break;
738 739 740 741 742
				}
#ifdef USE_SSL
			}
#endif

Bruce Momjian's avatar
Bruce Momjian committed
743
			if (pqWait(FALSE, TRUE, conn))
744 745 746 747
			{
				result = -1;
				break;
			}
Bruce Momjian's avatar
Bruce Momjian committed
748 749 750
		}
	}

751 752 753 754
	/* shift the remaining contents of the buffer */
	if (remaining > 0)
		memmove(conn->outBuffer, ptr, remaining);
	conn->outCount = remaining;
Bruce Momjian's avatar
Bruce Momjian committed
755

756
	return result;
757
}
758

759 760 761 762

/*
 * pqFlush: send any data waiting in the output buffer
 *
763 764
 * Return 0 on success, -1 on failure and 1 when not all data could be sent
 * because the socket would block and the connection is non-blocking.
765 766 767 768
 */
int
pqFlush(PGconn *conn)
{
769 770 771 772 773 774
	if (conn->Pfdebug)
		fflush(conn->Pfdebug);

	if (conn->outCount > 0)
		return pqSendSome(conn, conn->outCount);

775 776 777
	return 0;
}

778

779 780
/*
 * pqWait: wait until we can read or write the connection socket
781
 *
782 783 784
 * JAB: If SSL enabled and used and forRead, buffered bytes short-circuit the
 * call to select().
 *
785 786 787
 * We also stop waiting and return if the kernel flags an exception condition
 * on the socket.  The actual error condition will be detected and reported
 * when the caller tries to read or write the socket.
Bruce Momjian's avatar
Bruce Momjian committed
788 789 790
 */
int
pqWait(int forRead, int forWrite, PGconn *conn)
791
{
792
	return pqWaitTimed(forRead, forWrite, conn, (time_t) -1);
793 794
}

795 796 797
/*
 * pqWaitTimed: wait, but not past finish_time.
 *
798 799 800
 * If finish_time is exceeded then we return failure (EOF).  This is like
 * the response for a kernel exception because we don't want the caller
 * to try to read/write in that case.
801 802 803
 *
 * finish_time = ((time_t) -1) disables the wait limit.
 */
804
int
805
pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Bruce Momjian's avatar
Bruce Momjian committed
806
{
807
	int result;
808

809 810 811 812 813 814
	result = pqSocketCheck(conn, forRead, forWrite, finish_time);

	if (result < 0)
		return EOF;				/* errorMessage is already set */

	if (result == 0)
Bruce Momjian's avatar
Bruce Momjian committed
815
	{
816
		printfPQExpBuffer(&conn->errorMessage,
817
						  libpq_gettext("timeout expired\n"));
818
		return EOF;
Bruce Momjian's avatar
Bruce Momjian committed
819 820
	}

821 822 823
	return 0;
}

824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
/*
 * pqReadReady: is select() saying the file is ready to read?
 * Returns -1 on failure, 0 if not ready, 1 if ready.
 */
int
pqReadReady(PGconn *conn)
{
	return pqSocketCheck(conn, 1, 0, (time_t) 0);
}

/*
 * pqWriteReady: is select() saying the file is ready to write?
 * Returns -1 on failure, 0 if not ready, 1 if ready.
 */
int
pqWriteReady(PGconn *conn)
{
	return pqSocketCheck(conn, 0, 1, (time_t) 0);
}

844 845 846 847
/*
 * Checks a socket, using poll or select, for data to be read, written,
 * or both.  Returns >0 if one or more conditions are met, 0 if it timed
 * out, -1 if an error occurred.
848
 *
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
 * If SSL is in use, the SSL buffer is checked prior to checking the socket
 * for read data directly.
 */
static int
pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
{
	int result;

	if (!conn)
		return -1;
	if (conn->sock < 0)
	{
		printfPQExpBuffer(&conn->errorMessage,
		                  libpq_gettext("socket not open\n"));
		return -1;
	}

866
#ifdef USE_SSL
867
	/* Check for SSL library buffering read bytes */
868 869 870
	if (forRead && conn->ssl && SSL_pending(conn->ssl) > 0)
	{
		/* short-circuit the select */
871
		return 1;
872 873 874
	}
#endif

875 876
	/* We will retry as long as we get EINTR */
	do
877
	{
878 879 880
		result = pqSocketPoll(conn->sock, forRead, forWrite, end_time);
	}
	while (result < 0 && SOCK_ERRNO == EINTR);
881

882 883 884 885 886
	if (result < 0)
	{
		printfPQExpBuffer(&conn->errorMessage,
		                  libpq_gettext("select() failed: %s\n"),
		                  SOCK_STRERROR(SOCK_ERRNO));
Bruce Momjian's avatar
Bruce Momjian committed
887 888
	}

889
	return result;
Bruce Momjian's avatar
Bruce Momjian committed
890
}
891 892


893 894 895 896 897
/*
 * Check a file descriptor for read and/or write data, possibly waiting.
 * If neither forRead nor forWrite are set, immediately return a timeout
 * condition (without waiting).  Return >0 if condition is met, 0
 * if a timeout occurred, -1 if an error or interrupt occurred.
898
 *
899 900 901 902 903 904 905 906 907 908 909
 * Timeout is infinite if end_time is -1.  Timeout is immediate (no blocking)
 * if end_time is 0 (or indeed, any time before now).
 */
static int
pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
{
	/* We use poll(2) if available, otherwise select(2) */
#ifdef HAVE_POLL
	struct pollfd input_fd;
	int           timeout_ms;

910 911 912
	if (!forRead && !forWrite)
		return 0;

913
	input_fd.fd      = sock;
914
	input_fd.events  = POLLERR;
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
	input_fd.revents = 0;

	if (forRead)
		input_fd.events |= POLLIN;
	if (forWrite)
		input_fd.events |= POLLOUT;

	/* Compute appropriate timeout interval */
	if (end_time == ((time_t) -1))
	{
		timeout_ms = -1;
	}
	else
	{
		time_t now = time(NULL);

		if (end_time > now)
			timeout_ms = (end_time - now) * 1000;
		else
			timeout_ms = 0;
	}

	return poll(&input_fd, 1, timeout_ms);

#else /* !HAVE_POLL */

	fd_set          input_mask;
	fd_set          output_mask;
	fd_set          except_mask;
	struct timeval  timeout;
	struct timeval *ptr_timeout;

	if (!forRead && !forWrite)
		return 0;

	FD_ZERO(&input_mask);
	FD_ZERO(&output_mask);
	FD_ZERO(&except_mask);
	if (forRead)
		FD_SET(sock, &input_mask);
	if (forWrite)
		FD_SET(sock, &output_mask);
	FD_SET(sock, &except_mask);

	/* Compute appropriate timeout interval */
	if (end_time == ((time_t) -1))
	{
		ptr_timeout = NULL;
	}
	else
	{
		time_t	now = time(NULL);

		if (end_time > now)
			timeout.tv_sec = end_time - now;
		else
			timeout.tv_sec = 0;
		timeout.tv_usec = 0;
		ptr_timeout = &timeout;
	}

	return select(sock + 1, &input_mask, &output_mask,
				  &except_mask, ptr_timeout);
#endif /* HAVE_POLL */
}

981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003

/*
 * A couple of "miscellaneous" multibyte related functions. They used
 * to be in fe-print.c but that file is doomed.
 */

/*
 * returns the byte length of the word beginning s, using the
 * specified encoding.
 */
int
PQmblen(const unsigned char *s, int encoding)
{
	return (pg_encoding_mblen(encoding, s));
}

/*
 * Get encoding id from environment variable PGCLIENTENCODING.
 */
int
PQenv2encoding(void)
{
	char	   *str;
Tatsuo Ishii's avatar
Tatsuo Ishii committed
1004
	int			encoding = PG_SQL_ASCII;
1005 1006 1007 1008

	str = getenv("PGCLIENTENCODING");
	if (str && *str != '\0')
		encoding = pg_char_to_encoding(str);
1009
	return (encoding);
1010 1011
}

1012 1013

#ifdef ENABLE_NLS
1014

1015 1016 1017
char *
libpq_gettext(const char *msgid)
{
1018
	static int	already_bound = 0;
1019 1020 1021 1022 1023 1024 1025 1026 1027

	if (!already_bound)
	{
		already_bound = 1;
		bindtextdomain("libpq", LOCALEDIR);
	}

	return dgettext("libpq", msgid);
}
Bruce Momjian's avatar
Bruce Momjian committed
1028

1029
#endif   /* ENABLE_NLS */