PostgreSQL Source Code git master
fe-cancel.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * fe-cancel.c
4 * functions related to setting up a connection to the backend
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/interfaces/libpq/fe-cancel.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres_fe.h"
17
18#include <unistd.h>
19
20#include "libpq-fe.h"
21#include "libpq-int.h"
22#include "port/pg_bswap.h"
23
24
25/*
26 * pg_cancel_conn (backing struct for PGcancelConn) is a wrapper around a
27 * PGconn to send cancellations using PQcancelBlocking and PQcancelStart.
28 * This isn't just a typedef because we want the compiler to complain when a
29 * PGconn is passed to a function that expects a PGcancelConn, and vice versa.
30 */
32{
34};
35
36/*
37 * pg_cancel (backing struct for PGcancel) stores all data necessary to send a
38 * cancel request.
39 */
41{
42 SockAddr raddr; /* Remote address */
43 int be_pid; /* PID of to-be-canceled backend */
44 int be_key; /* cancel key of to-be-canceled backend */
45 int pgtcp_user_timeout; /* tcp user timeout */
46 int keepalives; /* use TCP keepalives? */
47 int keepalives_idle; /* time between TCP keepalives */
48 int keepalives_interval; /* time between TCP keepalive
49 * retransmits */
50 int keepalives_count; /* maximum number of TCP keepalive
51 * retransmits */
52};
53
54
55/*
56 * PQcancelCreate
57 *
58 * Create and return a PGcancelConn, which can be used to securely cancel a
59 * query on the given connection.
60 *
61 * This requires either following the non-blocking flow through
62 * PQcancelStart() and PQcancelPoll(), or the blocking PQcancelBlocking().
63 */
66{
68 pg_conn_host originalHost;
69
70 if (cancelConn == NULL)
71 return NULL;
72
73 /* Check we have an open connection */
74 if (!conn)
75 {
76 libpq_append_conn_error(cancelConn, "connection pointer is NULL");
77 return (PGcancelConn *) cancelConn;
78 }
79
81 {
82 libpq_append_conn_error(cancelConn, "connection not open");
83 return (PGcancelConn *) cancelConn;
84 }
85
86 /*
87 * Indicate that this connection is used to send a cancellation
88 */
89 cancelConn->cancelRequest = true;
90
92 return (PGcancelConn *) cancelConn;
93
94 /*
95 * Compute derived options
96 */
98 return (PGcancelConn *) cancelConn;
99
100 /*
101 * Copy cancellation token data from the original connection
102 */
105
106 /*
107 * Cancel requests should not iterate over all possible hosts. The request
108 * needs to be sent to the exact host and address that the original
109 * connection used. So we manually create the host and address arrays with
110 * a single element after freeing the host array that we generated from
111 * the connection options.
112 */
114 cancelConn->nconnhost = 1;
115 cancelConn->naddr = 1;
116
117 cancelConn->connhost = calloc(cancelConn->nconnhost, sizeof(pg_conn_host));
118 if (!cancelConn->connhost)
119 goto oom_error;
120
121 originalHost = conn->connhost[conn->whichhost];
122 if (originalHost.host)
123 {
124 cancelConn->connhost[0].host = strdup(originalHost.host);
125 if (!cancelConn->connhost[0].host)
126 goto oom_error;
127 }
128 if (originalHost.hostaddr)
129 {
130 cancelConn->connhost[0].hostaddr = strdup(originalHost.hostaddr);
131 if (!cancelConn->connhost[0].hostaddr)
132 goto oom_error;
133 }
134 if (originalHost.port)
135 {
136 cancelConn->connhost[0].port = strdup(originalHost.port);
137 if (!cancelConn->connhost[0].port)
138 goto oom_error;
139 }
140 if (originalHost.password)
141 {
142 cancelConn->connhost[0].password = strdup(originalHost.password);
143 if (!cancelConn->connhost[0].password)
144 goto oom_error;
145 }
146
147 cancelConn->addr = calloc(cancelConn->naddr, sizeof(AddrInfo));
148 if (!cancelConn->addr)
149 goto oom_error;
150
151 cancelConn->addr[0].addr = conn->raddr;
152 cancelConn->addr[0].family = conn->raddr.addr.ss_family;
153
155 return (PGcancelConn *) cancelConn;
156
157oom_error:
158 cancelConn->status = CONNECTION_BAD;
159 libpq_append_conn_error(cancelConn, "out of memory");
160 return (PGcancelConn *) cancelConn;
161}
162
163
164/*
165 * PQcancelBlocking
166 *
167 * Send a cancellation request in a blocking fashion.
168 * Returns 1 if successful 0 if not.
169 */
170int
172{
174 return 0;
175 return pqConnectDBComplete(&cancelConn->conn);
176}
177
178/*
179 * PQcancelStart
180 *
181 * Starts sending a cancellation request in a non-blocking fashion. Returns
182 * 1 if successful 0 if not.
183 */
184int
186{
187 if (!cancelConn || cancelConn->conn.status == CONNECTION_BAD)
188 return 0;
189
190 if (cancelConn->conn.status != CONNECTION_ALLOCATED)
191 {
193 "cancel request is already being sent on this connection");
194 cancelConn->conn.status = CONNECTION_BAD;
195 return 0;
196 }
197
198 return pqConnectDBStart(&cancelConn->conn);
199}
200
201/*
202 * PQcancelPoll
203 *
204 * Poll a cancel connection. For usage details see PQconnectPoll.
205 */
208{
209 PGconn *conn = &cancelConn->conn;
210 int n;
211
212 /*
213 * We leave most of the connection establishment to PQconnectPoll, since
214 * it's very similar to normal connection establishment. But once we get
215 * to the CONNECTION_AWAITING_RESPONSE we need to start doing our own
216 * thing.
217 */
219 {
220 return PQconnectPoll(conn);
221 }
222
223 /*
224 * At this point we are waiting on the server to close the connection,
225 * which is its way of communicating that the cancel has been handled.
226 */
227
228 n = pqReadData(conn);
229
230 if (n == 0)
232
233#ifndef WIN32
234
235 /*
236 * If we receive an error report it, but only if errno is non-zero.
237 * Otherwise we assume it's an EOF, which is what we expect from the
238 * server.
239 *
240 * We skip this for Windows, because Windows is a bit special in its EOF
241 * behaviour for TCP. Sometimes it will error with an ECONNRESET when
242 * there is a clean connection closure. See these threads for details:
243 * https://www.postgresql.org/message-id/flat/90b34057-4176-7bb0-0dbb-9822a5f6425b%40greiz-reinsdorf.de
244 *
245 * https://www.postgresql.org/message-id/flat/CA%2BhUKG%2BOeoETZQ%3DQw5Ub5h3tmwQhBmDA%3DnuNO3KG%3DzWfUypFAw%40mail.gmail.com
246 *
247 * PQcancel ignores such errors and reports success for the cancellation
248 * anyway, so even if this is not always correct we do the same here.
249 */
250 if (n < 0 && errno != 0)
251 {
254 }
255#endif
256
257 /*
258 * We don't expect any data, only connection closure. So if we strangely
259 * do receive some data we consider that an error.
260 */
261 if (n > 0)
262 {
263 libpq_append_conn_error(conn, "unexpected response from server");
266 }
267
268 /*
269 * Getting here means that we received an EOF, which is what we were
270 * expecting -- the cancel request has completed.
271 */
272 cancelConn->conn.status = CONNECTION_OK;
274 return PGRES_POLLING_OK;
275}
276
277/*
278 * PQcancelStatus
279 *
280 * Get the status of a cancel connection.
281 */
284{
285 return PQstatus(&cancelConn->conn);
286}
287
288/*
289 * PQcancelSocket
290 *
291 * Get the socket of the cancel connection.
292 */
293int
295{
296 return PQsocket(&cancelConn->conn);
297}
298
299/*
300 * PQcancelErrorMessage
301 *
302 * Returns the error message most recently generated by an operation on the
303 * cancel connection.
304 */
305char *
307{
308 return PQerrorMessage(&cancelConn->conn);
309}
310
311/*
312 * PQcancelReset
313 *
314 * Resets the cancel connection, so it can be reused to send a new cancel
315 * request.
316 */
317void
319{
321 cancelConn->conn.status = CONNECTION_ALLOCATED;
322 cancelConn->conn.whichhost = 0;
323 cancelConn->conn.whichaddr = 0;
324 cancelConn->conn.try_next_host = false;
325 cancelConn->conn.try_next_addr = false;
326}
327
328/*
329 * PQcancelFinish
330 *
331 * Closes and frees the cancel connection.
332 */
333void
335{
336 PQfinish(&cancelConn->conn);
337}
338
339/*
340 * PQgetCancel: get a PGcancel structure corresponding to a connection.
341 *
342 * A copy is needed to be able to cancel a running query from a different
343 * thread. If the same structure is used all structure members would have
344 * to be individually locked (if the entire structure was locked, it would
345 * be impossible to cancel a synchronous query because the structure would
346 * have to stay locked for the duration of the query).
347 */
348PGcancel *
350{
351 PGcancel *cancel;
352
353 if (!conn)
354 return NULL;
355
356 if (conn->sock == PGINVALID_SOCKET)
357 return NULL;
358
359 cancel = malloc(sizeof(PGcancel));
360 if (cancel == NULL)
361 return NULL;
362
363 memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr));
364 cancel->be_pid = conn->be_pid;
365 cancel->be_key = conn->be_key;
366 /* We use -1 to indicate an unset connection option */
367 cancel->pgtcp_user_timeout = -1;
368 cancel->keepalives = -1;
369 cancel->keepalives_idle = -1;
370 cancel->keepalives_interval = -1;
371 cancel->keepalives_count = -1;
372 if (conn->pgtcp_user_timeout != NULL)
373 {
375 &cancel->pgtcp_user_timeout,
376 conn, "tcp_user_timeout"))
377 goto fail;
378 }
379 if (conn->keepalives != NULL)
380 {
382 &cancel->keepalives,
383 conn, "keepalives"))
384 goto fail;
385 }
386 if (conn->keepalives_idle != NULL)
387 {
389 &cancel->keepalives_idle,
390 conn, "keepalives_idle"))
391 goto fail;
392 }
393 if (conn->keepalives_interval != NULL)
394 {
396 &cancel->keepalives_interval,
397 conn, "keepalives_interval"))
398 goto fail;
399 }
400 if (conn->keepalives_count != NULL)
401 {
403 &cancel->keepalives_count,
404 conn, "keepalives_count"))
405 goto fail;
406 }
407
408 return cancel;
409
410fail:
411 free(cancel);
412 return NULL;
413}
414
415/* PQfreeCancel: free a cancel structure */
416void
418{
419 free(cancel);
420}
421
422
423/*
424 * Sets an integer socket option on a TCP socket, if the provided value is
425 * not negative. Returns false if setsockopt fails for some reason.
426 *
427 * CAUTION: This needs to be signal safe, since it's used by PQcancel.
428 */
429#if defined(TCP_USER_TIMEOUT) || !defined(WIN32)
430static bool
431optional_setsockopt(int fd, int protoid, int optid, int value)
432{
433 if (value < 0)
434 return true;
435 if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0)
436 return false;
437 return true;
438}
439#endif
440
441
442/*
443 * PQcancel: old, non-encrypted, but signal-safe way of requesting query cancel
444 *
445 * The return value is true if the cancel request was successfully
446 * dispatched, false if not (in which case an error message is available).
447 * Note: successful dispatch is no guarantee that there will be any effect at
448 * the backend. The application must read the operation result as usual.
449 *
450 * On failure, an error message is stored in *errbuf, which must be of size
451 * errbufsize (recommended size is 256 bytes). *errbuf is not changed on
452 * success return.
453 *
454 * CAUTION: we want this routine to be safely callable from a signal handler
455 * (for example, an application might want to call it in a SIGINT handler).
456 * This means we cannot use any C library routine that might be non-reentrant.
457 * malloc/free are often non-reentrant, and anything that might call them is
458 * just as dangerous. We avoid sprintf here for that reason. Building up
459 * error messages with strcpy/strcat is tedious but should be quite safe.
460 * We also save/restore errno in case the signal handler support doesn't.
461 */
462int
463PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
464{
465 int save_errno = SOCK_ERRNO;
466 pgsocket tmpsock = PGINVALID_SOCKET;
467 int maxlen;
468 struct
469 {
470 uint32 packetlen;
472 } crp;
473
474 if (!cancel)
475 {
476 strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
477 /* strlcpy probably doesn't change errno, but be paranoid */
478 SOCK_ERRNO_SET(save_errno);
479 return false;
480 }
481
482 /*
483 * We need to open a temporary connection to the postmaster. Do this with
484 * only kernel calls.
485 */
486 if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
487 {
488 strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
489 goto cancel_errReturn;
490 }
491
492 /*
493 * Since this connection will only be used to send a single packet of
494 * data, we don't need NODELAY. We also don't set the socket to
495 * nonblocking mode, because the API definition of PQcancel requires the
496 * cancel to be sent in a blocking way.
497 *
498 * We do set socket options related to keepalives and other TCP timeouts.
499 * This ensures that this function does not block indefinitely when
500 * reasonable keepalive and timeout settings have been provided.
501 */
502 if (cancel->raddr.addr.ss_family != AF_UNIX &&
503 cancel->keepalives != 0)
504 {
505#ifndef WIN32
506 if (!optional_setsockopt(tmpsock, SOL_SOCKET, SO_KEEPALIVE, 1))
507 {
508 strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize);
509 goto cancel_errReturn;
510 }
511
512#ifdef PG_TCP_KEEPALIVE_IDLE
513 if (!optional_setsockopt(tmpsock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
514 cancel->keepalives_idle))
515 {
516 strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize);
517 goto cancel_errReturn;
518 }
519#endif
520
521#ifdef TCP_KEEPINTVL
522 if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPINTVL,
523 cancel->keepalives_interval))
524 {
525 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize);
526 goto cancel_errReturn;
527 }
528#endif
529
530#ifdef TCP_KEEPCNT
531 if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPCNT,
532 cancel->keepalives_count))
533 {
534 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize);
535 goto cancel_errReturn;
536 }
537#endif
538
539#else /* WIN32 */
540
541#ifdef SIO_KEEPALIVE_VALS
542 if (!pqSetKeepalivesWin32(tmpsock,
543 cancel->keepalives_idle,
544 cancel->keepalives_interval))
545 {
546 strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize);
547 goto cancel_errReturn;
548 }
549#endif /* SIO_KEEPALIVE_VALS */
550#endif /* WIN32 */
551
552 /* TCP_USER_TIMEOUT works the same way on Unix and Windows */
553#ifdef TCP_USER_TIMEOUT
554 if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT,
555 cancel->pgtcp_user_timeout))
556 {
557 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize);
558 goto cancel_errReturn;
559 }
560#endif
561 }
562
563retry3:
564 if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
565 cancel->raddr.salen) < 0)
566 {
567 if (SOCK_ERRNO == EINTR)
568 /* Interrupted system call - we'll just try again */
569 goto retry3;
570 strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
571 goto cancel_errReturn;
572 }
573
574 /* Create and send the cancel request packet. */
575
576 crp.packetlen = pg_hton32((uint32) sizeof(crp));
577 crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
578 crp.cp.backendPID = pg_hton32(cancel->be_pid);
579 crp.cp.cancelAuthCode = pg_hton32(cancel->be_key);
580
581retry4:
582 if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
583 {
584 if (SOCK_ERRNO == EINTR)
585 /* Interrupted system call - we'll just try again */
586 goto retry4;
587 strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
588 goto cancel_errReturn;
589 }
590
591 /*
592 * Wait for the postmaster to close the connection, which indicates that
593 * it's processed the request. Without this delay, we might issue another
594 * command only to find that our cancel zaps that command instead of the
595 * one we thought we were canceling. Note we don't actually expect this
596 * read to obtain any data, we are just waiting for EOF to be signaled.
597 */
598retry5:
599 if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
600 {
601 if (SOCK_ERRNO == EINTR)
602 /* Interrupted system call - we'll just try again */
603 goto retry5;
604 /* we ignore other error conditions */
605 }
606
607 /* All done */
608 closesocket(tmpsock);
609 SOCK_ERRNO_SET(save_errno);
610 return true;
611
612cancel_errReturn:
613
614 /*
615 * Make sure we don't overflow the error buffer. Leave space for the \n at
616 * the end, and for the terminating zero.
617 */
618 maxlen = errbufsize - strlen(errbuf) - 2;
619 if (maxlen >= 0)
620 {
621 /*
622 * We can't invoke strerror here, since it's not signal-safe. Settle
623 * for printing the decimal value of errno. Even that has to be done
624 * the hard way.
625 */
626 int val = SOCK_ERRNO;
627 char buf[32];
628 char *bufp;
629
630 bufp = buf + sizeof(buf) - 1;
631 *bufp = '\0';
632 do
633 {
634 *(--bufp) = (val % 10) + '0';
635 val /= 10;
636 } while (val > 0);
637 bufp -= 6;
638 memcpy(bufp, "error ", 6);
639 strncat(errbuf, bufp, maxlen);
640 strcat(errbuf, "\n");
641 }
642 if (tmpsock != PGINVALID_SOCKET)
643 closesocket(tmpsock);
644 SOCK_ERRNO_SET(save_errno);
645 return false;
646}
647
648/*
649 * PQrequestCancel: old, not thread-safe function for requesting query cancel
650 *
651 * Returns true if able to send the cancel request, false if not.
652 *
653 * On failure, the error message is saved in conn->errorMessage; this means
654 * that this can't be used when there might be other active operations on
655 * the connection object.
656 *
657 * NOTE: error messages will be cut off at the current size of the
658 * error message buffer, since we dare not try to expand conn->errorMessage!
659 */
660int
662{
663 int r;
664 PGcancel *cancel;
665
666 /* Check we have an open connection */
667 if (!conn)
668 return false;
669
670 if (conn->sock == PGINVALID_SOCKET)
671 {
673 "PQrequestCancel() -- connection is not open\n",
676 conn->errorReported = 0;
677
678 return false;
679 }
680
681 cancel = PQgetCancel(conn);
682 if (cancel)
683 {
684 r = PQcancel(cancel, conn->errorMessage.data,
686 PQfreeCancel(cancel);
687 }
688 else
689 {
690 strlcpy(conn->errorMessage.data, "out of memory",
692 r = false;
693 }
694
695 if (!r)
696 {
698 conn->errorReported = 0;
699 }
700
701 return r;
702}
uint32_t uint32
Definition: c.h:488
static PGcancel *volatile cancelConn
Definition: cancel.c:43
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-cancel.c:349
void PQcancelReset(PGcancelConn *cancelConn)
Definition: fe-cancel.c:318
PGcancelConn * PQcancelCreate(PGconn *conn)
Definition: fe-cancel.c:65
ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn)
Definition: fe-cancel.c:283
static bool optional_setsockopt(int fd, int protoid, int optid, int value)
Definition: fe-cancel.c:431
int PQcancelBlocking(PGcancelConn *cancelConn)
Definition: fe-cancel.c:171
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-cancel.c:463
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition: fe-cancel.c:207
void PQcancelFinish(PGcancelConn *cancelConn)
Definition: fe-cancel.c:334
int PQrequestCancel(PGconn *conn)
Definition: fe-cancel.c:661
void PQfreeCancel(PGcancel *cancel)
Definition: fe-cancel.c:417
int PQcancelSocket(const PGcancelConn *cancelConn)
Definition: fe-cancel.c:294
char * PQcancelErrorMessage(const PGcancelConn *cancelConn)
Definition: fe-cancel.c:306
int PQcancelStart(PGcancelConn *cancelConn)
Definition: fe-cancel.c:185
bool pqConnectOptions2(PGconn *conn)
Definition: fe-connect.c:1129
void pqClosePGconn(PGconn *conn)
Definition: fe-connect.c:4893
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2655
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:7824
void pqReleaseConnHosts(PGconn *conn)
Definition: fe-connect.c:4777
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7205
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4939
PGconn * pqMakeEmptyPGconn(void)
Definition: fe-connect.c:4594
int pqConnectDBStart(PGconn *conn)
Definition: fe-connect.c:2451
bool pqCopyPGconn(PGconn *srcConn, PGconn *dstConn)
Definition: fe-connect.c:965
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7268
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7294
int pqConnectDBComplete(PGconn *conn)
Definition: fe-connect.c:2529
int pqReadData(PGconn *conn)
Definition: fe-misc.c:580
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1372
#define calloc(a, b)
Definition: header.h:55
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
static struct @162 value
long val
Definition: informix.c:689
ConnStatusType
Definition: libpq-fe.h:80
@ CONNECTION_AWAITING_RESPONSE
Definition: libpq-fe.h:91
@ CONNECTION_BAD
Definition: libpq-fe.h:82
@ CONNECTION_OK
Definition: libpq-fe.h:81
@ CONNECTION_ALLOCATED
Definition: libpq-fe.h:104
PostgresPollingStatusType
Definition: libpq-fe.h:109
@ PGRES_POLLING_OK
Definition: libpq-fe.h:113
@ PGRES_POLLING_READING
Definition: libpq-fe.h:111
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:110
#define SOCK_ERRNO
Definition: libpq-int.h:936
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:938
#define pg_hton32(x)
Definition: pg_bswap.h:121
static char * buf
Definition: pg_test_fsync.c:72
int pgsocket
Definition: port.h:29
#define PGINVALID_SOCKET
Definition: port.h:31
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define closesocket
Definition: port.h:376
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:133
ProtocolVersion MsgType
Definition: pqcomm.h:102
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PGconn * conn
Definition: streamutil.c:53
struct sockaddr_storage addr
Definition: pqcomm.h:32
socklen_t salen
Definition: pqcomm.h:33
PGconn conn
Definition: fe-cancel.c:33
int pgtcp_user_timeout
Definition: fe-cancel.c:45
int keepalives_interval
Definition: fe-cancel.c:48
int keepalives_idle
Definition: fe-cancel.c:47
int keepalives_count
Definition: fe-cancel.c:50
SockAddr raddr
Definition: fe-cancel.c:42
int be_pid
Definition: fe-cancel.c:43
int keepalives
Definition: fe-cancel.c:46
int be_key
Definition: fe-cancel.c:44
char * host
Definition: libpq-int.h:366
char * password
Definition: libpq-int.h:369
char * port
Definition: libpq-int.h:368
char * hostaddr
Definition: libpq-int.h:367
pgsocket sock
Definition: libpq-int.h:490
int errorReported
Definition: libpq-int.h:653
int be_pid
Definition: libpq-int.h:531
int be_key
Definition: libpq-int.h:532
char * keepalives_idle
Definition: libpq-int.h:406
char * keepalives
Definition: libpq-int.h:405
char * keepalives_interval
Definition: libpq-int.h:407
char * pgtcp_user_timeout
Definition: libpq-int.h:392
PQExpBufferData errorMessage
Definition: libpq-int.h:652
SockAddr raddr
Definition: libpq-int.h:493
int whichhost
Definition: libpq-int.h:472
char * keepalives_count
Definition: libpq-int.h:409
pg_conn_host * connhost
Definition: libpq-int.h:473
ConnStatusType status
Definition: libpq-int.h:453
#define EINTR
Definition: win32_port.h:364
#define recv(s, buf, len, flags)
Definition: win32_port.h:504
#define send(s, buf, len, flags)
Definition: win32_port.h:505
#define socket(af, type, protocol)
Definition: win32_port.h:498
#define connect(s, name, namelen)
Definition: win32_port.h:502