aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2003-06-14 17:49:54 +0000
committerBruce Momjian <bruce@momjian.us>2003-06-14 17:49:54 +0000
commita16a0314114f7e6e4414d11f6ff2744496952bda (patch)
tree453187eb6cf695da32e516fbd9c3d1ad6f2fa9ed /src
parent62b532b73668267eb950f1ba8fed4a8ec45f60ae (diff)
downloadpostgresql-a16a0314114f7e6e4414d11f6ff2744496952bda.tar.gz
postgresql-a16a0314114f7e6e4414d11f6ff2744496952bda.zip
Make libpq thread-safe with configure --with-threads option.
Lee Kindness
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-auth.c24
-rw-r--r--src/interfaces/libpq/fe-connect.c39
-rw-r--r--src/interfaces/libpq/fe-lobj.c8
-rw-r--r--src/interfaces/libpq/fe-misc.c14
-rw-r--r--src/interfaces/libpq/fe-secure.c55
-rw-r--r--src/interfaces/libpq/libpq-int.h5
-rw-r--r--src/interfaces/libpq/win32.c21
-rw-r--r--src/interfaces/libpq/win32.h3
8 files changed, 106 insertions, 63 deletions
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index d31ec6ff881..6ec25d400a5 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -10,7 +10,7 @@
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.79 2003/06/08 17:43:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.80 2003/06/14 17:49:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -391,8 +391,10 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
flags = fcntl(sock, F_GETFL);
if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
{
+ char sebuf[256];
+
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
- libpq_gettext("could not set socket to blocking mode: %s\n"), strerror(errno));
+ libpq_gettext("could not set socket to blocking mode: %s\n"), pqStrerror(errno, sebuf, sizeof(sebuf)));
krb5_free_principal(pg_krb5_context, server);
return STATUS_ERROR;
}
@@ -436,9 +438,11 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
if (fcntl(sock, F_SETFL, (long) flags))
{
+ char sebuf[256];
+
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
libpq_gettext("could not restore non-blocking mode on socket: %s\n"),
- strerror(errno));
+ pqStrerror(errno, sebuf, sizeof(sebuf)));
ret = STATUS_ERROR;
}
@@ -495,8 +499,11 @@ pg_local_sendauth(char *PQerrormsg, PGconn *conn)
if (sendmsg(conn->sock, &msg, 0) == -1)
{
+ char sebuf[256];
+
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
- "pg_local_sendauth: sendmsg: %s\n", strerror(errno));
+ "pg_local_sendauth: sendmsg: %s\n",
+ pqStrerror(errno, sebuf, sizeof(sebuf)));
return STATUS_ERROR;
}
return STATUS_OK;
@@ -739,10 +746,13 @@ fe_getauthname(char *PQerrormsg)
if (GetUserName(username, &namesize))
name = username;
#else
- struct passwd *pw = getpwuid(geteuid());
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pw = NULL;
- if (pw)
- name = pw->pw_name;
+ if( pqGetpwuid(geteuid(), &pwdstr,
+ pwdbuf, sizeof(pwdbuf), &pw) == 0 )
+ name = pw->pw_name;
#endif
}
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 74e8ab55722..a5a9cb2336d 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.247 2003/06/12 08:15:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.248 2003/06/14 17:49:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -713,9 +713,11 @@ connectMakeNonblocking(PGconn *conn)
{
if (FCNTL_NONBLOCK(conn->sock) < 0)
{
+ char sebuf[256];
+
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to non-blocking mode: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0;
}
@@ -738,9 +740,11 @@ connectNoDelay(PGconn *conn)
(char *) &on,
sizeof(on)) < 0)
{
+ char sebuf[256];
+
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0;
}
#endif
@@ -759,6 +763,7 @@ connectFailureMessage(PGconn *conn, int errorno)
{
char hostname[NI_MAXHOST];
char service[NI_MAXHOST];
+ char sebuf[256];
getnameinfo((struct sockaddr *)&conn->raddr.addr, conn->raddr.salen,
hostname, sizeof(hostname), service, sizeof(service),
@@ -770,7 +775,7 @@ connectFailureMessage(PGconn *conn, int errorno)
"\tIs the server running locally and accepting\n"
"\tconnections on Unix domain socket \"%s\"?\n"
),
- SOCK_STRERROR(errorno), service);
+ SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), service);
else
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext(
@@ -778,7 +783,7 @@ connectFailureMessage(PGconn *conn, int errorno)
"\tIs the server running on host %s and accepting\n"
"\tTCP/IP connections on port %s?\n"
),
- SOCK_STRERROR(errorno),
+ SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
conn->pghostaddr
? conn->pghostaddr
: (conn->pghost
@@ -1001,6 +1006,7 @@ PostgresPollingStatusType
PQconnectPoll(PGconn *conn)
{
PGresult *res;
+ char sebuf[256];
if (conn == NULL)
return PGRES_POLLING_FAILED;
@@ -1094,7 +1100,7 @@ keep_going: /* We will come back to here until there
}
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not create socket: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
break;
}
@@ -1200,7 +1206,7 @@ retry_connect:
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get socket error status: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
}
else if (optval != 0)
@@ -1237,7 +1243,7 @@ retry_connect:
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get client address from socket: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
}
@@ -1282,7 +1288,7 @@ retry_connect:
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not send SSL negotiation packet: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
}
/* Ok, wait for response */
@@ -1317,7 +1323,7 @@ retry_connect:
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not send startup packet: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
free(startpacket);
goto error_return;
}
@@ -1357,7 +1363,7 @@ retry_ssl_read:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
}
if (nread == 0)
@@ -2037,6 +2043,7 @@ PQrequestCancel(PGconn *conn)
{
int save_errno = SOCK_ERRNO;
int tmpsock = -1;
+ char sebuf[256];
struct
{
uint32 packetlen;
@@ -2115,7 +2122,7 @@ retry4:
return TRUE;
cancel_errReturn:
- strcat(conn->errorMessage.data, SOCK_STRERROR(SOCK_ERRNO));
+ strcat(conn->errorMessage.data, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
strcat(conn->errorMessage.data, "\n");
conn->errorMessage.len = strlen(conn->errorMessage.data);
if (tmpsock >= 0)
@@ -2262,8 +2269,9 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
*val;
int found_keyword;
- key = strtok(line, "=");
- if (key == NULL)
+ key = line;
+ val = strchr(line, '=');
+ if( val == NULL )
{
printfPQExpBuffer(errorMessage,
"ERROR: syntax error in service file '%s', line %d\n",
@@ -2272,6 +2280,7 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
fclose(f);
return 3;
}
+ *val++ = '\0';
/*
* If not already set, set the database name to the
@@ -2287,8 +2296,6 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
}
}
- val = line + strlen(line) + 1;
-
/*
* Set the parameter --- but don't override any
* previous explicit setting.
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index dd2d76867df..bc7b814c612 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.41 2002/06/20 20:29:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.42 2003/06/14 17:49:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -396,9 +396,10 @@ lo_import(PGconn *conn, const char *filename)
fd = open(filename, O_RDONLY | PG_BINARY, 0666);
if (fd < 0)
{ /* error */
+ char sebuf[256];
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not open file \"%s\": %s\n"),
- filename, strerror(errno));
+ filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
return InvalidOid;
}
@@ -479,9 +480,10 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
if (fd < 0)
{ /* error */
+ char sebuf[256];
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not open file \"%s\": %s\n"),
- filename, strerror(errno));
+ filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
(void) lo_close(conn, lobj);
return -1;
}
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index f456365348e..3856145a4ef 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -23,7 +23,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.95 2003/06/12 08:15:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.96 2003/06/14 17:49:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -536,6 +536,7 @@ pqReadData(PGconn *conn)
{
int someread = 0;
int nread;
+ char sebuf[256];
if (conn->sock < 0)
{
@@ -606,7 +607,7 @@ retry3:
#endif
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not receive data from server: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return -1;
}
if (nread > 0)
@@ -686,7 +687,7 @@ retry4:
#endif
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not receive data from server: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return -1;
}
if (nread > 0)
@@ -740,6 +741,7 @@ pqSendSome(PGconn *conn, int len)
while (len > 0)
{
int sent;
+ char sebuf[256];
sent = pqsecure_write(conn, ptr, len);
@@ -787,7 +789,7 @@ pqSendSome(PGconn *conn, int len)
default:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not send data to server: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
/* We don't assume it's a fatal error... */
conn->outCount = 0;
return -1;
@@ -963,9 +965,11 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
if (result < 0)
{
+ char sebuf[256];
+
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("select() failed: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
}
return result;
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index f3f3ad3fb01..1771d8bb7dd 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.23 2003/06/08 17:43:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.24 2003/06/14 17:49:54 momjian Exp $
*
* NOTES
* The client *requires* a valid server certificate. Since
@@ -298,14 +298,19 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
*/
goto rloop;
case SSL_ERROR_SYSCALL:
+ {
+ char sebuf[256];
+
if (n == -1)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
else
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+
break;
+ }
case SSL_ERROR_SSL:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL error: %s\n"), SSLerrmessage());
@@ -360,14 +365,18 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
n = 0;
break;
case SSL_ERROR_SYSCALL:
+ {
+ char sebuf[256];
+
if (n == -1)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
else
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
break;
+ }
case SSL_ERROR_SSL:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL error: %s\n"), SSLerrmessage());
@@ -418,7 +427,6 @@ verify_cb(int ok, X509_STORE_CTX *ctx)
#ifdef NOT_USED
/*
* Verify that common name resolves to peer.
- * This function is not thread-safe due to gethostbyname().
*/
static int
verify_peer(PGconn *conn)
@@ -434,9 +442,10 @@ verify_peer(PGconn *conn)
len = sizeof(addr);
if (getpeername(conn->sock, &addr, &len) == -1)
{
+ char sebuf[256];
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("error querying socket: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return -1;
}
@@ -514,14 +523,16 @@ verify_peer(PGconn *conn)
static DH *
load_dh_file(int keylength)
{
- struct passwd *pwd;
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pwd = NULL;
FILE *fp;
char fnbuf[2048];
DH *dh = NULL;
int codes;
- if ((pwd = getpwuid(getuid())) == NULL)
- return NULL;
+ if( pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0 )
+ return NULL;
/* attempt to open file. It's not an error if it doesn't exist. */
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
@@ -654,15 +665,19 @@ tmp_dh_cb(SSL *s, int is_export, int keylength)
static int
client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
- struct passwd *pwd;
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pwd = NULL;
struct stat buf,
buf2;
char fnbuf[2048];
FILE *fp;
PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
int (*cb) () = NULL; /* how to read user password */
+ char sebuf[256];
+
- if ((pwd = getpwuid(getuid())) == NULL)
+ if( pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0 )
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get user information\n"));
@@ -678,7 +693,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not open certificate (%s): %s\n"),
- fnbuf, strerror(errno));
+ fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
return -1;
}
if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
@@ -714,7 +729,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not open private key file (%s): %s\n"),
- fnbuf, strerror(errno));
+ fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
X509_free(*x509);
return -1;
}
@@ -758,7 +773,9 @@ static int
initialize_SSL(PGconn *conn)
{
struct stat buf;
- struct passwd *pwd;
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pwd = NULL;
char fnbuf[2048];
if (!SSL_context)
@@ -775,7 +792,7 @@ initialize_SSL(PGconn *conn)
}
}
- if ((pwd = getpwuid(getuid())) != NULL)
+ if( pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0 )
{
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
pwd->pw_dir);
@@ -783,10 +800,11 @@ initialize_SSL(PGconn *conn)
{
return 0;
#ifdef NOT_USED
+ char sebuf[256];
/* CLIENT CERTIFICATES NOT REQUIRED bjm 2002-09-26 */
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not read root certificate list (%s): %s\n"),
- fnbuf, strerror(errno));
+ fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
return -1;
#endif
}
@@ -846,16 +864,19 @@ open_client_SSL(PGconn *conn)
return PGRES_POLLING_WRITING;
case SSL_ERROR_SYSCALL:
+ {
+ char sebuf[256];
+
if (r == -1)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO));
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
else
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
close_SSL(conn);
return PGRES_POLLING_FAILED;
-
+ }
case SSL_ERROR_SSL:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL error: %s\n"), SSLerrmessage());
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 47dbbb4af5f..019683ac265 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.73 2003/06/12 07:36:51 momjian Exp $
+ * $Id: libpq-int.h,v 1.74 2003/06/14 17:49:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,6 +26,7 @@
#include <sys/time.h>
#endif
+
#if defined(WIN32) && (!defined(ssize_t))
typedef int ssize_t; /* ssize_t doesn't exist in VC (atleast
* not VC6) */
@@ -448,7 +449,7 @@ __attribute__((format_arg(1)));
#define SOCK_STRERROR winsock_strerror
#else
#define SOCK_ERRNO errno
-#define SOCK_STRERROR strerror
+#define SOCK_STRERROR pqStrerror
#endif
#endif /* LIBPQ_INT_H */
diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c
index 17fe9ca93ec..36c4230e747 100644
--- a/src/interfaces/libpq/win32.c
+++ b/src/interfaces/libpq/win32.c
@@ -271,13 +271,12 @@ struct MessageDLL
*/
const char *
-winsock_strerror(int err)
+winsock_strerror(int err, char *strerrbuf, size_t buflen)
{
- static char buf[512]; /* Not threadsafe */
unsigned long flags;
int offs,
i;
- int success = LookupWSErrorMessage(err, buf);
+ int success = LookupWSErrorMessage(err, strerrbuf);
for (i = 0; !success && i < DLLS_SIZE; i++)
{
@@ -302,20 +301,20 @@ winsock_strerror(int err)
flags,
dlls[i].handle, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buf, sizeof(buf) - 64,
+ strerrbuf, buflen - 64,
0
);
}
if (!success)
- sprintf(buf, "Unknown socket error (0x%08X/%lu)", err, err);
+ sprintf(strerrbuf, "Unknown socket error (0x%08X/%lu)", err, err);
else
{
- buf[sizeof(buf) - 1] = '\0';
- offs = strlen(buf);
- if (offs > sizeof(buf) - 64)
- offs = sizeof(buf) - 64;
- sprintf(buf + offs, " (0x%08X/%lu)", err, err);
+ strerrbuf[buflen - 1] = '\0';
+ offs = strlen(strerrbuf);
+ if (offs > buflen - 64)
+ offs = buflen - 64;
+ sprintf(strerrbuf + offs, " (0x%08X/%lu)", err, err);
}
- return buf;
+ return strerrbuf;
}
diff --git a/src/interfaces/libpq/win32.h b/src/interfaces/libpq/win32.h
index 7f3f5cbd629..468e786dccc 100644
--- a/src/interfaces/libpq/win32.h
+++ b/src/interfaces/libpq/win32.h
@@ -37,7 +37,6 @@
/*
* support for handling Windows Socket errors
*/
-extern const char *winsock_strerror(int eno);
-
+extern const char *winsock_strerror(int err, char *strerrbuf, size_t buflen);
#endif