Skip to content

Commit 394eec1

Browse files
committed
Fix for EINTR returns from Win9X socket operations:
In summary, if a software writer implements timer events or other events which generate a signal with a timing fast enough to occur while libpq is inside connect(), then connect returns -EINTR. The code following the connect call does not handle this and generates an error message. The sum result is that the pg_connect() fails. If the timer or other event is right on the window of the connect() completion time, the pg_connect() may appear to work sporadically. If the event is too slow, pg_connect() will appear to always work and if the event is too fast, pg_connect() will always fail. David Ford
1 parent b66cbc1 commit 394eec1

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.182 2002/03/02 00:49:22 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.183 2002/04/15 23:34:17 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -913,8 +913,13 @@ connectDBStart(PGconn *conn)
913913
* Thus, we have to make arrangements for all eventualities.
914914
* ----------
915915
*/
916+
retry1:
916917
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
917918
{
919+
if (SOCK_ERRNO == EINTR)
920+
/* Interrupted system call - we'll just try again */
921+
goto retry1;
922+
918923
if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
919924
{
920925
/*
@@ -949,9 +954,14 @@ connectDBStart(PGconn *conn)
949954
SOCK_STRERROR(SOCK_ERRNO));
950955
goto connect_errReturn;
951956
}
957+
retry2:
952958
/* Now receive the postmasters response */
953959
if (recv(conn->sock, &SSLok, 1, 0) != 1)
954960
{
961+
if (SOCK_ERRNO == EINTR)
962+
/* Interrupted system call - we'll just try again */
963+
goto retry2;
964+
955965
printfPQExpBuffer(&conn->errorMessage,
956966
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
957967
SOCK_STRERROR(SOCK_ERRNO));
@@ -2132,8 +2142,12 @@ PQrequestCancel(PGconn *conn)
21322142
"PQrequestCancel() -- socket() failed: ");
21332143
goto cancel_errReturn;
21342144
}
2145+
retry3:
21352146
if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
21362147
{
2148+
if (SOCK_ERRNO == EINTR)
2149+
/* Interrupted system call - we'll just try again */
2150+
goto retry3;
21372151
strcpy(conn->errorMessage.data,
21382152
"PQrequestCancel() -- connect() failed: ");
21392153
goto cancel_errReturn;
@@ -2150,8 +2164,12 @@ PQrequestCancel(PGconn *conn)
21502164
crp.cp.backendPID = htonl(conn->be_pid);
21512165
crp.cp.cancelAuthCode = htonl(conn->be_key);
21522166

2167+
retry4:
21532168
if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
21542169
{
2170+
if (SOCK_ERRNO == EINTR)
2171+
/* Interrupted system call - we'll just try again */
2172+
goto retry4;
21552173
strcpy(conn->errorMessage.data,
21562174
"PQrequestCancel() -- send() failed: ");
21572175
goto cancel_errReturn;

src/interfaces/libpq/fe-misc.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*
2626
*
2727
* IDENTIFICATION
28-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.68 2002/03/06 06:10:42 momjian Exp $
28+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $
2929
*
3030
*-------------------------------------------------------------------------
3131
*/
@@ -361,7 +361,7 @@ pqReadReady(PGconn *conn)
361361
if (!conn || conn->sock < 0)
362362
return -1;
363363

364-
retry:
364+
retry1:
365365
FD_ZERO(&input_mask);
366366
FD_SET(conn->sock, &input_mask);
367367
timeout.tv_sec = 0;
@@ -371,7 +371,7 @@ pqReadReady(PGconn *conn)
371371
{
372372
if (SOCK_ERRNO == EINTR)
373373
/* Interrupted system call - we'll just try again */
374-
goto retry;
374+
goto retry1;
375375

376376
printfPQExpBuffer(&conn->errorMessage,
377377
libpq_gettext("select() failed: %s\n"),
@@ -395,7 +395,7 @@ pqWriteReady(PGconn *conn)
395395
if (!conn || conn->sock < 0)
396396
return -1;
397397

398-
retry:
398+
retry2:
399399
FD_ZERO(&input_mask);
400400
FD_SET(conn->sock, &input_mask);
401401
timeout.tv_sec = 0;
@@ -405,7 +405,7 @@ pqWriteReady(PGconn *conn)
405405
{
406406
if (SOCK_ERRNO == EINTR)
407407
/* Interrupted system call - we'll just try again */
408-
goto retry;
408+
goto retry2;
409409

410410
printfPQExpBuffer(&conn->errorMessage,
411411
libpq_gettext("select() failed: %s\n"),
@@ -478,7 +478,7 @@ pqReadData(PGconn *conn)
478478
}
479479

480480
/* OK, try to read some data */
481-
tryAgain:
481+
retry3:
482482
#ifdef USE_SSL
483483
if (conn->ssl)
484484
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
@@ -490,7 +490,7 @@ pqReadData(PGconn *conn)
490490
if (nread < 0)
491491
{
492492
if (SOCK_ERRNO == EINTR)
493-
goto tryAgain;
493+
goto retry3;
494494
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
495495
#ifdef EAGAIN
496496
if (SOCK_ERRNO == EAGAIN)
@@ -531,7 +531,7 @@ pqReadData(PGconn *conn)
531531
(conn->inBufSize - conn->inEnd) >= 8192)
532532
{
533533
someread = 1;
534-
goto tryAgain;
534+
goto retry3;
535535
}
536536
return 1;
537537
}
@@ -564,7 +564,7 @@ pqReadData(PGconn *conn)
564564
* Still not sure that it's EOF, because some data could have just
565565
* arrived.
566566
*/
567-
tryAgain2:
567+
retry4:
568568
#ifdef USE_SSL
569569
if (conn->ssl)
570570
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
@@ -576,7 +576,7 @@ pqReadData(PGconn *conn)
576576
if (nread < 0)
577577
{
578578
if (SOCK_ERRNO == EINTR)
579-
goto tryAgain2;
579+
goto retry4;
580580
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
581581
#ifdef EAGAIN
582582
if (SOCK_ERRNO == EAGAIN)
@@ -804,7 +804,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
804804

805805
if (forRead || forWrite)
806806
{
807-
retry:
807+
retry5:
808808
FD_ZERO(&input_mask);
809809
FD_ZERO(&output_mask);
810810
FD_ZERO(&except_mask);
@@ -817,7 +817,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
817817
(struct timeval *) NULL) < 0)
818818
{
819819
if (SOCK_ERRNO == EINTR)
820-
goto retry;
820+
goto retry5;
821821
printfPQExpBuffer(&conn->errorMessage,
822822
libpq_gettext("select() failed: %s\n"),
823823
SOCK_STRERROR(SOCK_ERRNO));

0 commit comments

Comments
 (0)