PostgreSQL Source Code: src/interfaces/libpq/fe-cancel.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
19
23
24
25
26
27
28
29
30
32{
34};
35
36
37
38
39
41{
48
50
51
52
55};
56
57
58
59
60
61
62
63
64
65
66
69{
72
74 return NULL;
75
76
78 {
81 }
82
84 {
87 }
88
89
91 {
94 }
95
96
97
98
100
103
104
105
106
109
110
111
112
115 {
118 goto oom_error;
120 }
123
124
125
126
127
128
129
130
134
137 goto oom_error;
138
140 if (originalHost.host)
141 {
142 cancelConn->connhost[0].host = strdup(originalHost.host);
144 goto oom_error;
145 }
147 {
149 if (->connhost[0].hostaddr)
150 goto oom_error;
151 }
152 if (originalHost.port)
153 {
154 cancelConn->connhost[0].port = strdup(originalHost.port);
156 goto oom_error;
157 }
159 {
161 if (->connhost[0].password)
162 goto oom_error;
163 }
164
167 goto oom_error;
168
171
174
175oom_error:
179}
180
181
182
183
184
185
186
187
188int
190{
192 return 0;
194}
195
196
197
198
199
200
201
202int
204{
206 return 0;
207
209 {
211 "cancel request is already being sent on this connection");
213 return 0;
214 }
215
217}
218
219
220
221
222
223
226{
228 int n;
229
230
231
232
233
234
235
237 {
239 }
240
241
242
243
244
245
247
248 if (n == 0)
250
251#ifndef WIN32
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268 if (n < 0 && errno != 0)
269 {
272 }
273#endif
274
275
276
277
278
279 if (n > 0)
280 {
284 }
285
286
287
288
289
293}
294
295
296
297
298
299
302{
304}
305
306
307
308
309
310
311int
313{
315}
316
317
318
319
320
321
322
323char *
325{
327}
328
329
330
331
332
333
334
335void
337{
342 cancelConn->conn.try_next_host = false;
343 cancelConn->conn.try_next_addr = false;
344}
345
346
347
348
349
350
351void
353{
355}
356
357
358
359
360
361
362
363
364
365
368{
370 int cancel_req_len;
372
374 return NULL;
375
377 return NULL;
378
379
381 return NULL;
382
384 cancel = malloc(offsetof(PGcancel, cancel_req) + cancel_req_len);
385 if (cancel == NULL)
386 return NULL;
387
389
390
397 {
400 conn, "tcp_user_timeout"))
401 goto fail;
402 }
404 {
407 conn, "keepalives"))
408 goto fail;
409 }
411 {
414 conn, "keepalives_idle"))
415 goto fail;
416 }
418 {
421 conn, "keepalives_interval"))
422 goto fail;
423 }
425 {
428 conn, "keepalives_count"))
429 goto fail;
430 }
431
436
438
439 return cancel;
440
441fail:
442 free(cancel);
443 return NULL;
444}
445
446
447
448
449
450
451
452
453int
455{
457
458
461
462
470
471
474
475
478
480}
481
482
483void
485{
486 free(cancel);
487}
488
489
490
491
492
493
494
495
496#if defined(TCP_USER_TIMEOUT) || !defined(WIN32)
497static bool
499{
501 return true;
502 if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0)
503 return false;
504 return true;
505}
506#endif
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529int
531{
534 int maxlen;
535 char recvbuf;
536 int cancel_pkt_len;
537
538 if (!cancel)
539 {
540 strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
541
543 return false;
544 }
545
546
547
548
549
551 {
552 strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
553 goto cancel_errReturn;
554 }
555
556
557
558
559
560
561
562
563
564
565
566 if (cancel->raddr.addr.ss_family != AF_UNIX &&
568 {
569#ifndef WIN32
571 {
572 strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize);
573 goto cancel_errReturn;
574 }
575
576#ifdef PG_TCP_KEEPALIVE_IDLE
579 {
580 strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize);
581 goto cancel_errReturn;
582 }
583#endif
584
585#ifdef TCP_KEEPINTVL
588 {
589 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize);
590 goto cancel_errReturn;
591 }
592#endif
593
594#ifdef TCP_KEEPCNT
597 {
598 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize);
599 goto cancel_errReturn;
600 }
601#endif
602
603#else
604
605#ifdef SIO_KEEPALIVE_VALS
606 if (!pqSetKeepalivesWin32(tmpsock,
609 {
610 strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize);
611 goto cancel_errReturn;
612 }
613#endif
614#endif
615
616
617#ifdef TCP_USER_TIMEOUT
620 {
621 strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize);
622 goto cancel_errReturn;
623 }
624#endif
625 }
626
627retry3:
628 if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
630 {
632
633 goto retry3;
634 strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
635 goto cancel_errReturn;
636 }
637
639
640retry4:
641
642
643
644
645
646 if (send(tmpsock, (char *) &cancel->cancel_pkt_len, cancel_pkt_len, 0) != cancel_pkt_len)
647 {
649
650 goto retry4;
651 strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
652 goto cancel_errReturn;
653 }
654
655
656
657
658
659
660
661
662retry5:
663 if (recv(tmpsock, &recvbuf, 1, 0) < 0)
664 {
666
667 goto retry5;
668
669 }
670
671
674 return true;
675
676cancel_errReturn:
677
678
679
680
681
682 maxlen = errbufsize - strlen(errbuf) - 2;
683 if (maxlen >= 0)
684 {
685
686
687
688
689
691 char buf[32];
692 char *bufp;
693
694 bufp = buf + sizeof(buf) - 1;
695 *bufp = '\0';
696 do
697 {
698 *(--bufp) = (val % 10) + '0';
699 val /= 10;
700 } while (val > 0);
701 bufp -= 6;
702 memcpy(bufp, "error ", 6);
703 strncat(errbuf, bufp, maxlen);
704 strcat(errbuf, "\n");
705 }
709 return false;
710}
711
712
713
714
715
716
717
718
719
720
721
722
723
724int
726{
727 int r;
729
730
732 return false;
733
735 {
737 "PQrequestCancel() -- connection is not open\n",
741
742 return false;
743 }
744
746 if (cancel)
747 {
751 }
752 else
753 {
756 r = false;
757 }
758
759 if (!r)
760 {
763 }
764
765 return r;
766}
#define FLEXIBLE_ARRAY_MEMBER
static PGcancel *volatile cancelConn
PGcancel * PQgetCancel(PGconn *conn)
void PQcancelReset(PGcancelConn *cancelConn)
int PQsendCancelRequest(PGconn *cancelConn)
PGcancelConn * PQcancelCreate(PGconn *conn)
ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn)
static bool optional_setsockopt(int fd, int protoid, int optid, int value)
int PQcancelBlocking(PGcancelConn *cancelConn)
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
void PQcancelFinish(PGcancelConn *cancelConn)
int PQrequestCancel(PGconn *conn)
void PQfreeCancel(PGcancel *cancel)
int PQcancelSocket(const PGcancelConn *cancelConn)
char * PQcancelErrorMessage(const PGcancelConn *cancelConn)
int PQcancelStart(PGcancelConn *cancelConn)
bool pqConnectOptions2(PGconn *conn)
void pqClosePGconn(PGconn *conn)
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
void pqReleaseConnHosts(PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
PGconn * pqMakeEmptyPGconn(void)
int pqConnectDBStart(PGconn *conn)
bool pqCopyPGconn(PGconn *srcConn, PGconn *dstConn)
char * PQerrorMessage(const PGconn *conn)
int PQsocket(const PGconn *conn)
int pqConnectDBComplete(PGconn *conn)
int pqReadData(PGconn *conn)
int pqFlush(PGconn *conn)
int pqPutMsgStart(char msg_type, PGconn *conn)
int pqPutnchar(const void *s, size_t len, PGconn *conn)
int pqPutMsgEnd(PGconn *conn)
@ CONNECTION_AWAITING_RESPONSE
PostgresPollingStatusType
#define SOCK_ERRNO_SET(e)
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
size_t strlcpy(char *dst, const char *src, size_t siz)
#define CANCEL_REQUEST_CODE
void resetPQExpBuffer(PQExpBuffer str)
static int fd(const char *x, int i)
MsgType cancelRequestCode
uint8 cancelAuthCode[FLEXIBLE_ARRAY_MEMBER]
struct sockaddr_storage addr
char cancel_req[FLEXIBLE_ARRAY_MEMBER]
char * keepalives_interval
char * pgtcp_user_timeout
PQExpBufferData errorMessage
#define recv(s, buf, len, flags)
#define send(s, buf, len, flags)
#define socket(af, type, protocol)
#define connect(s, name, namelen)