fe-misc.c 19.8 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3 4
 *	 FILE
 *		fe-misc.c
5
 *
6 7
 *	 DESCRIPTION
 *		 miscellaneous useful functions
B
Bruce Momjian 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * 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
 * routines.  Note that this module supports *only* network byte order
 * for transmitted ints, whereas the backend modules (as of this writing)
 * still handle either network or little-endian byte order.
22
 *
23
 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
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.50 2001/07/06 17:58:53 petere Exp $
29 30 31 32
 *
 *-------------------------------------------------------------------------
 */

33
#include "postgres_fe.h"
M
 
Marc G. Fournier 已提交
34

B
Hello!  
Bruce Momjian 已提交
35 36
#ifdef WIN32
#include "win32.h"
37 38
#else
#include <unistd.h>
B
Hi!  
Bruce Momjian 已提交
39
#include <sys/time.h>
B
Bruce Momjian 已提交
40
#endif
M
 
Marc G. Fournier 已提交
41

42 43 44 45
#include <errno.h>
#include <signal.h>
#include <time.h>

B
Bruce Momjian 已提交
46 47 48
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
49

50 51 52 53
#include "libpq-fe.h"
#include "libpq-int.h"
#include "pqsignal.h"

P
Peter Eisentraut 已提交
54 55 56 57
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif

58

B
 
Bruce Momjian 已提交
59 60 61
#define DONOTICE(conn,message) \
	((*(conn)->noticeHook) ((conn)->noticeArg, (message)))

62 63
static int pqPutBytes(const char *s, size_t nbytes, PGconn *conn);

B
 
Bruce Momjian 已提交
64

65
/* --------------------------------------------------------------------- */
66
/* pqGetc:
B
Bruce Momjian 已提交
67
   get a character from the connection
68

B
Bruce Momjian 已提交
69 70 71
   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.
72
*/
73
int
B
Bruce Momjian 已提交
74
pqGetc(char *result, PGconn *conn)
75
{
B
Bruce Momjian 已提交
76 77
	if (conn->inCursor >= conn->inEnd)
		return EOF;
78

B
Bruce Momjian 已提交
79
	*result = conn->inBuffer[conn->inCursor++];
80

B
Bruce Momjian 已提交
81 82
	if (conn->Pfdebug)
		fprintf(conn->Pfdebug, "From backend> %c\n", *result);
83

B
Bruce Momjian 已提交
84
	return 0;
85 86
}

B
Bruce Momjian 已提交
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
/*
 * write 1 char to the connection
 */
int
pqPutc(char c, PGconn *conn)
{
	if (pqPutBytes(&c, 1, conn) == EOF)
		return EOF;

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

	return 0;
}


104
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
105 106 107 108
/* pqPutBytes: local routine to write N bytes to the connection,
   with buffering
 */
static int
B
Bruce Momjian 已提交
109
pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
B
Bruce Momjian 已提交
110
{
111
	size_t		avail = Max(conn->outBufSize - conn->outCount, 0);
B
Bruce Momjian 已提交
112

113
	/*
114 115
	 * if we are non-blocking and the send queue is too full to buffer
	 * this request then try to flush some and return an error
116 117 118
	 */
	if (pqIsnonblocking(conn) && nbytes > avail && pqFlush(conn))
	{
119 120 121 122 123 124 125 126

		/*
		 * even if the flush failed we may still have written some data,
		 * recalculate the size of the send-queue relative to the amount
		 * we have to send, we may be able to queue it afterall even
		 * though it's not sent to the database it's ok, any routines that
		 * check the data coming from the database better call pqFlush()
		 * anyway.
127 128 129 130
		 */
		if (nbytes > Max(conn->outBufSize - conn->outCount, 0))
		{
			printfPQExpBuffer(&conn->errorMessage,
131 132 133
						   "pqPutBytes --  pqFlush couldn't flush enough"
						 " data: space available: %d, space needed %d\n",
					  Max(conn->outBufSize - conn->outCount, 0), nbytes);
134 135
			return EOF;
		}
136 137
		/* fixup avail for while loop */
		avail = Max(conn->outBufSize - conn->outCount, 0);
138 139
	}

140
	/*
141 142 143
	 * is the amount of data to be sent is larger than the size of the
	 * output buffer then we must flush it to make more room.
	 *
144 145
	 * the code above will make sure the loop conditional is never true for
	 * non-blocking connections
146
	 */
B
Bruce Momjian 已提交
147 148 149 150 151 152 153 154 155 156
	while (nbytes > avail)
	{
		memcpy(conn->outBuffer + conn->outCount, s, avail);
		conn->outCount += avail;
		s += avail;
		nbytes -= avail;
		if (pqFlush(conn))
			return EOF;
		avail = conn->outBufSize;
	}
157

B
Bruce Momjian 已提交
158 159 160 161 162 163 164 165 166
	memcpy(conn->outBuffer + conn->outCount, s, nbytes);
	conn->outCount += nbytes;

	return 0;
}

