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