diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 18a6ae7..ea8cc64 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -523,11 +523,12 @@ SET ENABLE_SEQSCAN TO OFF;
- On systems that support the TCP_KEEPIDLE socket option, specifies the
+ On systems that support the TCP_KEEPIDLE or
+ TCP_KEEPALIVE> socket option, specifies the
number of seconds between sending keepalives on an otherwise idle
- connection. A value of zero uses the system default. If TCP_KEEPIDLE is
- not supported, this parameter must be zero. This parameter is ignored for
- connections made via a Unix-domain socket.
+ connection. A value of zero uses the system default. If neither of
+ these socket options is supported, this parameter must be zero. This
+ parameter is ignored for connections made via a Unix-domain socket.
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 8f0a9cf..14d7000 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -298,10 +298,10 @@
Controls the number of seconds of inactivity after which TCP should
send a keepalive message to the server. A value of zero uses the
- system default. This parameter is ignored if the
- TCP_KEEPIDLE> socket option is not supported, for
- connections made via a Unix-domain socket, or if keepalives are
- disabled.
+ system default. This parameter is ignored if the neither the
+ TCP_KEEPIDLE> nor the TCP_KEEPALIVE> socket
+ options are supported, for connections made via a Unix-domain
+ socket, or if keepalives are disabled.
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 82f5a59..c7550a9 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1317,7 +1317,7 @@ pq_endcopyout(bool errorAbort)
int
pq_getkeepalivesidle(Port *port)
{
-#ifdef TCP_KEEPIDLE
+#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE)
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
return 0;
@@ -1328,6 +1328,7 @@ pq_getkeepalivesidle(Port *port)
{
ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);
+#ifdef TCP_KEEPIDLE
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
(char *) &port->default_keepalives_idle,
&size) < 0)
@@ -1335,6 +1336,15 @@ pq_getkeepalivesidle(Port *port)
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
port->default_keepalives_idle = -1; /* don't know */
}
+#else
+ if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
+ (char *) &port->default_keepalives_idle,
+ &size) < 0)
+ {
+ elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
+ port->default_keepalives_idle = -1; /* don't know */
+ }
+#endif
}
return port->default_keepalives_idle;
@@ -1349,7 +1359,7 @@ pq_setkeepalivesidle(int idle, Port *port)
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
return STATUS_OK;
-#ifdef TCP_KEEPIDLE
+#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE)
if (idle == port->keepalives_idle)
return STATUS_OK;
@@ -1367,18 +1377,27 @@ pq_setkeepalivesidle(int idle, Port *port)
if (idle == 0)
idle = port->default_keepalives_idle;
+#ifdef TCP_KEEPIDLE
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
(char *) &idle, sizeof(idle)) < 0)
{
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
return STATUS_ERROR;
}
+#else
+ if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
+ (char *) &idle, sizeof(idle)) < 0)
+ {
+ elog(LOG, "setsockopt(TCP_KEEPALIVE) failed: %m");
+ return STATUS_ERROR;
+ }
+#endif
port->keepalives_idle = idle;
#else
if (idle != 0)
{
- elog(LOG, "setsockopt(TCP_KEEPIDLE) not supported");
+ elog(LOG, "setting the keepalive idle time is not supported");
return STATUS_ERROR;
}
#endif
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index ed37bbd..36b3ac7 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1008,6 +1008,20 @@ setKeepalivesIdle(PGconn *conn)
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0;
}
+#else
+#ifdef TCP_KEEPALIVE
+ /* Darwin uses TCP_KEEPALIVE rather than TCP_KEEPIDLE */
+ if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
+ (char *) &idle, sizeof(idle)) < 0)
+ {
+ char sebuf[256];
+
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("setsockopt(TCP_KEEPALIVE) failed: %s\n"),
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ return 0;
+ }
+#endif
#endif
return 1;