/* --------------------------------------------------------------------- */
/* pqGets:
   get a null-terminated string from the connection,
167 168
   and store it in an expansible PQExpBuffer.
   If we run out of memory, all of the string is still read,
B
Bruce Momjian 已提交
169
   but the excess characters are silently discarded.
170
*/
171
int
172
pqGets(PQExpBuffer buf, PGconn *conn)
B
Bruce Momjian 已提交
173 174
{
	/* Copy conn data to locals for faster search loop */
175 176 177 178
	char	   *inBuffer = conn->inBuffer;
	int			inCursor = conn->inCursor;
	int			inEnd = conn->inEnd;
	int			slen;
B
Bruce Momjian 已提交
179 180 181 182 183 184 185 186

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

	if (inCursor >= inEnd)
		return EOF;

	slen = inCursor - conn->inCursor;
187 188 189

	resetPQExpBuffer(buf);
	appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
B
Bruce Momjian 已提交
190 191 192 193

	conn->inCursor = ++inCursor;

	if (conn->Pfdebug)
194 195
		fprintf(conn->Pfdebug, "From backend> \"%s\"\n",
				buf->data);
B
Bruce Momjian 已提交
196 197 198 199 200 201 202

	return 0;
}

/* --------------------------------------------------------------------- */
int
pqPuts(const char *s, PGconn *conn)
203
{
204
	if (pqPutBytes(s, strlen(s) + 1, conn))
B
Bruce Momjian 已提交
205 206 207 208
		return EOF;

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

B
Bruce Momjian 已提交
210
	return 0;
211 212
}

213
/* --------------------------------------------------------------------- */
214
/* pqGetnchar:
215
   get a string of exactly len bytes in buffer s, no null termination
216
*/
217
int
B
Bruce Momjian 已提交
218
pqGetnchar(char *s, size_t len, PGconn *conn)
219
{
B
Bruce Momjian 已提交
220 221 222 223
	if (len < 0 || len > conn->inEnd - conn->inCursor)
		return EOF;

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

B
Bruce Momjian 已提交
226
	conn->inCursor += len;
227

B
Bruce Momjian 已提交
228
	if (conn->Pfdebug)
B
Bruce Momjian 已提交
229
		fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long) len, (int) len, s);
230

B
Bruce Momjian 已提交
231
	return 0;
232 233
}

234
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
235
/* pqPutnchar:
236
   send a string of exactly len bytes, no null termination needed
237
*/
238
int
B
Bruce Momjian 已提交
239
pqPutnchar(const char *s, size_t len, PGconn *conn)
240
{
B
Bruce Momjian 已提交
241 242
	if (pqPutBytes(s, len, conn))
		return EOF;
243

B
Bruce Momjian 已提交
244
	if (conn->Pfdebug)
245
		fprintf(conn->Pfdebug, "To backend> %.*s\n", (int) len, s);
246

B
Bruce Momjian 已提交
247
	return 0;
248 249
}

250
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
251 252 253
/* pgGetInt
   read a 2 or 4 byte integer and convert from network byte order
   to local byte order
254
*/
255
int
B
Bruce Momjian 已提交
256
pqGetInt(int *result, size_t bytes, PGconn *conn)
257
{
258 259
	uint16		tmp2;
	uint32		tmp4;
260
	char		noticeBuf[64];
261 262 263

	switch (bytes)
	{
264
		case 2:
B
Bruce Momjian 已提交
265 266 267 268 269
			if (conn->inCursor + 2 > conn->inEnd)
				return EOF;
			memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
			conn->inCursor += 2;
			*result = (int) ntohs(tmp2);
270 271
			break;
		case 4:
B
Bruce Momjian 已提交
272 273 274 275 276
			if (conn->inCursor + 4 > conn->inEnd)
				return EOF;
			memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
			conn->inCursor += 4;
			*result = (int) ntohl(tmp4);
277 278
			break;
		default:
279
			sprintf(noticeBuf,
B
Bruce Momjian 已提交
280
					"pqGetInt: int size %lu not supported\n", (unsigned long) bytes);
281
			DONOTICE(conn, noticeBuf);
B
Bruce Momjian 已提交
282
			return EOF;
283 284
	}

B
Bruce Momjian 已提交
285
	if (conn->Pfdebug)
B
Bruce Momjian 已提交
286
		fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
287

B
Bruce Momjian 已提交
288
	return 0;
289 290
}

