From a16a0314114f7e6e4414d11f6ff2744496952bda Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Sat, 14 Jun 2003 17:49:54 +0000 Subject: [PATCH] Make libpq thread-safe with configure --with-threads option. Lee Kindness --- configure | 22 +++++++++++-- configure.in | 26 ++++++++++++--- src/interfaces/libpq/fe-auth.c | 24 ++++++++++---- src/interfaces/libpq/fe-connect.c | 39 +++++++++++++--------- src/interfaces/libpq/fe-lobj.c | 8 +++-- src/interfaces/libpq/fe-misc.c | 14 +++++--- src/interfaces/libpq/fe-secure.c | 55 +++++++++++++++++++++---------- src/interfaces/libpq/libpq-int.h | 5 +-- src/interfaces/libpq/win32.c | 21 ++++++------ src/interfaces/libpq/win32.h | 3 +- 10 files changed, 146 insertions(+), 71 deletions(-) diff --git a/configure b/configure index 55530ade970..e7cc4766140 100755 --- a/configure +++ b/configure @@ -3591,6 +3591,10 @@ rm -f conftest* # # Pthreads # +# For each platform, we need to know about any special compile and link +# libraries, and whether the normal C function names are thread-safe. +# +NEED_REENTRANT_FUNC_NAMES=no if test "$with_threads" = yes; then echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 @@ -3902,13 +3906,19 @@ fi case $host_os in netbsd*|bsdi*) # these require no special flags or libraries + NEED_REENTRANT_FUNC_NAMES=no + ;; + freebsd2*|freebsd3*|freebsd4*) + THREAD_CFLAGS="-pthread" + NEED_REENTRANT_FUNC_NAMES=yes ;; - freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;; freebsd*) THREAD_LIBS="-lc_r" + NEED_REENTRANT_FUNC_NAMES=yes ;; linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS" THREAD_LIBS="-lpthread" + NEED_REENTRANT_FUNC_NAMES=yes ;; *) # other operating systems might fail because they have pthread.h but need @@ -12829,8 +12839,14 @@ fi # # Check for re-entrant versions of certain functions # -# Include special flags if required +# Include special flags if threads are enabled _and_ if required for +# threading on this platform. Some platforms have *_r functions but +# their natively named funcs are threadsafe, and should be used instead. +# +# One trick here is that if the don't call AC_CHECK_FUNCS, the +# functions are marked "not found", which is perfect. # +if test "$NEED_REENTRANT_FUNC_NAMES" = yes ; then _CFLAGS="$CFLAGS" _LIB="$LIBS" CFLAGS="$CFLAGS $TREAD_CFLAGS" @@ -12915,7 +12931,7 @@ done CFLAGS="$_CFLAGS" LIB="$_LIBS" - +fi # This test makes sure that run tests work at all. Sometimes a shared diff --git a/configure.in b/configure.in index b8c533d05df..a5b7108db95 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.262 2003/06/14 14:35:42 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.263 2003/06/14 17:49:53 momjian Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -554,18 +554,28 @@ AC_SUBST(ELF_SYS) # # Pthreads # +# For each platform, we need to know about any special compile and link +# libraries, and whether the normal C function names are thread-safe. +# +NEED_REENTRANT_FUNC_NAMES=no if test "$with_threads" = yes; then AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([pthread.h not found, required for --with-threads])]) case $host_os in - netbsd*|bsdi*) + netbsd*|bsdi*) # these require no special flags or libraries + NEED_REENTRANT_FUNC_NAMES=no + ;; + freebsd2*|freebsd3*|freebsd4*) + THREAD_CFLAGS="-pthread" + NEED_REENTRANT_FUNC_NAMES=yes ;; - freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;; freebsd*) THREAD_LIBS="-lc_r" + NEED_REENTRANT_FUNC_NAMES=yes ;; linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS" THREAD_LIBS="-lpthread" + NEED_REENTRANT_FUNC_NAMES=yes ;; *) # other operating systems might fail because they have pthread.h but need @@ -991,8 +1001,14 @@ AC_FUNC_FSEEKO # # Check for re-entrant versions of certain functions # -# Include special flags if required +# Include special flags if threads are enabled _and_ if required for +# threading on this platform. Some platforms have *_r functions but +# their natively named funcs are threadsafe, and should be used instead. +# +# One trick here is that if the don't call AC_CHECK_FUNCS, the +# functions are marked "not found", which is perfect. # +if test "$NEED_REENTRANT_FUNC_NAMES" = yes ; then _CFLAGS="$CFLAGS" _LIB="$LIBS" CFLAGS="$CFLAGS $TREAD_CFLAGS" @@ -1000,7 +1016,7 @@ LIBS="$LIBS $THREAD_LIBS" AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r]) CFLAGS="$_CFLAGS" LIB="$_LIBS" - +fi # This test makes sure that run tests work at all. Sometimes a shared 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 -- GitLab