*** fe-connect.c.orig ώΤ αΧΗ 8 12:22:46 2002 --- fe-connect.c πΤ αΧΗ 9 14:57:18 2002 *************** *** 114,119 **** --- 114,122 ---- {"password", "PGPASSWORD", DefaultPassword, NULL, "Database-Password", "*", 20}, + {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL, + "Connect-timeout", "", 10}, /* strlen( INT32_MAX) == 10 */ + {"dbname", "PGDATABASE", NULL, NULL, "Database-Name", "", 20}, *************** *** 307,312 **** --- 310,317 ---- conn->pguser = tmp ? strdup(tmp) : NULL; tmp = conninfo_getval(connOptions, "password"); conn->pgpass = tmp ? strdup(tmp) : NULL; + tmp = conninfo_getval(connOptions, "connect_timeout"); + conn->connect_timeout = tmp ? strdup(tmp) : NULL; #ifdef USE_SSL tmp = conninfo_getval(connOptions, "requiressl"); conn->require_ssl = tmp ? (tmp[0] == '1' ? true : false) : false; *************** *** 1050,1060 **** { PostgresPollingStatusType flag = PGRES_POLLING_WRITING; if (conn == NULL || conn->status == CONNECTION_BAD) return 0; ! for (;;) { /* * Wait, if necessary. Note that the initial state (just after * PQconnectStart) is to wait for the socket to select for --- 1055,1086 ---- { PostgresPollingStatusType flag = PGRES_POLLING_WRITING; + time_t finish_time, start_time; + struct timeval remains, *rp = NULL; + if (conn == NULL || conn->status == CONNECTION_BAD) return 0; ! if (conn->connect_timeout != NULL) { + remains.tv_sec = atoi(conn->connect_timeout); + if (!remains.tv_sec) + { + conn->status = CONNECTION_BAD; + return 0; + } + remains.tv_usec = 0; + rp = &remains; + } + + + while (rp == NULL || remains.tv_sec > 0) + { + if ((time_t)-1 == (start_time = time(NULL))) + { + conn->status = CONNECTION_BAD; + return 0; + } /* * Wait, if necessary. Note that the initial state (just after * PQconnectStart) is to wait for the socket to select for *************** *** 1069,1075 **** return 1; /* success! */ case PGRES_POLLING_READING: ! if (pqWait(1, 0, conn)) { conn->status = CONNECTION_BAD; return 0; --- 1095,1101 ---- return 1; /* success! */ case PGRES_POLLING_READING: ! if (pqWaitTimed(1, 0, conn, rp)) { conn->status = CONNECTION_BAD; return 0; *************** *** 1077,1083 **** break; case PGRES_POLLING_WRITING: ! if (pqWait(0, 1, conn)) { conn->status = CONNECTION_BAD; return 0; --- 1103,1109 ---- break; case PGRES_POLLING_WRITING: ! if (pqWaitTimed(0, 1, conn, rp)) { conn->status = CONNECTION_BAD; return 0; *************** *** 1094,1100 **** --- 1120,1135 ---- * Now try to advance the state machine. */ flag = PQconnectPoll(conn); + + if ((time_t)-1 == (finish_time = time(NULL))) + { + conn->status = CONNECTION_BAD; + return 0; + } + remains.tv_sec -= finish_time - start_time; } + conn->status = CONNECTION_BAD; + return 0; } /* ---------------- *************** *** 1929,1934 **** --- 1964,1971 ---- free(conn->pguser); if (conn->pgpass) free(conn->pgpass); + if (conn->connect_timeout) + free(conn->connect_timeout); /* Note that conn->Pfdebug is not ours to close or free */ if (conn->notifyList) DLFreeList(conn->notifyList); *** fe-misc.c.orig ώΤ αΧΗ 8 16:33:34 2002 --- fe-misc.c ώΤ αΧΗ 8 16:33:45 2002 *************** *** 748,753 **** --- 748,759 ---- int pqWait(int forRead, int forWrite, PGconn *conn) { + return pqWaitTimed( forRead, forWrite, conn, (struct timeval *) NULL); + } + + int + pqWaitTimed(int forRead, int forWrite, PGconn *conn, struct timeval *timeout) + { fd_set input_mask; fd_set output_mask; fd_set except_mask; *************** *** 770,777 **** if (forWrite) FD_SET(conn->sock, &output_mask); FD_SET(conn->sock, &except_mask); ! if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask, ! (struct timeval *) NULL) < 0) { if (SOCK_ERRNO == EINTR) goto retry; --- 776,783 ---- if (forWrite) FD_SET(conn->sock, &output_mask); FD_SET(conn->sock, &except_mask); ! if (select(conn->sock + 1, &input_mask, &output_mask, ! &except_mask, timeout) < 0) { if (SOCK_ERRNO == EINTR) goto retry; *** libpq-int.h.orig ώΤ αΧΗ 8 16:37:56 2002 --- libpq-int.h ώΤ αΧΗ 8 16:37:37 2002 *************** *** 279,284 **** --- 279,286 ---- PQExpBufferData workBuffer; /* expansible string */ int client_encoding; /* encoding id */ + + char *connect_timeout; }; /* String descriptions of the ExecStatusTypes. *************** *** 324,329 **** --- 326,332 ---- extern int pqReadData(PGconn *conn); extern int pqFlush(PGconn *conn); extern int pqWait(int forRead, int forWrite, PGconn *conn); + extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, struct timeval* timeout); extern int pqReadReady(PGconn *conn); extern int pqWriteReady(PGconn *conn);