291
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
292 293 294
/* pgPutInt
   send an integer of 2 or 4 bytes, converting from host byte order
   to network byte order.
295
*/
296
int
B
Bruce Momjian 已提交
297
pqPutInt(int value, size_t bytes, PGconn *conn)
298
{
299 300
	uint16		tmp2;
	uint32		tmp4;
301
	char		noticeBuf[64];
302 303 304

	switch (bytes)
	{
305
		case 2:
B
Bruce Momjian 已提交
306
			tmp2 = htons((uint16) value);
307
			if (pqPutBytes((const char *) &tmp2, 2, conn))
B
Bruce Momjian 已提交
308
				return EOF;
309 310
			break;
		case 4:
B
Bruce Momjian 已提交
311
			tmp4 = htonl((uint32) value);
312
			if (pqPutBytes((const char *) &tmp4, 4, conn))
B
Bruce Momjian 已提交
313
				return EOF;
314 315
			break;
		default:
316
			sprintf(noticeBuf,
B
Bruce Momjian 已提交
317
					"pqPutInt: int size %lu not supported\n", (unsigned long) bytes);
318
			DONOTICE(conn, noticeBuf);
B
Bruce Momjian 已提交
319
			return EOF;
320 321
	}

B
Bruce Momjian 已提交
322
	if (conn->Pfdebug)
B
Bruce Momjian 已提交
323
		fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
324

B
Bruce Momjian 已提交
325
	return 0;
326
}
327

328
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
329
/* pqReadReady: is select() saying the file is ready to read?
330
 * Returns -1 on failure, 0 if not ready, 1 if ready.
B
Bruce Momjian 已提交
331
 */
332
int
B
Bruce Momjian 已提交
333 334
pqReadReady(PGconn *conn)
{
335 336
	fd_set		input_mask;
	struct timeval timeout;
B
Bruce Momjian 已提交
337

338 339
	if (!conn || conn->sock < 0)
		return -1;
B
Bruce Momjian 已提交
340

341
retry:
B
Bruce Momjian 已提交
342 343 344 345
	FD_ZERO(&input_mask);
	FD_SET(conn->sock, &input_mask);
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
346
	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
B
Bruce Momjian 已提交
347 348
			   &timeout) < 0)
	{
349 350 351 352
		if (errno == EINTR)
			/* Interrupted system call - we'll just try again */
			goto retry;

353
		printfPQExpBuffer(&conn->errorMessage,
354
					  "pqReadReady() -- select() failed: errno=%d\n%s\n",
355
						  errno, strerror(errno));
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
		return -1;
	}

	return FD_ISSET(conn->sock, &input_mask) ? 1 : 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)
{
	fd_set		input_mask;
	struct timeval timeout;

	if (!conn || conn->sock < 0)
		return -1;

375
retry:
376 377 378 379 380 381 382 383 384 385 386 387
	FD_ZERO(&input_mask);
	FD_SET(conn->sock, &input_mask);
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
			   &timeout) < 0)
	{
		if (errno == EINTR)
			/* Interrupted system call - we'll just try again */
			goto retry;

		printfPQExpBuffer(&conn->errorMessage,
388
					 "pqWriteReady() -- select() failed: errno=%d\n%s\n",
389 390
						  errno, strerror(errno));
		return -1;
B
Bruce Momjian 已提交
391
	}
392
	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
B
Bruce Momjian 已提交
393 394 395 396 397
}

/* --------------------------------------------------------------------- */
/* pqReadData: read more data, if any is available
 * Possible return values:
398 399 400 401
 *	 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
B
Bruce Momjian 已提交
402 403 404
 * NOTE: callers must not assume that pointers or indexes into conn->inBuffer
 * remain valid across this call!
 */
