aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-04-15 23:34:17 +0000
committerBruce Momjian <bruce@momjian.us>2002-04-15 23:34:17 +0000
commit394eec1068f1caea4c6ac4a3f2191eaef2a6719e (patch)
treeb4f795fbd896540369739947c8df3c24d81b21a3 /src
parentb66cbc1fa26aebfcfecbfff7c92d804d083af843 (diff)
downloadpostgresql-394eec1068f1caea4c6ac4a3f2191eaef2a6719e.tar.gz
postgresql-394eec1068f1caea4c6ac4a3f2191eaef2a6719e.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-connect.c20
-rw-r--r--src/interfaces/libpq/fe-misc.c24
2 files changed, 31 insertions, 13 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 772e54b8dba..9864aad9bf8 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.182 2002/03/02 00:49:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.183 2002/04/15 23:34:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -913,8 +913,13 @@ connectDBStart(PGconn *conn)
* Thus, we have to make arrangements for all eventualities.
* ----------
*/
+retry1:
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
{
+ if (SOCK_ERRNO == EINTR)
+ /* Interrupted system call - we'll just try again */
+ goto retry1;
+
if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
{
/*
@@ -949,9 +954,14 @@ connectDBStart(PGconn *conn)
SOCK_STRERROR(SOCK_ERRNO));
goto connect_errReturn;
}
+retry2:
/* Now receive the postmasters response */
if (recv(conn->sock, &SSLok, 1, 0) != 1)
{
+ if (SOCK_ERRNO == EINTR)
+ /* Interrupted system call - we'll just try again */
+ goto retry2;
+
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
SOCK_STRERROR(SOCK_ERRNO));
@@ -2132,8 +2142,12 @@ PQrequestCancel(PGconn *conn)
"PQrequestCancel() -- socket() failed: ");
goto cancel_errReturn;
}
+retry3:
if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
{
+ if (SOCK_ERRNO == EINTR)
+ /* Interrupted system call - we'll just try again */
+ goto retry3;
strcpy(conn->errorMessage.data,
"PQrequestCancel() -- connect() failed: ");
goto cancel_errReturn;
@@ -2150,8 +2164,12 @@ PQrequestCancel(PGconn *conn)
crp.cp.backendPID = htonl(conn->be_pid);
crp.cp.cancelAuthCode = htonl(conn->be_key);
+retry4:
if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
{
+ if (SOCK_ERRNO == EINTR)
+ /* Interrupted system call - we'll just try again */
+ goto retry4;
strcpy(conn->errorMessage.data,
"PQrequestCancel() -- send() failed: ");
goto cancel_errReturn;
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 5f90547d604..190d378fd9a 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -25,7 +25,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.68 2002/03/06 06:10:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -361,7 +361,7 @@ pqReadReady(PGconn *conn)
if (!conn || conn->sock < 0)
return -1;
-retry:
+retry1:
FD_ZERO(&input_mask);
FD_SET(conn->sock, &input_mask);
timeout.tv_sec = 0;
@@ -371,7 +371,7 @@ retry:
{
if (SOCK_ERRNO == EINTR)
/* Interrupted system call - we'll just try again */
- goto retry;
+ goto retry1;
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("select() failed: %s\n"),
@@ -395,7 +395,7 @@ pqWriteReady(PGconn *conn)
if (!conn || conn->sock < 0)
return -1;
-retry:
+retry2:
FD_ZERO(&input_mask);
FD_SET(conn->sock, &input_mask);
timeout.tv_sec = 0;
@@ -405,7 +405,7 @@ retry:
{
if (SOCK_ERRNO == EINTR)
/* Interrupted system call - we'll just try again */
- goto retry;
+ goto retry2;
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("select() failed: %s\n"),
@@ -478,7 +478,7 @@ pqReadData(PGconn *conn)
}
/* OK, try to read some data */
-tryAgain:
+retry3:
#ifdef USE_SSL
if (conn->ssl)
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
@@ -490,7 +490,7 @@ tryAgain:
if (nread < 0)
{
if (SOCK_ERRNO == EINTR)
- goto tryAgain;
+ goto retry3;
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
if (SOCK_ERRNO == EAGAIN)
@@ -531,7 +531,7 @@ tryAgain:
(conn->inBufSize - conn->inEnd) >= 8192)
{
someread = 1;
- goto tryAgain;
+ goto retry3;
}
return 1;
}
@@ -564,7 +564,7 @@ tryAgain:
* Still not sure that it's EOF, because some data could have just
* arrived.
*/
-tryAgain2:
+retry4:
#ifdef USE_SSL
if (conn->ssl)
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
@@ -576,7 +576,7 @@ tryAgain2:
if (nread < 0)
{
if (SOCK_ERRNO == EINTR)
- goto tryAgain2;
+ goto retry4;
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
if (SOCK_ERRNO == EAGAIN)
@@ -804,7 +804,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
if (forRead || forWrite)
{
-retry:
+retry5:
FD_ZERO(&input_mask);
FD_ZERO(&output_mask);
FD_ZERO(&except_mask);
@@ -817,7 +817,7 @@ retry:
(struct timeval *) NULL) < 0)
{
if (SOCK_ERRNO == EINTR)
- goto retry;
+ goto retry5;
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("select() failed: %s\n"),
SOCK_STRERROR(SOCK_ERRNO));