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-2025, 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 : : pg_usec_time_t end_time);
58 : :
59 : : /*
60 : : * PQlibVersion: return the libpq version number
61 : : */
62 : : int
5372 magnus@hagander.net 63 :UBC 0 : PQlibVersion(void)
64 : : {
65 : 0 : return PG_VERSION_NUM;
66 : : }
67 : :
68 : :
69 : : /*
70 : : * pqGetc: read 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
9985 bruce@momjian.us 77 :CBC 10280745 : pqGetc(char *result, PGconn *conn)
78 : : {
79 [ + + ]: 10280745 : if (conn->inCursor >= conn->inEnd)
80 : 1519094 : return EOF;
81 : :
82 : 8761651 : *result = conn->inBuffer[conn->inCursor++];
83 : :
84 : 8761651 : return 0;
85 : : }
86 : :
87 : :
88 : : /*
89 : : * pqPutc: write 1 char to the current message
90 : : */
91 : : int
8828 peter_e@gmx.net 92 : 10062 : pqPutc(char c, PGconn *conn)
93 : : {
8176 tgl@sss.pgh.pa.us 94 [ - + ]: 10062 : if (pqPutMsgBytes(&c, 1, conn))
8828 peter_e@gmx.net 95 :UBC 0 : return EOF;
96 : :
8828 peter_e@gmx.net 97 :CBC 10062 : return 0;
98 : : }
99 : :
100 : :
101 : : /*
102 : : * pqGets[_append]:
103 : : * read 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
6158 magnus@hagander.net 109 : 1479946 : pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
110 : : {
111 : : /* Copy conn data to locals for faster search loop */
9867 bruce@momjian.us 112 : 1479946 : char *inBuffer = conn->inBuffer;
113 : 1479946 : int inCursor = conn->inCursor;
114 : 1479946 : int inEnd = conn->inEnd;
115 : : int slen;
116 : :
9985 117 [ + - + + ]: 18012201 : while (inCursor < inEnd && inBuffer[inCursor])
118 : 16532255 : inCursor++;
119 : :
120 [ - + ]: 1479946 : if (inCursor >= inEnd)
9985 bruce@momjian.us 121 :UBC 0 : return EOF;
122 : :
9985 bruce@momjian.us 123 :CBC 1479946 : slen = inCursor - conn->inCursor;
124 : :
6158 magnus@hagander.net 125 [ + - ]: 1479946 : if (resetbuffer)
126 : 1479946 : resetPQExpBuffer(buf);
127 : :
9503 tgl@sss.pgh.pa.us 128 : 1479946 : appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
129 : :
9985 bruce@momjian.us 130 : 1479946 : conn->inCursor = ++inCursor;
131 : :
132 : 1479946 : return 0;
133 : : }
134 : :
135 : : int
6158 magnus@hagander.net 136 : 1479946 : pqGets(PQExpBuffer buf, PGconn *conn)
137 : : {
138 : 1479946 : return pqGets_internal(buf, conn, true);
139 : : }
140 : :
141 : : int
6158 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
9985 bruce@momjian.us 152 :CBC 348939 : pqPuts(const char *s, PGconn *conn)
153 : : {
8176 tgl@sss.pgh.pa.us 154 [ - + ]: 348939 : if (pqPutMsgBytes(s, strlen(s) + 1, conn))
9985 bruce@momjian.us 155 :UBC 0 : return EOF;
156 : :
9985 bruce@momjian.us 157 :CBC 348939 : return 0;
158 : : }
159 : :
160 : : /*
161 : : * pqGetnchar:
162 : : * read exactly len bytes in buffer s, no null termination
163 : : */
164 : : int
121 heikki.linnakangas@i 165 : 12909 : pqGetnchar(void *s, size_t len, PGconn *conn)
166 : : {
5952 meskes@postgresql.or 167 [ - + ]: 12909 : if (len > (size_t) (conn->inEnd - conn->inCursor))
9985 bruce@momjian.us 168 :UBC 0 : return EOF;
169 : :
9985 bruce@momjian.us 170 :CBC 12909 : memcpy(s, conn->inBuffer + conn->inCursor, len);
171 : : /* no terminating null */
172 : :
173 : 12909 : conn->inCursor += len;
174 : :
175 : 12909 : 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
4903 tgl@sss.pgh.pa.us 187 : 18448065 : pqSkipnchar(size_t len, PGconn *conn)
188 : : {
189 [ - + ]: 18448065 : if (len > (size_t) (conn->inEnd - conn->inCursor))
4903 tgl@sss.pgh.pa.us 190 :UBC 0 : return EOF;
191 : :
4903 tgl@sss.pgh.pa.us 192 :CBC 18448065 : conn->inCursor += len;
193 : :
194 : 18448065 : return 0;
195 : : }
196 : :
197 : : /*
198 : : * pqPutnchar:
199 : : * write exactly len bytes to the current message
200 : : */
201 : : int
121 heikki.linnakangas@i 202 : 375474 : pqPutnchar(const void *s, size_t len, PGconn *conn)
203 : : {
8176 tgl@sss.pgh.pa.us 204 [ - + ]: 375474 : if (pqPutMsgBytes(s, len, conn))
9985 bruce@momjian.us 205 :UBC 0 : return EOF;
206 : :
9985 bruce@momjian.us 207 :CBC 375474 : 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
9431 216 : 35084645 : pqGetInt(int *result, size_t bytes, PGconn *conn)
217 : : {
218 : : uint16 tmp2;
219 : : uint32 tmp4;
220 : :
10226 221 [ + + - ]: 35084645 : switch (bytes)
222 : : {
10225 223 : 5687415 : case 2:
9985 224 [ - + ]: 5687415 : if (conn->inCursor + 2 > conn->inEnd)
9985 bruce@momjian.us 225 :UBC 0 : return EOF;
9985 bruce@momjian.us 226 :CBC 5687415 : memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
227 : 5687415 : conn->inCursor += 2;
2897 andres@anarazel.de 228 : 5687415 : *result = (int) pg_ntoh16(tmp2);
10225 bruce@momjian.us 229 : 5687415 : break;
230 : 29397230 : case 4:
9985 231 [ + + ]: 29397230 : if (conn->inCursor + 4 > conn->inEnd)
232 : 2706 : return EOF;
233 : 29394524 : memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
234 : 29394524 : conn->inCursor += 4;
2897 andres@anarazel.de 235 : 29394524 : *result = (int) pg_ntoh32(tmp4);
10225 bruce@momjian.us 236 : 29394524 : break;
10225 bruce@momjian.us 237 :UBC 0 : default:
8111 tgl@sss.pgh.pa.us 238 : 0 : pqInternalNotice(&conn->noticeHooks,
239 : : "integer of size %lu not supported by pqGetInt",
240 : : (unsigned long) bytes);
9985 bruce@momjian.us 241 : 0 : return EOF;
242 : : }
243 : :
9985 bruce@momjian.us 244 :CBC 35081939 : 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
9431 253 : 78307 : pqPutInt(int value, size_t bytes, PGconn *conn)
254 : : {
255 : : uint16 tmp2;
256 : : uint32 tmp4;
257 : :
10226 258 [ + + - ]: 78307 : switch (bytes)
259 : : {
10225 260 : 50277 : case 2:
2897 andres@anarazel.de 261 : 50277 : tmp2 = pg_hton16((uint16) value);
8176 tgl@sss.pgh.pa.us 262 [ - + ]: 50277 : if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
9985 bruce@momjian.us 263 :UBC 0 : return EOF;
10225 bruce@momjian.us 264 :CBC 50277 : break;
265 : 28030 : case 4:
2897 andres@anarazel.de 266 : 28030 : tmp4 = pg_hton32((uint32) value);
8176 tgl@sss.pgh.pa.us 267 [ - + ]: 28030 : if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
9985 bruce@momjian.us 268 :UBC 0 : return EOF;
10225 bruce@momjian.us 269 :CBC 28030 : break;
10225 bruce@momjian.us 270 :UBC 0 : default:
8111 tgl@sss.pgh.pa.us 271 : 0 : pqInternalNotice(&conn->noticeHooks,
272 : : "integer of size %lu not supported by pqPutInt",
273 : : (unsigned long) bytes);
9985 bruce@momjian.us 274 : 0 : return EOF;
275 : : }
276 : :
9985 bruce@momjian.us 277 :CBC 78307 : 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
6309 tgl@sss.pgh.pa.us 287 : 1533306 : pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
288 : : {
8176 289 : 1533306 : int newsize = conn->outBufSize;
290 : : char *newbuf;
291 : :
292 : : /* Quick exit if we have enough space */
6309 293 [ + + ]: 1533306 : if (bytes_needed <= (size_t) newsize)
8176 294 : 1533275 : 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 : 77 : newsize *= 2;
6309 306 [ + - + + ]: 77 : } while (newsize > 0 && bytes_needed > (size_t) newsize);
307 : :
308 [ + - + - ]: 31 : if (newsize > 0 && bytes_needed <= (size_t) newsize)
309 : : {
8176 310 : 31 : newbuf = realloc(conn->outBuffer, newsize);
311 [ + - ]: 31 : if (newbuf)
312 : : {
313 : : /* realloc succeeded */
314 : 31 : conn->outBuffer = newbuf;
315 : 31 : conn->outBufSize = newsize;
316 : 31 : return 0;
317 : : }
318 : : }
319 : :
8176 tgl@sss.pgh.pa.us 320 :UBC 0 : newsize = conn->outBufSize;
321 : : do
322 : : {
323 : 0 : newsize += 8192;
6309 324 [ # # # # ]: 0 : } while (newsize > 0 && bytes_needed > (size_t) newsize);
325 : :
326 [ # # # # ]: 0 : if (newsize > 0 && bytes_needed <= (size_t) newsize)
327 : : {
8176 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 */
1699 339 : 0 : appendPQExpBufferStr(&conn->errorMessage,
340 : : "cannot allocate memory for output buffer\n");
8176 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
6309 tgl@sss.pgh.pa.us 351 :CBC 296099 : pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
352 : : {
8173 353 : 296099 : int newsize = conn->inBufSize;
354 : : char *newbuf;
355 : :
356 : : /* Quick exit if we have enough space */
4140 357 [ + + ]: 296099 : if (bytes_needed <= (size_t) newsize)
358 : 181433 : 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 : 114666 : bytes_needed -= conn->inStart;
368 : :
369 [ + - ]: 114666 : if (conn->inStart < conn->inEnd)
370 : : {
371 [ + + ]: 114666 : if (conn->inStart > 0)
372 : : {
373 : 114463 : memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
374 : 114463 : conn->inEnd - conn->inStart);
375 : 114463 : conn->inEnd -= conn->inStart;
376 : 114463 : conn->inCursor -= conn->inStart;
377 : 114463 : conn->inStart = 0;
378 : : }
379 : : }
380 : : else
381 : : {
382 : : /* buffer is logically empty, reset it */
4140 tgl@sss.pgh.pa.us 383 :UBC 0 : conn->inStart = conn->inCursor = conn->inEnd = 0;
384 : : }
385 : :
386 : : /* Recheck whether we have enough space */
6309 tgl@sss.pgh.pa.us 387 [ + + ]:CBC 114666 : if (bytes_needed <= (size_t) newsize)
8173 388 : 113960 : 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 : 1253 : newsize *= 2;
6309 400 [ + - + + ]: 1253 : } while (newsize > 0 && bytes_needed > (size_t) newsize);
401 : :
402 [ + - + - ]: 706 : if (newsize > 0 && bytes_needed <= (size_t) newsize)
403 : : {
8173 404 : 706 : newbuf = realloc(conn->inBuffer, newsize);
405 [ + - ]: 706 : if (newbuf)
406 : : {
407 : : /* realloc succeeded */
408 : 706 : conn->inBuffer = newbuf;
409 : 706 : conn->inBufSize = newsize;
410 : 706 : return 0;
411 : : }
412 : : }
413 : :
8173 tgl@sss.pgh.pa.us 414 :UBC 0 : newsize = conn->inBufSize;
415 : : do
416 : : {
417 : 0 : newsize += 8192;
6309 418 [ # # # # ]: 0 : } while (newsize > 0 && bytes_needed > (size_t) newsize);
419 : :
420 [ # # # # ]: 0 : if (newsize > 0 && bytes_needed <= (size_t) newsize)
421 : : {
8173 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 */
1699 433 : 0 : appendPQExpBufferStr(&conn->errorMessage,
434 : : "cannot allocate memory for input buffer\n");
8173 435 : 0 : return EOF;
436 : : }
437 : :
438 : : /*
439 : : * pqParseDone: after a server-to-client message has successfully
440 : : * been parsed, advance conn->inStart to account for it.
441 : : */
442 : : void
386 alvherre@alvh.no-ip. 443 :CBC 7439504 : pqParseDone(PGconn *conn, int newInStart)
444 : : {
445 : : /* trace server-to-client message */
446 [ + + ]: 7439504 : if (conn->Pfdebug)
447 : 217 : pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false);
448 : :
449 : : /* Mark message as done */
450 : 7439504 : conn->inStart = newInStart;
451 : 7439504 : }
452 : :
453 : : /*
454 : : * pqPutMsgStart: begin construction of a message to the server
455 : : *
456 : : * msg_type is the message type byte, or 0 for a message without type byte
457 : : * (only startup messages have no type byte)
458 : : *
459 : : * Returns 0 on success, EOF on error
460 : : *
461 : : * The idea here is that we construct the message in conn->outBuffer,
462 : : * beginning just past any data already in outBuffer (ie, at
463 : : * outBuffer+outCount). We enlarge the buffer as needed to hold the message.
464 : : * When the message is complete, we fill in the length word (if needed) and
465 : : * then advance outCount past the message, making it eligible to send.
466 : : *
467 : : * The state variable conn->outMsgStart points to the incomplete message's
468 : : * length word: it is either outCount or outCount+1 depending on whether
469 : : * there is a type byte. The state variable conn->outMsgEnd is the end of
470 : : * the data collected so far.
471 : : */
472 : : int
1647 heikki.linnakangas@i 473 : 720503 : pqPutMsgStart(char msg_type, PGconn *conn)
474 : : {
475 : : int lenPos;
476 : : int endPos;
477 : :
478 : : /* allow room for message type byte */
8176 tgl@sss.pgh.pa.us 479 [ + + ]: 720503 : if (msg_type)
8126 480 : 707423 : endPos = conn->outCount + 1;
481 : : else
482 : 13080 : endPos = conn->outCount;
483 : :
484 : : /* do we want a length word? */
1647 heikki.linnakangas@i 485 : 720503 : lenPos = endPos;
486 : : /* allow room for message length */
487 : 720503 : endPos += 4;
488 : :
489 : : /* make sure there is room for message header */
8126 tgl@sss.pgh.pa.us 490 [ - + ]: 720503 : if (pqCheckOutBufferSpace(endPos, conn))
8176 tgl@sss.pgh.pa.us 491 :UBC 0 : return EOF;
492 : : /* okay, save the message type byte if any */
8176 tgl@sss.pgh.pa.us 493 [ + + ]:CBC 720503 : if (msg_type)
494 : 707423 : conn->outBuffer[conn->outCount] = msg_type;
495 : : /* set up the message pointers */
496 : 720503 : conn->outMsgStart = lenPos;
8126 497 : 720503 : conn->outMsgEnd = endPos;
498 : : /* length word, if needed, will be filled in by pqPutMsgEnd */
499 : :
8176 500 : 720503 : return 0;
501 : : }
502 : :
503 : : /*
504 : : * pqPutMsgBytes: add bytes to a partially-constructed message
505 : : *
506 : : * Returns 0 on success, EOF on error
507 : : */
508 : : static int
509 : 812782 : pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
510 : : {
511 : : /* make sure there is room for it */
8173 512 [ - + ]: 812782 : if (pqCheckOutBufferSpace(conn->outMsgEnd + len, conn))
8176 tgl@sss.pgh.pa.us 513 :UBC 0 : return EOF;
514 : : /* okay, save the data */
8176 tgl@sss.pgh.pa.us 515 :CBC 812782 : memcpy(conn->outBuffer + conn->outMsgEnd, buf, len);
516 : 812782 : conn->outMsgEnd += len;
517 : : /* no Pfdebug call here, caller should do it */
518 : 812782 : return 0;
519 : : }
520 : :
521 : : /*
522 : : * pqPutMsgEnd: finish constructing a message and possibly send it
523 : : *
524 : : * Returns 0 on success, EOF on error
525 : : *
526 : : * We don't actually send anything here unless we've accumulated at least
527 : : * 8K worth of data (the typical size of a pipe buffer on Unix systems).
528 : : * This avoids sending small partial packets. The caller must use pqFlush
529 : : * when it's important to flush all the data out to the server.
530 : : */
531 : : int
532 : 720503 : pqPutMsgEnd(PGconn *conn)
533 : : {
534 : : /* Fill in length word if needed */
8126 535 [ + - ]: 720503 : if (conn->outMsgStart >= 0)
536 : : {
537 : 720503 : uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
538 : :
2897 andres@anarazel.de 539 : 720503 : msgLen = pg_hton32(msgLen);
8126 tgl@sss.pgh.pa.us 540 : 720503 : memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
541 : : }
542 : :
543 : : /* trace client-to-server message */
1621 alvherre@alvh.no-ip. 544 [ + + ]: 720503 : if (conn->Pfdebug)
545 : : {
546 [ + - ]: 197 : if (conn->outCount < conn->outMsgStart)
547 : 197 : pqTraceOutputMessage(conn, conn->outBuffer + conn->outCount, true);
548 : : else
1621 alvherre@alvh.no-ip. 549 :UBC 0 : pqTraceOutputNoTypeByteMessage(conn,
550 : 0 : conn->outBuffer + conn->outMsgStart);
551 : : }
552 : :
553 : : /* Make message eligible to send */
8176 tgl@sss.pgh.pa.us 554 :CBC 720503 : conn->outCount = conn->outMsgEnd;
555 : :
556 : : /* If appropriate, try to push out some data */
557 [ + + ]: 720503 : if (conn->outCount >= 8192)
558 : : {
88 559 : 1109 : int toSend = conn->outCount;
560 : :
561 : : /*
562 : : * On Unix-pipe connections, it seems profitable to prefer sending
563 : : * pipe-buffer-sized packets not randomly-sized ones, so retain the
564 : : * last partial-8K chunk in our buffer for now. On TCP connections,
565 : : * the advantage of that is far less clear. Moreover, it flat out
566 : : * isn't safe when using SSL or GSSAPI, because those code paths have
567 : : * API stipulations that if they fail to send all the data that was
568 : : * offered in the previous write attempt, we mustn't offer less data
569 : : * in this write attempt. The previous write attempt might've been
570 : : * pqFlush attempting to send everything in the buffer, so we mustn't
571 : : * offer less now. (Presently, we won't try to use SSL or GSSAPI on
572 : : * Unix connections, so those checks are just Asserts. They'll have
573 : : * to become part of the regular if-test if we ever change that.)
574 : : */
575 [ + + ]: 1109 : if (conn->raddr.addr.ss_family == AF_UNIX)
576 : : {
577 : : #ifdef USE_SSL
578 [ - + ]: 1038 : Assert(!conn->ssl_in_use);
579 : : #endif
580 : : #ifdef ENABLE_GSS
581 [ - + ]: 1038 : Assert(!conn->gssenc);
582 : : #endif
583 : 1038 : toSend -= toSend % 8192;
584 : : }
585 : :
8176 586 [ - + ]: 1109 : if (pqSendSome(conn, toSend) < 0)
8176 tgl@sss.pgh.pa.us 587 :UBC 0 : return EOF;
588 : : /* in nonblock mode, don't complain if unable to send it all */
589 : : }
590 : :
8176 tgl@sss.pgh.pa.us 591 :CBC 720503 : return 0;
592 : : }
593 : :
594 : : /* ----------
595 : : * pqReadData: read more data, if any is available
596 : : * Possible return values:
597 : : * 1: successfully loaded at least one more byte
598 : : * 0: no data is presently available, but no error detected
599 : : * -1: error detected (including EOF = connection closure);
600 : : * conn->errorMessage set
601 : : * NOTE: callers must not assume that pointers or indexes into conn->inBuffer
602 : : * remain valid across this call!
603 : : * ----------
604 : : */
605 : : int
9985 bruce@momjian.us 606 : 941550 : pqReadData(PGconn *conn)
607 : : {
9490 tgl@sss.pgh.pa.us 608 : 941550 : int someread = 0;
609 : : int nread;
610 : :
4161 bruce@momjian.us 611 [ + + ]: 941550 : if (conn->sock == PGINVALID_SOCKET)
612 : : {
1026 peter@eisentraut.org 613 : 2 : libpq_append_conn_error(conn, "connection not open");
9985 bruce@momjian.us 614 : 2 : return -1;
615 : : }
616 : :
617 : : /* Left-justify any data in the buffer to make room */
618 [ + + ]: 941548 : if (conn->inStart < conn->inEnd)
619 : : {
8867 tgl@sss.pgh.pa.us 620 [ + + ]: 217284 : if (conn->inStart > 0)
621 : : {
622 : 49712 : memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
623 : 49712 : conn->inEnd - conn->inStart);
624 : 49712 : conn->inEnd -= conn->inStart;
625 : 49712 : conn->inCursor -= conn->inStart;
626 : 49712 : conn->inStart = 0;
627 : : }
628 : : }
629 : : else
630 : : {
631 : : /* buffer is logically empty, reset it */
9985 bruce@momjian.us 632 : 724264 : conn->inStart = conn->inCursor = conn->inEnd = 0;
633 : : }
634 : :
635 : : /*
636 : : * If the buffer is fairly full, enlarge it. We need to be able to enlarge
637 : : * the buffer in case a single message exceeds the initial buffer size. We
638 : : * enlarge before filling the buffer entirely so as to avoid asking the
639 : : * kernel for a partial packet. The magic constant here should be large
640 : : * enough for a TCP packet or Unix pipe bufferload. 8K is the usual pipe
641 : : * buffer size, so...
642 : : */
9503 tgl@sss.pgh.pa.us 643 [ + + ]: 941548 : if (conn->inBufSize - conn->inEnd < 8192)
644 : : {
6309 645 [ + - ]: 2 : if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
646 : : {
647 : : /*
648 : : * We don't insist that the enlarge worked, but we need some room
649 : : */
8173 tgl@sss.pgh.pa.us 650 [ # # ]:UBC 0 : if (conn->inBufSize - conn->inEnd < 100)
651 : 0 : return -1; /* errorMessage already set */
652 : : }
653 : : }
654 : :
655 : : /* OK, try to read some data */
8545 bruce@momjian.us 656 :CBC 1051819 : retry3:
8484 tgl@sss.pgh.pa.us 657 : 2103638 : nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
8403 bruce@momjian.us 658 : 1051819 : conn->inBufSize - conn->inEnd);
9985 659 [ + + ]: 1051819 : if (nread < 0)
660 : : {
1792 tgl@sss.pgh.pa.us 661 [ - + + - ]: 417134 : switch (SOCK_ERRNO)
662 : : {
1792 tgl@sss.pgh.pa.us 663 :UBC 0 : case EINTR:
664 : 0 : goto retry3;
665 : :
666 : : /* Some systems return EAGAIN/EWOULDBLOCK for no data */
667 : : #ifdef EAGAIN
1792 tgl@sss.pgh.pa.us 668 :CBC 417120 : case EAGAIN:
669 : 417120 : return someread;
670 : : #endif
671 : : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
672 : : case EWOULDBLOCK:
673 : : return someread;
674 : : #endif
675 : :
676 : : /* We might get ECONNRESET etc here if connection failed */
677 : 14 : case ALL_CONNECTION_FAILURE_ERRNOS:
678 : 14 : goto definitelyFailed;
679 : :
1792 tgl@sss.pgh.pa.us 680 :UBC 0 : default:
681 : : /* pqsecure_read set the error message for us */
682 : 0 : return -1;
683 : : }
684 : : }
9985 bruce@momjian.us 685 [ + + ]:CBC 634685 : if (nread > 0)
686 : : {
687 : 634493 : conn->inEnd += nread;
688 : :
689 : : /*
690 : : * Hack to deal with the fact that some kernels will only give us back
691 : : * 1 packet per recv() call, even if we asked for more and there is
692 : : * more available. If it looks like we are reading a long message,
693 : : * loop back to recv() again immediately, until we run out of data or
694 : : * buffer space. Without this, the block-and-restart behavior of
695 : : * libpq's higher levels leads to O(N^2) performance on long messages.
696 : : *
697 : : * Since we left-justified the data above, conn->inEnd gives the
698 : : * amount of data already read in the current message. We consider
699 : : * the message "long" once we have acquired 32k ...
700 : : */
9490 tgl@sss.pgh.pa.us 701 [ + + ]: 634493 : if (conn->inEnd > 32768 &&
702 [ + + ]: 196483 : (conn->inBufSize - conn->inEnd) >= 8192)
703 : : {
704 : 110271 : someread = 1;
8545 bruce@momjian.us 705 : 110271 : goto retry3;
706 : : }
9985 707 : 524222 : return 1;
708 : : }
709 : :
9490 tgl@sss.pgh.pa.us 710 [ - + ]: 192 : if (someread)
9490 tgl@sss.pgh.pa.us 711 :UBC 0 : return 1; /* got a zero read after successful tries */
712 : :
713 : : /*
714 : : * A return value of 0 could mean just that no data is now available, or
715 : : * it could mean EOF --- that is, the server has closed the connection.
716 : : * Since we have the socket in nonblock mode, the only way to tell the
717 : : * difference is to see if select() is saying that the file is ready.
718 : : * Grumble. Fortunately, we don't expect this path to be taken much,
719 : : * since in normal practice we should not be trying to read data unless
720 : : * the file selected for reading already.
721 : : *
722 : : * In SSL mode it's even worse: SSL_read() could say WANT_READ and then
723 : : * data could arrive before we make the pqReadReady() test, but the second
724 : : * SSL_read() could still say WANT_READ because the data received was not
725 : : * a complete SSL record. So we must play dumb and assume there is more
726 : : * data, relying on the SSL layer to detect true EOF.
727 : : */
728 : :
729 : : #ifdef USE_SSL
4044 heikki.linnakangas@i 730 [ + + ]:CBC 192 : if (conn->ssl_in_use)
8069 tgl@sss.pgh.pa.us 731 : 102 : return 0;
732 : : #endif
733 : :
9412 bruce@momjian.us 734 [ - + - ]: 90 : switch (pqReadReady(conn))
735 : : {
9412 bruce@momjian.us 736 :UBC 0 : case 0:
737 : : /* definitely no data available */
738 : 0 : return 0;
9412 bruce@momjian.us 739 :CBC 90 : case 1:
740 : : /* ready for read */
741 : 90 : break;
9412 bruce@momjian.us 742 :UBC 0 : default:
743 : : /* we override pqReadReady's message with something more useful */
3972 tgl@sss.pgh.pa.us 744 : 0 : goto definitelyEOF;
745 : : }
746 : :
747 : : /*
748 : : * Still not sure that it's EOF, because some data could have just
749 : : * arrived.
750 : : */
8545 bruce@momjian.us 751 :CBC 90 : retry4:
8484 tgl@sss.pgh.pa.us 752 : 180 : nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
753 : 90 : conn->inBufSize - conn->inEnd);
9985 bruce@momjian.us 754 [ - + ]: 90 : if (nread < 0)
755 : : {
1792 tgl@sss.pgh.pa.us 756 [ # # # # ]:UBC 0 : switch (SOCK_ERRNO)
757 : : {
758 : 0 : case EINTR:
759 : 0 : goto retry4;
760 : :
761 : : /* Some systems return EAGAIN/EWOULDBLOCK for no data */
762 : : #ifdef EAGAIN
763 : 0 : case EAGAIN:
764 : 0 : return 0;
765 : : #endif
766 : : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
767 : : case EWOULDBLOCK:
768 : : return 0;
769 : : #endif
770 : :
771 : : /* We might get ECONNRESET etc here if connection failed */
772 : 0 : case ALL_CONNECTION_FAILURE_ERRNOS:
773 : 0 : goto definitelyFailed;
774 : :
775 : 0 : default:
776 : : /* pqsecure_read set the error message for us */
777 : 0 : return -1;
778 : : }
779 : : }
9985 bruce@momjian.us 780 [ - + ]:CBC 90 : if (nread > 0)
781 : : {
9985 bruce@momjian.us 782 :UBC 0 : conn->inEnd += nread;
783 : 0 : return 1;
784 : : }
785 : :
786 : : /*
787 : : * OK, we are getting a zero read even though select() says ready. This
788 : : * means the connection has been closed. Cope.
789 : : */
3972 tgl@sss.pgh.pa.us 790 :CBC 90 : definitelyEOF:
1026 peter@eisentraut.org 791 : 90 : libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
792 : : "\tThis probably means the server terminated abnormally\n"
793 : : "\tbefore or while processing the request.");
794 : :
795 : : /* Come here if lower-level code already set a suitable errorMessage */
9848 bruce@momjian.us 796 : 104 : definitelyFailed:
797 : : /* Do *not* drop any already-read data; caller still wants it */
3586 tgl@sss.pgh.pa.us 798 : 104 : pqDropConnection(conn, false);
2999 799 : 104 : conn->status = CONNECTION_BAD; /* No more connection to backend */
9985 bruce@momjian.us 800 : 104 : return -1;
801 : : }
802 : :
803 : : /*
804 : : * pqSendSome: send data waiting in the output buffer.
805 : : *
806 : : * len is how much to try to send (typically equal to outCount, but may
807 : : * be less).
808 : : *
809 : : * Return 0 on success, -1 on failure and 1 when not all data could be sent
810 : : * because the socket would block and the connection is non-blocking.
811 : : *
812 : : * Note that this is also responsible for consuming data from the socket
813 : : * (putting it in conn->inBuffer) in any situation where we can't send
814 : : * all the specified data immediately.
815 : : *
816 : : * If a socket-level write failure occurs, conn->write_failed is set and the
817 : : * error message is saved in conn->write_err_msg, but we clear the output
818 : : * buffer and return zero anyway; this is because callers should soldier on
819 : : * until we have read what we can from the server and checked for an error
820 : : * message. write_err_msg should be reported only when we are unable to
821 : : * obtain a server error first. Much of that behavior is implemented at
822 : : * lower levels, but this function deals with some edge cases.
823 : : */
824 : : static int
8176 tgl@sss.pgh.pa.us 825 : 487838 : pqSendSome(PGconn *conn, int len)
826 : : {
9867 bruce@momjian.us 827 : 487838 : char *ptr = conn->outBuffer;
8176 tgl@sss.pgh.pa.us 828 : 487838 : int remaining = conn->outCount;
829 : 487838 : int result = 0;
830 : :
831 : : /*
832 : : * If we already had a write failure, we will never again try to send data
833 : : * on that connection. Even if the kernel would let us, we've probably
834 : : * lost message boundary sync with the server. conn->write_failed
835 : : * therefore persists until the connection is reset, and we just discard
836 : : * all data presented to be written. However, as long as we still have a
837 : : * valid socket, we should continue to absorb data from the backend, so
838 : : * that we can collect any final error messages.
839 : : */
2363 840 [ - + ]: 487838 : if (conn->write_failed)
841 : : {
842 : : /* conn->write_err_msg should be set up already */
2363 tgl@sss.pgh.pa.us 843 :UBC 0 : conn->outCount = 0;
844 : : /* Absorb input data if any, and detect socket closure */
1917 845 [ # # ]: 0 : if (conn->sock != PGINVALID_SOCKET)
846 : : {
847 [ # # ]: 0 : if (pqReadData(conn) < 0)
848 : 0 : return -1;
849 : : }
2363 850 : 0 : return 0;
851 : : }
852 : :
4161 bruce@momjian.us 853 [ - + ]:CBC 487838 : if (conn->sock == PGINVALID_SOCKET)
854 : : {
2363 tgl@sss.pgh.pa.us 855 :UBC 0 : conn->write_failed = true;
856 : : /* Store error message in conn->write_err_msg, if possible */
857 : : /* (strdup failure is OK, we'll cope later) */
1699 858 : 0 : conn->write_err_msg = strdup(libpq_gettext("connection not open\n"));
859 : : /* Discard queued data; no chance it'll ever be sent */
4224 860 : 0 : conn->outCount = 0;
2363 861 : 0 : return 0;
862 : : }
863 : :
864 : : /* while there's still data to send */
9985 bruce@momjian.us 865 [ + + ]:CBC 975690 : while (len > 0)
866 : : {
867 : : int sent;
868 : :
869 : : #ifndef WIN32
8484 tgl@sss.pgh.pa.us 870 : 487855 : sent = pqsecure_write(conn, ptr, len);
871 : : #else
872 : :
873 : : /*
874 : : * Windows can fail on large sends, per KB article Q201213. The
875 : : * failure-point appears to be different in different versions of
876 : : * Windows, but 64k should always be safe.
877 : : */
878 : : sent = pqsecure_write(conn, ptr, Min(len, 65536));
879 : : #endif
880 : :
9985 bruce@momjian.us 881 [ + + ]: 487855 : if (sent < 0)
882 : : {
883 : : /* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble */
8782 884 [ + - - ]: 20 : switch (SOCK_ERRNO)
885 : : {
886 : : #ifdef EAGAIN
9985 887 : 20 : case EAGAIN:
888 : 20 : break;
889 : : #endif
890 : : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
891 : : case EWOULDBLOCK:
892 : : break;
893 : : #endif
9363 bruce@momjian.us 894 :UBC 0 : case EINTR:
895 : 0 : continue;
896 : :
5158 tgl@sss.pgh.pa.us 897 : 0 : default:
898 : : /* Discard queued data; no chance it'll ever be sent */
8176 899 : 0 : conn->outCount = 0;
900 : :
901 : : /* Absorb input data if any, and detect socket closure */
1917 902 [ # # ]: 0 : if (conn->sock != PGINVALID_SOCKET)
903 : : {
904 [ # # ]: 0 : if (pqReadData(conn) < 0)
905 : 0 : return -1;
906 : : }
907 : :
908 : : /*
909 : : * Lower-level code should already have filled
910 : : * conn->write_err_msg (and set conn->write_failed) or
911 : : * conn->errorMessage. In the former case, we pretend
912 : : * there's no problem; the write_failed condition will be
913 : : * dealt with later. Otherwise, report the error now.
914 : : */
1302 915 [ # # ]: 0 : if (conn->write_failed)
916 : 0 : return 0;
917 : : else
918 : 0 : return -1;
919 : : }
920 : : }
921 : : else
922 : : {
9985 bruce@momjian.us 923 :CBC 487835 : ptr += sent;
924 : 487835 : len -= sent;
8176 tgl@sss.pgh.pa.us 925 : 487835 : remaining -= sent;
926 : : }
927 : :
9985 bruce@momjian.us 928 [ + + ]: 487855 : if (len > 0)
929 : : {
930 : : /*
931 : : * We didn't send it all, wait till we can send more.
932 : : *
933 : : * There are scenarios in which we can't send data because the
934 : : * communications channel is full, but we cannot expect the server
935 : : * to clear the channel eventually because it's blocked trying to
936 : : * send data to us. (This can happen when we are sending a large
937 : : * amount of COPY data, and the server has generated lots of
938 : : * NOTICE responses.) To avoid a deadlock situation, we must be
939 : : * prepared to accept and buffer incoming data before we try
940 : : * again. Furthermore, it is possible that such incoming data
941 : : * might not arrive until after we've gone to sleep. Therefore,
942 : : * we wait for either read ready or write ready.
943 : : *
944 : : * In non-blocking mode, we don't wait here directly, but return 1
945 : : * to indicate that data is still pending. The caller should wait
946 : : * for both read and write ready conditions, and call
947 : : * PQconsumeInput() on read ready, but just in case it doesn't, we
948 : : * call pqReadData() ourselves before returning. That's not
949 : : * enough if the data has not arrived yet, but it's the best we
950 : : * can do, and works pretty well in practice. (The documentation
951 : : * used to say that you only need to wait for write-ready, so
952 : : * there are still plenty of applications like that out there.)
953 : : *
954 : : * Note that errors here don't result in write_failed becoming
955 : : * set.
956 : : */
7993 tgl@sss.pgh.pa.us 957 [ - + ]: 20 : if (pqReadData(conn) < 0)
958 : : {
7993 tgl@sss.pgh.pa.us 959 :UBC 0 : result = -1; /* error message already set up */
960 : 0 : break;
961 : : }
962 : :
3848 heikki.linnakangas@i 963 [ + + ]:CBC 20 : if (pqIsnonblocking(conn))
964 : : {
965 : 3 : result = 1;
966 : 3 : break;
967 : : }
968 : :
2943 peter_e@gmx.net 969 [ - + ]: 17 : if (pqWait(true, true, conn))
970 : : {
8176 tgl@sss.pgh.pa.us 971 :UBC 0 : result = -1;
972 : 0 : break;
973 : : }
974 : : }
975 : : }
976 : :
977 : : /* shift the remaining contents of the buffer */
8176 tgl@sss.pgh.pa.us 978 [ + + ]:CBC 487838 : if (remaining > 0)
979 : 1038 : memmove(conn->outBuffer, ptr, remaining);
980 : 487838 : conn->outCount = remaining;
981 : :
982 : 487838 : return result;
983 : : }
984 : :
985 : :
986 : : /*
987 : : * pqFlush: send any data waiting in the output buffer
988 : : *
989 : : * Return 0 on success, -1 on failure and 1 when not all data could be sent
990 : : * because the socket would block and the connection is non-blocking.
991 : : * (See pqSendSome comments about how failure should be handled.)
992 : : */
993 : : int
8586 bruce@momjian.us 994 : 814764 : pqFlush(PGconn *conn)
995 : : {
8176 tgl@sss.pgh.pa.us 996 [ + + ]: 814764 : if (conn->outCount > 0)
997 : : {
1621 alvherre@alvh.no-ip. 998 [ + + ]: 486729 : if (conn->Pfdebug)
999 : 54 : fflush(conn->Pfdebug);
1000 : :
8176 tgl@sss.pgh.pa.us 1001 : 486729 : return pqSendSome(conn, conn->outCount);
1002 : : }
1003 : :
8586 bruce@momjian.us 1004 : 328035 : return 0;
1005 : : }
1006 : :
1007 : :
1008 : : /*
1009 : : * pqWait: wait until we can read or write the connection socket
1010 : : *
1011 : : * JAB: If SSL enabled and used and forRead, buffered bytes short-circuit the
1012 : : * call to select().
1013 : : *
1014 : : * We also stop waiting and return if the kernel flags an exception condition
1015 : : * on the socket. The actual error condition will be detected and reported
1016 : : * when the caller tries to read or write the socket.
1017 : : */
1018 : : int
9985 1019 : 443570 : pqWait(int forRead, int forWrite, PGconn *conn)
1020 : : {
450 tgl@sss.pgh.pa.us 1021 : 443570 : return pqWaitTimed(forRead, forWrite, conn, -1);
1022 : : }
1023 : :
1024 : : /*
1025 : : * pqWaitTimed: wait, but not past end_time.
1026 : : *
1027 : : * Returns -1 on failure, 0 if the socket is readable/writable, 1 if it timed out.
1028 : : *
1029 : : * The timeout is specified by end_time, which is the int64 number of
1030 : : * microseconds since the Unix epoch (that is, time_t times 1 million).
1031 : : * Timeout is infinite if end_time is -1. Timeout is immediate (no blocking)
1032 : : * if end_time is 0 (or indeed, any time before now).
1033 : : */
1034 : : int
1035 : 468200 : pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
1036 : : {
1037 : : int result;
1038 : :
1039 : 468200 : result = pqSocketCheck(conn, forRead, forWrite, end_time);
1040 : :
8220 1041 [ + + ]: 468200 : if (result < 0)
3032 rhaas@postgresql.org 1042 : 34 : return -1; /* errorMessage is already set */
1043 : :
8220 tgl@sss.pgh.pa.us 1044 [ + + ]: 468166 : if (result == 0)
1045 : : {
1026 peter@eisentraut.org 1046 : 1 : libpq_append_conn_error(conn, "timeout expired");
3032 rhaas@postgresql.org 1047 : 1 : return 1;
1048 : : }
1049 : :
8220 tgl@sss.pgh.pa.us 1050 : 468165 : return 0;
1051 : : }
1052 : :
1053 : : /*
1054 : : * pqReadReady: is select() saying the file is ready to read?
1055 : : * Returns -1 on failure, 0 if not ready, 1 if ready.
1056 : : */
1057 : : int
8176 1058 : 90 : pqReadReady(PGconn *conn)
1059 : : {
450 1060 : 90 : return pqSocketCheck(conn, 1, 0, 0);
1061 : : }
1062 : :
1063 : : /*
1064 : : * pqWriteReady: is select() saying the file is ready to write?
1065 : : * Returns -1 on failure, 0 if not ready, 1 if ready.
1066 : : */
1067 : : int
8176 tgl@sss.pgh.pa.us 1068 :UBC 0 : pqWriteReady(PGconn *conn)
1069 : : {
450 1070 : 0 : return pqSocketCheck(conn, 0, 1, 0);
1071 : : }
1072 : :
1073 : : /*
1074 : : * Checks a socket, using poll or select, for data to be read, written,
1075 : : * or both. Returns >0 if one or more conditions are met, 0 if it timed
1076 : : * out, -1 if an error occurred.
1077 : : *
1078 : : * If an altsock is set for asynchronous authentication, that will be used in
1079 : : * preference to the "server" socket. Otherwise, if SSL is in use, the SSL
1080 : : * buffer is checked prior to checking the socket for read data directly.
1081 : : */
1082 : : static int
450 tgl@sss.pgh.pa.us 1083 :CBC 468290 : pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
1084 : : {
1085 : : int result;
1086 : : pgsocket sock;
1087 : :
8220 1088 [ - + ]: 468290 : if (!conn)
8220 tgl@sss.pgh.pa.us 1089 :UBC 0 : return -1;
1090 : :
212 dgustafsson@postgres 1091 [ + + ]:CBC 468290 : if (conn->altsock != PGINVALID_SOCKET)
1092 : 282 : sock = conn->altsock;
1093 : : else
1094 : : {
1095 : 468008 : sock = conn->sock;
1096 [ + + ]: 468008 : if (sock == PGINVALID_SOCKET)
1097 : : {
1098 : 34 : libpq_append_conn_error(conn, "invalid socket");
1099 : 34 : return -1;
1100 : : }
1101 : :
1102 : : #ifdef USE_SSL
1103 : : /* Check for SSL library buffering read bytes */
1104 [ + + + + : 467974 : if (forRead && conn->ssl_in_use && pgtls_read_pending(conn))
- + ]
1105 : : {
1106 : : /* short-circuit the select */
212 dgustafsson@postgres 1107 :UBC 0 : return 1;
1108 : : }
1109 : : #endif
1110 : : }
1111 : :
1112 : : /* We will retry as long as we get EINTR */
1113 : : do
212 dgustafsson@postgres 1114 :CBC 468258 : result = PQsocketPoll(sock, forRead, forWrite, end_time);
8220 tgl@sss.pgh.pa.us 1115 [ + + + - ]: 468258 : while (result < 0 && SOCK_ERRNO == EINTR);
1116 : :
1117 [ - + ]: 468256 : if (result < 0)
1118 : : {
1119 : : char sebuf[PG_STRERROR_R_BUFLEN];
1120 : :
1026 peter@eisentraut.org 1121 :UBC 0 : libpq_append_conn_error(conn, "%s() failed: %s", "select",
841 tgl@sss.pgh.pa.us 1122 : 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1123 : : }
1124 : :
8220 tgl@sss.pgh.pa.us 1125 :CBC 468256 : return result;
1126 : : }
1127 : :
1128 : :
1129 : : /*
1130 : : * Check a file descriptor for read and/or write data, possibly waiting.
1131 : : * If neither forRead nor forWrite are set, immediately return a timeout
1132 : : * condition (without waiting). Return >0 if condition is met, 0
1133 : : * if a timeout occurred, -1 if an error or interrupt occurred.
1134 : : *
1135 : : * The timeout is specified by end_time, which is the int64 number of
1136 : : * microseconds since the Unix epoch (that is, time_t times 1 million).
1137 : : * Timeout is infinite if end_time is -1. Timeout is immediate (no blocking)
1138 : : * if end_time is 0 (or indeed, any time before now).
1139 : : */
1140 : : int
450 1141 : 961520 : PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time)
1142 : : {
1143 : : /* We use poll(2) if available, otherwise select(2) */
1144 : : #ifdef HAVE_POLL
1145 : : struct pollfd input_fd;
1146 : : int timeout_ms;
1147 : :
8176 1148 [ + + - + ]: 961520 : if (!forRead && !forWrite)
8176 tgl@sss.pgh.pa.us 1149 :UBC 0 : return 0;
1150 : :
8069 bruce@momjian.us 1151 :CBC 961520 : input_fd.fd = sock;
1152 : 961520 : input_fd.events = POLLERR;
8220 tgl@sss.pgh.pa.us 1153 : 961520 : input_fd.revents = 0;
1154 : :
1155 [ + + ]: 961520 : if (forRead)
1156 : 949171 : input_fd.events |= POLLIN;
1157 [ + + ]: 961520 : if (forWrite)
1158 : 12366 : input_fd.events |= POLLOUT;
1159 : :
1160 : : /* Compute appropriate timeout interval */
450 1161 [ + + ]: 961520 : if (end_time == -1)
8220 1162 : 468156 : timeout_ms = -1;
450 1163 [ + + ]: 493364 : else if (end_time == 0)
1164 : 492987 : timeout_ms = 0;
1165 : : else
1166 : : {
1167 : 377 : pg_usec_time_t now = PQgetCurrentTimeUSec();
1168 : :
8220 1169 [ + - ]: 377 : if (end_time > now)
450 1170 : 377 : timeout_ms = (end_time - now) / 1000;
1171 : : else
8220 tgl@sss.pgh.pa.us 1172 :UBC 0 : timeout_ms = 0;
1173 : : }
1174 : :
8220 tgl@sss.pgh.pa.us 1175 :CBC 961520 : return poll(&input_fd, 1, timeout_ms);
1176 : : #else /* !HAVE_POLL */
1177 : :
1178 : : fd_set input_mask;
1179 : : fd_set output_mask;
1180 : : fd_set except_mask;
1181 : : struct timeval timeout;
1182 : : struct timeval *ptr_timeout;
1183 : :
1184 : : if (!forRead && !forWrite)
1185 : : return 0;
1186 : :
1187 : : FD_ZERO(&input_mask);
1188 : : FD_ZERO(&output_mask);
1189 : : FD_ZERO(&except_mask);
1190 : : if (forRead)
1191 : : FD_SET(sock, &input_mask);
1192 : :
1193 : : if (forWrite)
1194 : : FD_SET(sock, &output_mask);
1195 : : FD_SET(sock, &except_mask);
1196 : :
1197 : : /* Compute appropriate timeout interval */
1198 : : if (end_time == -1)
1199 : : ptr_timeout = NULL;
1200 : : else if (end_time == 0)
1201 : : {
1202 : : timeout.tv_sec = 0;
1203 : : timeout.tv_usec = 0;
1204 : : ptr_timeout = &timeout;
1205 : : }
1206 : : else
1207 : : {
1208 : : pg_usec_time_t now = PQgetCurrentTimeUSec();
1209 : :
1210 : : if (end_time > now)
1211 : : {
1212 : : timeout.tv_sec = (end_time - now) / 1000000;
1213 : : timeout.tv_usec = (end_time - now) % 1000000;
1214 : : }
1215 : : else
1216 : : {
1217 : : timeout.tv_sec = 0;
1218 : : timeout.tv_usec = 0;
1219 : : }
1220 : : ptr_timeout = &timeout;
1221 : : }
1222 : :
1223 : : return select(sock + 1, &input_mask, &output_mask,
1224 : : &except_mask, ptr_timeout);
1225 : : #endif /* HAVE_POLL */
1226 : : }
1227 : :
1228 : : /*
1229 : : * PQgetCurrentTimeUSec: get current time with microsecond precision
1230 : : *
1231 : : * This provides a platform-independent way of producing a reference
1232 : : * value for PQsocketPoll's timeout parameter.
1233 : : */
1234 : : pg_usec_time_t
450 1235 : 730 : PQgetCurrentTimeUSec(void)
1236 : : {
1237 : : struct timeval tval;
1238 : :
1239 : 730 : gettimeofday(&tval, NULL);
1240 : 730 : return (pg_usec_time_t) tval.tv_sec * 1000000 + tval.tv_usec;
1241 : : }
1242 : :
1243 : :
1244 : : /*
1245 : : * A couple of "miscellaneous" multibyte related functions. They used
1246 : : * to be in fe-print.c but that file is doomed.
1247 : : */
1248 : :
1249 : : /*
1250 : : * Like pg_encoding_mblen(). Use this in callers that want the
1251 : : * dynamically-linked libpq's stance on encodings, even if that means
1252 : : * different behavior in different startups of the executable.
1253 : : */
1254 : : int
7287 1255 : 27045991 : PQmblen(const char *s, int encoding)
1256 : : {
7178 neilc@samurai.com 1257 : 27045991 : return pg_encoding_mblen(encoding, s);
1258 : : }
1259 : :
1260 : : /*
1261 : : * Like pg_encoding_mblen_bounded(). Use this in callers that want the
1262 : : * dynamically-linked libpq's stance on encodings, even if that means
1263 : : * different behavior in different startups of the executable.
1264 : : */
1265 : : int
1552 tgl@sss.pgh.pa.us 1266 : 393128 : PQmblenBounded(const char *s, int encoding)
1267 : : {
1268 : 393128 : return strnlen(s, pg_encoding_mblen(encoding, s));
1269 : : }
1270 : :
1271 : : /*
1272 : : * Returns the display length of the character beginning at s, using the
1273 : : * specified encoding.
1274 : : */
1275 : : int
7287 1276 : 27045879 : PQdsplen(const char *s, int encoding)
1277 : : {
7178 neilc@samurai.com 1278 : 27045879 : return pg_encoding_dsplen(encoding, s);
1279 : : }
1280 : :
1281 : : /*
1282 : : * Get encoding id from environment variable PGCLIENTENCODING.
1283 : : */
1284 : : int
9352 peter_e@gmx.net 1285 : 8485 : PQenv2encoding(void)
1286 : : {
1287 : : char *str;
8766 ishii@postgresql.org 1288 : 8485 : int encoding = PG_SQL_ASCII;
1289 : :
9352 peter_e@gmx.net 1290 : 8485 : str = getenv("PGCLIENTENCODING");
1291 [ + + + - ]: 8485 : if (str && *str != '\0')
1292 : : {
1293 : 6 : encoding = pg_char_to_encoding(str);
6538 tgl@sss.pgh.pa.us 1294 [ - + ]: 6 : if (encoding < 0)
6538 tgl@sss.pgh.pa.us 1295 :UBC 0 : encoding = PG_SQL_ASCII;
1296 : : }
7178 neilc@samurai.com 1297 :CBC 8485 : return encoding;
1298 : : }
1299 : :
1300 : :
1301 : : #ifdef ENABLE_NLS
1302 : :
1303 : : static void
1934 noah@leadboat.com 1304 : 28104 : libpq_binddomain(void)
1305 : : {
1306 : : /*
1307 : : * At least on Windows, there are gettext implementations that fail if
1308 : : * multiple threads call bindtextdomain() concurrently. Use a mutex and
1309 : : * flag variable to ensure that we call it just once per process. It is
1310 : : * not known that similar bugs exist on non-Windows platforms, but we
1311 : : * might as well do it the same way everywhere.
1312 : : */
1313 : : static volatile bool already_bound = false;
1314 : : static pthread_mutex_t binddomain_mutex = PTHREAD_MUTEX_INITIALIZER;
1315 : :
8819 peter_e@gmx.net 1316 [ + + ]: 28104 : if (!already_bound)
1317 : : {
1318 : : /* bindtextdomain() does not preserve errno */
1319 : : #ifdef WIN32
1320 : : int save_errno = GetLastError();
1321 : : #else
7266 bruce@momjian.us 1322 : 10700 : int save_errno = errno;
1323 : : #endif
1324 : :
575 tgl@sss.pgh.pa.us 1325 : 10700 : (void) pthread_mutex_lock(&binddomain_mutex);
1326 : :
1327 [ + - ]: 10700 : if (!already_bound)
1328 : : {
1329 : : const char *ldir;
1330 : :
1331 : : /*
1332 : : * No relocatable lookup here because the calling executable could
1333 : : * be anywhere
1334 : : */
1335 : 10700 : ldir = getenv("PGLOCALEDIR");
1336 [ + + ]: 10700 : if (!ldir)
1337 : 129 : ldir = LOCALEDIR;
1338 : 10700 : bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir);
1339 : 10700 : already_bound = true;
1340 : : }
1341 : :
1342 : 10700 : (void) pthread_mutex_unlock(&binddomain_mutex);
1343 : :
1344 : : #ifdef WIN32
1345 : : SetLastError(save_errno);
1346 : : #else
7367 1347 : 10700 : errno = save_errno;
1348 : : #endif
1349 : : }
4012 heikki.linnakangas@i 1350 : 28104 : }
1351 : :
1352 : : char *
1353 : 28097 : libpq_gettext(const char *msgid)
1354 : : {
1355 : 28097 : libpq_binddomain();
6113 peter_e@gmx.net 1356 : 28097 : return dgettext(PG_TEXTDOMAIN("libpq"), msgid);
1357 : : }
1358 : :
1359 : : char *
4012 heikki.linnakangas@i 1360 : 7 : libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n)
1361 : : {
1362 : 7 : libpq_binddomain();
1363 : 7 : return dngettext(PG_TEXTDOMAIN("libpq"), msgid, msgid_plural, n);
1364 : : }
1365 : :
1366 : : #endif /* ENABLE_NLS */
1367 : :
1368 : :
1369 : : /*
1370 : : * Append a formatted string to the given buffer, after translating it. A
1371 : : * newline is automatically appended; the format should not end with a
1372 : : * newline.
1373 : : */
1374 : : void
841 tgl@sss.pgh.pa.us 1375 : 35 : libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...)
1376 : : {
1026 peter@eisentraut.org 1377 : 35 : int save_errno = errno;
1378 : : bool done;
1379 : : va_list args;
1380 : :
1381 [ - + ]: 35 : Assert(fmt[strlen(fmt) - 1] != '\n');
1382 : :
1383 [ + - - + ]: 35 : if (PQExpBufferBroken(errorMessage))
1026 peter@eisentraut.org 1384 :UBC 0 : return; /* already failed */
1385 : :
1386 : : /* Loop in case we have to retry after enlarging the buffer. */
1387 : : do
1388 : : {
1026 peter@eisentraut.org 1389 :CBC 35 : errno = save_errno;
1390 : 35 : va_start(args, fmt);
1391 : 35 : done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
1392 : 35 : va_end(args);
1393 [ - + ]: 35 : } while (!done);
1394 : :
1395 : 35 : appendPQExpBufferChar(errorMessage, '\n');
1396 : : }
1397 : :
1398 : : /*
1399 : : * Append a formatted string to the error message buffer of the given
1400 : : * connection, after translating it. A newline is automatically appended; the
1401 : : * format should not end with a newline.
1402 : : */
1403 : : void
841 tgl@sss.pgh.pa.us 1404 : 760 : libpq_append_conn_error(PGconn *conn, const char *fmt,...)
1405 : : {
1026 peter@eisentraut.org 1406 : 760 : int save_errno = errno;
1407 : : bool done;
1408 : : va_list args;
1409 : :
1410 [ - + ]: 760 : Assert(fmt[strlen(fmt) - 1] != '\n');
1411 : :
1412 [ + - - + ]: 760 : if (PQExpBufferBroken(&conn->errorMessage))
1026 peter@eisentraut.org 1413 :UBC 0 : return; /* already failed */
1414 : :
1415 : : /* Loop in case we have to retry after enlarging the buffer. */
1416 : : do
1417 : : {
1026 peter@eisentraut.org 1418 :CBC 770 : errno = save_errno;
1419 : 770 : va_start(args, fmt);
1420 : 770 : done = appendPQExpBufferVA(&conn->errorMessage, libpq_gettext(fmt), args);
1421 : 770 : va_end(args);
1422 [ + + ]: 770 : } while (!done);
1423 : :
1424 : 760 : appendPQExpBufferChar(&conn->errorMessage, '\n');
1425 : : }
|