405
int
B
Bruce Momjian 已提交
406
pqReadData(PGconn *conn)
407
{
408
	int			someread = 0;
409
	int			nread;
B
Bruce Momjian 已提交
410 411 412

	if (conn->sock < 0)
	{
413 414
		printfPQExpBuffer(&conn->errorMessage,
						  "pqReadData() -- connection not open\n");
B
Bruce Momjian 已提交
415 416
		return -1;
	}
417

B
Bruce Momjian 已提交
418 419 420
	/* Left-justify any data in the buffer to make room */
	if (conn->inStart < conn->inEnd)
	{
421 422 423 424 425 426 427 428
		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;
		}
B
Bruce Momjian 已提交
429 430
	}
	else
431 432
	{
		/* buffer is logically empty, reset it */
B
Bruce Momjian 已提交
433
		conn->inStart = conn->inCursor = conn->inEnd = 0;
434
	}
435 436 437 438 439 440

	/*
	 * 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
441
	 * here should be large enough for a TCP packet or Unix pipe
442
	 * bufferload.	8K is the usual pipe buffer size, so...
B
Bruce Momjian 已提交
443
	 */
444
	if (conn->inBufSize - conn->inEnd < 8192)
B
Bruce Momjian 已提交
445
	{
446 447 448
		int			newSize = conn->inBufSize * 2;
		char	   *newBuf = (char *) realloc(conn->inBuffer, newSize);

B
Bruce Momjian 已提交
449 450 451 452 453 454
		if (newBuf)
		{
			conn->inBuffer = newBuf;
			conn->inBufSize = newSize;
		}
	}
455

B
Bruce Momjian 已提交
456 457
	/* OK, try to read some data */
tryAgain:
458
#ifdef USE_SSL
459 460 461
	if (conn->ssl)
		nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
						 conn->inBufSize - conn->inEnd);
462 463
	else
#endif
464 465
		nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
					 conn->inBufSize - conn->inEnd, 0);
B
Bruce Momjian 已提交
466 467 468 469
	if (nread < 0)
	{
		if (errno == EINTR)
			goto tryAgain;
470 471 472
		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
		if (errno == EAGAIN)
473
			return someread;
474 475 476
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
		if (errno == EWOULDBLOCK)
477
			return someread;
B
Bruce Momjian 已提交
478 479 480 481 482
#endif
		/* We might get ECONNRESET here if using TCP and backend died */
#ifdef ECONNRESET
		if (errno == ECONNRESET)
			goto definitelyFailed;
483
#endif
484
		printfPQExpBuffer(&conn->errorMessage,
485
						"pqReadData() --  read() failed: errno=%d\n%s\n",
486
						  errno, strerror(errno));
B
Bruce Momjian 已提交
487 488 489 490 491
		return -1;
	}
	if (nread > 0)
	{
		conn->inEnd += nread;
492

493 494
		/*
		 * Hack to deal with the fact that some kernels will only give us
495 496 497 498 499 500
		 * 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.
501 502
		 *
		 * Since we left-justified the data above, conn->inEnd gives the
503 504
		 * amount of data already read in the current message.	We
		 * consider the message "long" once we have acquired 32k ...
505 506 507 508 509 510 511
		 */
		if (conn->inEnd > 32768 &&
			(conn->inBufSize - conn->inEnd) >= 8192)
		{
			someread = 1;
			goto tryAgain;
		}
B
Bruce Momjian 已提交
512 513
		return 1;
	}
514

515 516 517
	if (someread)
		return 1;				/* got a zero read after successful tries */

518 519 520 521 522 523 524 525
	/*
	 * 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.
B
Bruce Momjian 已提交
526
	 */
527 528 529 530 531 532 533 534 535 536 537
	switch (pqReadReady(conn))
	{
		case 0:
			/* definitely no data available */
			return 0;
		case 1:
			/* ready for read */
			break;
		default:
			goto definitelyFailed;
	}
B
Bruce Momjian 已提交
538

539 540 541
	/*
	 * Still not sure that it's EOF, because some data could have just
	 * arrived.
B
Bruce Momjian 已提交
542 543
	 */
tryAgain2:
544
#ifdef USE_SSL
545 546 547
	if (conn->ssl)
		nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
						 conn->inBufSize - conn->inEnd);
548 549
	else
#endif
550 551
		nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
					 conn->inBufSize - conn->inEnd, 0);
B
Bruce Momjian 已提交
552 553 554 555
	if (nread < 0)
	{
		if (errno == EINTR)
			goto tryAgain2;
556 557 558 559 560 561 562 563
		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
		if (errno == EAGAIN)
			return 0;
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
		if (errno == EWOULDBLOCK)
			return 0;
B
Bruce Momjian 已提交
564 565 566 567 568
#endif
		/* We might get ECONNRESET here if using TCP and backend died */
#ifdef ECONNRESET
		if (errno == ECONNRESET)
			goto definitelyFailed;
569
#endif
570
		printfPQExpBuffer(&conn->errorMessage,
571
						"pqReadData() --  read() failed: errno=%d\n%s\n",
572
						  errno, strerror(errno));
B
Bruce Momjian 已提交
573 574 575 576 577 578 579 580
		return -1;
	}
	if (nread > 0)
	{
		conn->inEnd += nread;
		return 1;
	}

581 582
	/*
	 * OK, we are getting a zero read even though select() says ready.
B
Bruce Momjian 已提交
583 584
	 * This means the connection has been closed.  Cope.
	 */
B
Bruce Momjian 已提交
585
definitelyFailed:
586
	printfPQExpBuffer(&conn->errorMessage,
587 588 589
			 "pqReadData() -- backend closed the channel unexpectedly.\n"
			  "\tThis probably means the backend terminated abnormally\n"
					  "\tbefore or while processing the request.\n");
590
	conn->status = CONNECTION_BAD;		/* No more connection to backend */
B
Hello!  
Bruce Momjian 已提交
591 592 593
#ifdef WIN32
	closesocket(conn->sock);
#else
B
Bruce Momjian 已提交
594
	close(conn->sock);
B
Hello!  
Bruce Momjian 已提交
595
#endif
B
Bruce Momjian 已提交
596
	conn->sock = -1;
597

B
Bruce Momjian 已提交
598
	return -1;
599 600
}

601
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
602 603 604 605
/* pqFlush: send any data waiting in the output buffer
 */
int
pqFlush(PGconn *conn)
606
{
607 608
	char	   *ptr = conn->outBuffer;
	int			len = conn->outCount;
B
Bruce Momjian 已提交
609 610 611

	if (conn->sock < 0)
	{
612 613
		printfPQExpBuffer(&conn->errorMessage,
						  "pqFlush() -- connection not open\n");
B
Bruce Momjian 已提交
614 615
		return EOF;
	}
616

617 618 619
	/*
	 * don't try to send zero data, allows us to use this function without
	 * too much worry about overhead
620 621 622 623 624
	 */
	if (len == 0)
		return (0);

	/* while there's still data to send */
B
Bruce Momjian 已提交
625 626
	while (len > 0)
	{
M
 
Marc G. Fournier 已提交
627 628
		/* Prevent being SIGPIPEd if backend has closed the connection. */
#ifndef WIN32
629
		pqsigfunc	oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
630

M
 
Marc G. Fournier 已提交
631 632
#endif

633
		int			sent;
634

635
#ifdef USE_SSL
636 637
		if (conn->ssl)
			sent = SSL_write(conn->ssl, ptr, len);
638 639
		else
#endif
640
			sent = send(conn->sock, ptr, len, 0);
M
 
Marc G. Fournier 已提交
641 642 643 644 645

#ifndef WIN32
		pqsignal(SIGPIPE, oldsighandler);
#endif

B
Bruce Momjian 已提交
646 647
		if (sent < 0)
		{
B
Bruce Momjian 已提交
648

B
Bruce Momjian 已提交
649
			/*
B
Bruce Momjian 已提交
650 651 652
			 * Anything except EAGAIN or EWOULDBLOCK is trouble. If it's
			 * EPIPE or ECONNRESET, assume we've lost the backend
			 * connection permanently.
B
Bruce Momjian 已提交
653
			 */
B
Bruce Momjian 已提交
654 655 656 657 658 659 660 661 662 663
			switch (errno)
			{
#ifdef EAGAIN
				case EAGAIN:
					break;
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
				case EWOULDBLOCK:
					break;
#endif
664 665
				case EINTR:
					continue;
666

B
Bruce Momjian 已提交
667 668 669 670
				case EPIPE:
#ifdef ECONNRESET
				case ECONNRESET:
#endif
671
					printfPQExpBuffer(&conn->errorMessage,
B
Bruce Momjian 已提交
672 673 674
									  "pqFlush() -- backend closed the channel unexpectedly.\n"
									  "\tThis probably means the backend terminated abnormally"
						   " before or while processing the request.\n");
675

676 677 678
					/*
					 * We used to close the socket here, but that's a bad
					 * idea since there might be unread data waiting
679 680 681 682
					 * (typically, a NOTICE message from the backend
					 * telling us it's committing hara-kiri...).  Leave
					 * the socket open until pqReadData finds no more data
					 * can be read.
683
					 */
B
Bruce Momjian 已提交
684
					return EOF;
685

B
Bruce Momjian 已提交
686
				default:
687
					printfPQExpBuffer(&conn->errorMessage,
B
Bruce Momjian 已提交
688 689
					  "pqFlush() --  couldn't send data: errno=%d\n%s\n",
									  errno, strerror(errno));
B
Bruce Momjian 已提交
690
					/* We don't assume it's a fatal error... */
B
Bruce Momjian 已提交
691 692 693 694 695 696 697 698
					return EOF;
			}
		}
		else
		{
			ptr += sent;
			len -= sent;
		}
699

B
Bruce Momjian 已提交
700 701 702
		if (len > 0)
		{
			/* We didn't send it all, wait till we can send more */
703

704 705 706
			/*
			 * if the socket is in non-blocking mode we may need to abort
			 * here
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
			 */
#ifdef USE_SSL
			/* can't do anything for our SSL users yet */
			if (conn->ssl == NULL)
			{
#endif
				if (pqIsnonblocking(conn))
				{
					/* shift the contents of the buffer */
					memmove(conn->outBuffer, ptr, len);
					conn->outCount = len;
					return EOF;
				}
#ifdef USE_SSL
			}
#endif

B
Bruce Momjian 已提交
724 725 726 727 728 729 730 731 732 733 734
			if (pqWait(FALSE, TRUE, conn))
				return EOF;
		}
	}

	conn->outCount = 0;

	if (conn->Pfdebug)
		fflush(conn->Pfdebug);

	return 0;
735
}
736

737
/* --------------------------------------------------------------------- */
B
Bruce Momjian 已提交
738
/* pqWait: wait until we can read or write the connection socket
739 740 741 742
 *
 * 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.
B
Bruce Momjian 已提交
743 744 745 746
 */
int
pqWait(int forRead, int forWrite, PGconn *conn)
{
747 748
	fd_set		input_mask;
	fd_set		output_mask;
749
	fd_set		except_mask;
B
Bruce Momjian 已提交
750 751 752

	if (conn->sock < 0)
	{
753 754
		printfPQExpBuffer(&conn->errorMessage,
						  "pqWait() -- connection not open\n");
B
Bruce Momjian 已提交
755 756 757
		return EOF;
	}

758
	if (forRead || forWrite)
759
	{
760
retry:
B
Bruce Momjian 已提交
761 762
		FD_ZERO(&input_mask);
		FD_ZERO(&output_mask);
763
		FD_ZERO(&except_mask);
B
Bruce Momjian 已提交
764 765 766 767
		if (forRead)
			FD_SET(conn->sock, &input_mask);
		if (forWrite)
			FD_SET(conn->sock, &output_mask);
768 769
		FD_SET(conn->sock, &except_mask);
		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
B
Bruce Momjian 已提交
770 771 772
				   (struct timeval *) NULL) < 0)
		{
			if (errno == EINTR)
773
				goto retry;
774
			printfPQExpBuffer(&conn->errorMessage,
775
							  "pqWait() -- select() failed: errno=%d\n%s\n",
776
							  errno, strerror(errno));
B
Bruce Momjian 已提交
777 778 779 780 781 782
			return EOF;
		}
	}

	return 0;
}
P
Peter Eisentraut 已提交
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813



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

#ifdef MULTIBYTE
/*
 * 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;
	int			encoding = SQL_ASCII;

	str = getenv("PGCLIENTENCODING");
	if (str && *str != '\0')
		encoding = pg_char_to_encoding(str);
814
	return (encoding);
P
Peter Eisentraut 已提交
815 816 817 818 819 820 821 822
}

#else

/* Provide a default definition in case someone calls it anyway */
int
PQmblen(const unsigned char *s, int encoding)
{
823 824
	(void) s;
	(void) encoding;
P
Peter Eisentraut 已提交
825 826 827 828 829 830 831 832 833
	return 1;
}
int
PQenv2encoding(void)
{
	return 0;
}

#endif	 /* MULTIBYTE */