Re: [HACKERS] PostgreSQL libraries - PThread Support, but - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: [HACKERS] PostgreSQL libraries - PThread Support, but
Date
Msg-id 200306141722.h5EHMiZ05057@candle.pha.pa.us
Whole thread Raw
In response to Re: [HACKERS] PostgreSQL libraries - PThread Support, but  (Lee Kindness <lkindness@csl.co.uk>)
List pgsql-patches
Here is the final patch for libpq threading.  It adds the bulk of your
patch, plus some cleanups on calling reentrant functions.

We now have these per-platform configure settings:

    linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
        THREAD_LIBS="-lpthread"
        NEED_REENTRANT_FUNC_NAMES=yes

They control compile flags, link libraries, and the use of reentrant
function names.

---------------------------------------------------------------------------

Lee Kindness wrote:
Content-Description: message body text

> Patch attached, along with new libpq-reentrant.c and libpq-reentrant.h
> files for src/interfaces/libpq.
>
> Also at http://services.csl.co.uk/postgresql/
>
> Thanks, Lee.
>
> Lee Kindness writes:
>  > Ok guys, I propose that the new libpq diff and 2 source files which
>  > i'll soon send to pgsql-patches is applied to the source. This diff is
>  > a cleaned up version of the previous version with the wrapper
>  > functions moved out into their own file and more comments added. Also
>  > the use of crypt_r() has been removed (not worth the effort), the
>  > cpp defines have been renamed to be consistent with each other and
>  > Tom's concerns with loose #defines has been partly addressed.
>  >
>  > This diff does not include any configure changes. I plan to tackle
>  > this separately ASAP, and hopefully produce something more acceptable.
>  >
>  > I will add checks for appropriate compiler thread flags (for compiling
>  > libpq, and alow the removal of #defines in libpq-reentrant.h), and
>  > link flags & libs (for a planned threaded libpq test program and
>  > renentrant ecpg library). If a thread environment is found then check
>  > for the reentrant functions will be done.
>  >
>  > Looking at various open source projects configure.in files there seems
>  > to be little commonality in the thread test macros (telp gratefully
>  > accepted!), I currently think that something like the approach used by
>  > glib is most suitable (switch on OS).
>  >
>  > All sound acceptable?
>  >
>  > Thanks, Lee.
>  >
>  > Peter Eisentraut writes:
>  >  > Lee Kindness writes:
>  >  >
>  >  > > Patches attached to make libpq thread-safe, now uses strerror_r(),
>  >  > > gethostbyname_r(), getpwuid_r() and crypt_r() where available. Where
>  >  > > strtok() was previously used strchr() is now used.
>  >  >
>  >  > AC_TRY_RUN tests are prohibited.  Also, try to factor out some of these
>  >  > huge tests into separate macros and put them into config/c-library.m4.
>  >  > And it would be nice if there was some documentation about what was
>  >  > checked for.  If you just want to check whether gethostbyname_r() has 5 or
>  >  > 6 arguments you can do that in half the space.
>

[ Attachment, skipping... ]

[ Attachment, skipping... ]

[ Attachment, skipping... ]

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: configure
===================================================================
RCS file: /cvsroot/pgsql-server/configure,v
retrieving revision 1.271
diff -c -c -r1.271 configure
*** configure    14 Jun 2003 14:35:42 -0000    1.271
--- configure    14 Jun 2003 17:12:15 -0000
***************
*** 3591,3596 ****
--- 3591,3600 ----
  #
  # 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,3914 ****
  case $host_os in
          netbsd*|bsdi*)
              # these require no special flags or libraries
              ;;
-         freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
          freebsd*)
              THREAD_LIBS="-lc_r"
              ;;
          linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
              THREAD_LIBS="-lpthread"
              ;;
          *)
              # other operating systems might fail because they have pthread.h but need
--- 3906,3924 ----
  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
              ;;
          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,12836 ****
  #
  # Check for re-entrant versions of certain functions
  #
! # Include special flags if required
  #
  _CFLAGS="$CFLAGS"
  _LIB="$LIBS"
  CFLAGS="$CFLAGS $TREAD_CFLAGS"
--- 12839,12852 ----
  #
  # Check for re-entrant versions of certain functions
  #
! # 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,12921 ****

  CFLAGS="$_CFLAGS"
  LIB="$_LIBS"
!


  # This test makes sure that run tests work at all.  Sometimes a shared
--- 12931,12937 ----

  CFLAGS="$_CFLAGS"
  LIB="$_LIBS"
! fi


  # This test makes sure that run tests work at all.  Sometimes a shared
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql-server/configure.in,v
retrieving revision 1.262
diff -c -c -r1.262 configure.in
*** configure.in    14 Jun 2003 14:35:42 -0000    1.262
--- configure.in    14 Jun 2003 17:12:16 -0000
***************
*** 554,571 ****
  #
  # Pthreads
  #
  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*)
              # these require no special flags or libraries
              ;;
-         freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
          freebsd*)
              THREAD_LIBS="-lc_r"
              ;;
          linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
              THREAD_LIBS="-lpthread"
              ;;
          *)
              # other operating systems might fail because they have pthread.h but need
--- 554,581 ----
  #
  # 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*)
              # these require no special flags or libraries
+             NEED_REENTRANT_FUNC_NAMES=no
+             ;;
+         freebsd2*|freebsd3*|freebsd4*)
+             THREAD_CFLAGS="-pthread"
+             NEED_REENTRANT_FUNC_NAMES=yes
              ;;
          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,998 ****
  #
  # Check for re-entrant versions of certain functions
  #
! # Include special flags if required
  #
  _CFLAGS="$CFLAGS"
  _LIB="$LIBS"
  CFLAGS="$CFLAGS $TREAD_CFLAGS"
--- 1001,1014 ----
  #
  # Check for re-entrant versions of certain functions
  #
! # 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,1006 ****
  AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r])
  CFLAGS="$_CFLAGS"
  LIB="$_LIBS"
!


  # This test makes sure that run tests work at all.  Sometimes a shared
--- 1016,1022 ----
  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
Index: src/interfaces/libpq/fe-auth.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-auth.c,v
retrieving revision 1.79
diff -c -c -r1.79 fe-auth.c
*** src/interfaces/libpq/fe-auth.c    8 Jun 2003 17:43:00 -0000    1.79
--- src/interfaces/libpq/fe-auth.c    14 Jun 2003 17:12:20 -0000
***************
*** 391,398 ****
      flags = fcntl(sock, F_GETFL);
      if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
      {
          snprintf(PQerrormsg, PQERRORMSG_LENGTH,
!                  libpq_gettext("could not set socket to blocking mode: %s\n"), strerror(errno));
          krb5_free_principal(pg_krb5_context, server);
          return STATUS_ERROR;
      }
--- 391,400 ----
      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"), pqStrerror(errno, sebuf,
sizeof(sebuf)));
          krb5_free_principal(pg_krb5_context, server);
          return STATUS_ERROR;
      }
***************
*** 436,444 ****

      if (fcntl(sock, F_SETFL, (long) flags))
      {
          snprintf(PQerrormsg, PQERRORMSG_LENGTH,
                   libpq_gettext("could not restore non-blocking mode on socket: %s\n"),
!                  strerror(errno));
          ret = STATUS_ERROR;
      }

--- 438,448 ----

      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"),
!                  pqStrerror(errno, sebuf, sizeof(sebuf)));
          ret = STATUS_ERROR;
      }

***************
*** 495,502 ****

      if (sendmsg(conn->sock, &msg, 0) == -1)
      {
          snprintf(PQerrormsg, PQERRORMSG_LENGTH,
!                  "pg_local_sendauth: sendmsg: %s\n", strerror(errno));
          return STATUS_ERROR;
      }
      return STATUS_OK;
--- 499,509 ----

      if (sendmsg(conn->sock, &msg, 0) == -1)
      {
+         char sebuf[256];
+
          snprintf(PQerrormsg, PQERRORMSG_LENGTH,
!              "pg_local_sendauth: sendmsg: %s\n",
!              pqStrerror(errno, sebuf, sizeof(sebuf)));
          return STATUS_ERROR;
      }
      return STATUS_OK;
***************
*** 739,748 ****
          if (GetUserName(username, &namesize))
              name = username;
  #else
!         struct passwd *pw = getpwuid(geteuid());
!
!         if (pw)
!             name = pw->pw_name;
  #endif
      }

--- 746,758 ----
          if (GetUserName(username, &namesize))
              name = username;
  #else
!         char pwdbuf[BUFSIZ];
!         struct passwd pwdstr;
!         struct passwd *pw = NULL;
!
!         if( pqGetpwuid(geteuid(), &pwdstr,
!                    pwdbuf, sizeof(pwdbuf), &pw) == 0 )
!           name = pw->pw_name;
  #endif
      }

Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.247
diff -c -c -r1.247 fe-connect.c
*** src/interfaces/libpq/fe-connect.c    12 Jun 2003 08:15:29 -0000    1.247
--- src/interfaces/libpq/fe-connect.c    14 Jun 2003 17:12:23 -0000
***************
*** 713,721 ****
  {
      if (FCNTL_NONBLOCK(conn->sock) < 0)
      {
          printfPQExpBuffer(&conn->errorMessage,
          libpq_gettext("could not set socket to non-blocking mode: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
          return 0;
      }

--- 713,723 ----
  {
      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, sebuf, sizeof(sebuf)));
          return 0;
      }

***************
*** 738,746 ****
                     (char *) &on,
                     sizeof(on)) < 0)
      {
          printfPQExpBuffer(&conn->errorMessage,
          libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
          return 0;
      }
  #endif
--- 740,750 ----
                     (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, sebuf, sizeof(sebuf)));
          return 0;
      }
  #endif
***************
*** 759,764 ****
--- 763,769 ----
  {
      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,776 ****
                          "\tIs the server running locally and accepting\n"
                            "\tconnections on Unix domain socket \"%s\"?\n"
                                          ),
!             SOCK_STRERROR(errorno), service);
      else
          printfPQExpBuffer(&conn->errorMessage,
                            libpq_gettext(
--- 775,781 ----
                          "\tIs the server running locally and accepting\n"
                            "\tconnections on Unix domain socket \"%s\"?\n"
                                          ),
!             SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), service);
      else
          printfPQExpBuffer(&conn->errorMessage,
                            libpq_gettext(
***************
*** 778,784 ****
                       "\tIs the server running on host %s and accepting\n"
                                       "\tTCP/IP connections on port %s?\n"
                                          ),
!                           SOCK_STRERROR(errorno),
                            conn->pghostaddr
                            ? conn->pghostaddr
                            : (conn->pghost
--- 783,789 ----
                       "\tIs the server running on host %s and accepting\n"
                                       "\tTCP/IP connections on port %s?\n"
                                          ),
!                           SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
                            conn->pghostaddr
                            ? conn->pghostaddr
                            : (conn->pghost
***************
*** 1001,1006 ****
--- 1006,1012 ----
  PQconnectPoll(PGconn *conn)
  {
      PGresult   *res;
+     char        sebuf[256];

      if (conn == NULL)
          return PGRES_POLLING_FAILED;
***************
*** 1094,1100 ****
                          }
                          printfPQExpBuffer(&conn->errorMessage,
                                libpq_gettext("could not create socket: %s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO));
                          break;
                      }

--- 1100,1106 ----
                          }
                          printfPQExpBuffer(&conn->errorMessage,
                                libpq_gettext("could not create socket: %s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                          break;
                      }

***************
*** 1200,1206 ****
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                                        libpq_gettext("could not get socket error status: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO));
                      goto error_return;
                  }
                  else if (optval != 0)
--- 1206,1212 ----
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                                        libpq_gettext("could not get socket error status: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                      goto error_return;
                  }
                  else if (optval != 0)
***************
*** 1237,1243 ****
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("could not get client address from socket: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO));
                      goto error_return;
                  }

--- 1243,1249 ----
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("could not get client address from socket: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                      goto error_return;
                  }

***************
*** 1282,1288 ****
                      {
                          printfPQExpBuffer(&conn->errorMessage,
                                            libpq_gettext("could not send SSL negotiation packet: %s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO));
                          goto error_return;
                      }
                      /* Ok, wait for response */
--- 1288,1294 ----
                      {
                          printfPQExpBuffer(&conn->errorMessage,
                                            libpq_gettext("could not send SSL negotiation packet: %s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                          goto error_return;
                      }
                      /* Ok, wait for response */
***************
*** 1317,1323 ****
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                      libpq_gettext("could not send startup packet: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO));
                      free(startpacket);
                      goto error_return;
                  }
--- 1323,1329 ----
                  {
                      printfPQExpBuffer(&conn->errorMessage,
                      libpq_gettext("could not send startup packet: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                      free(startpacket);
                      goto error_return;
                  }
***************
*** 1357,1363 ****

                          printfPQExpBuffer(&conn->errorMessage,
                                            libpq_gettext("could not receive server response to SSL negotiation packet:
%s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO));
                          goto error_return;
                      }
                      if (nread == 0)
--- 1363,1369 ----

                          printfPQExpBuffer(&conn->errorMessage,
                                            libpq_gettext("could not receive server response to SSL negotiation packet:
%s\n"),
!                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                          goto error_return;
                      }
                      if (nread == 0)
***************
*** 2037,2042 ****
--- 2043,2049 ----
  {
      int            save_errno = SOCK_ERRNO;
      int            tmpsock = -1;
+     char        sebuf[256];
      struct
      {
          uint32        packetlen;
***************
*** 2115,2121 ****
      return TRUE;

  cancel_errReturn:
!     strcat(conn->errorMessage.data, SOCK_STRERROR(SOCK_ERRNO));
      strcat(conn->errorMessage.data, "\n");
      conn->errorMessage.len = strlen(conn->errorMessage.data);
      if (tmpsock >= 0)
--- 2122,2128 ----
      return TRUE;

  cancel_errReturn:
!     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,2269 ****
                                 *val;
                      int            found_keyword;

!                     key = strtok(line, "=");
!                     if (key == NULL)
                      {
                          printfPQExpBuffer(errorMessage,
                                            "ERROR: syntax error in service file '%s', line %d\n",
--- 2269,2277 ----
                                 *val;
                      int            found_keyword;

!                     key = line;
!                     val = strchr(line, '=');
!                     if( val == NULL )
                      {
                          printfPQExpBuffer(errorMessage,
                                            "ERROR: syntax error in service file '%s', line %d\n",
***************
*** 2272,2277 ****
--- 2280,2286 ----
                          fclose(f);
                          return 3;
                      }
+                     *val++ = '\0';

                      /*
                       *    If not already set, set the database name to the
***************
*** 2286,2293 ****
                              break;
                          }
                      }
-
-                     val = line + strlen(line) + 1;

                      /*
                       * Set the parameter --- but don't override any
--- 2295,2300 ----
Index: src/interfaces/libpq/fe-lobj.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-lobj.c,v
retrieving revision 1.41
diff -c -c -r1.41 fe-lobj.c
*** src/interfaces/libpq/fe-lobj.c    20 Jun 2002 20:29:54 -0000    1.41
--- src/interfaces/libpq/fe-lobj.c    14 Jun 2003 17:12:23 -0000
***************
*** 396,404 ****
      fd = open(filename, O_RDONLY | PG_BINARY, 0666);
      if (fd < 0)
      {                            /* error */
          printfPQExpBuffer(&conn->errorMessage,
                         libpq_gettext("could not open file \"%s\": %s\n"),
!                           filename, strerror(errno));
          return InvalidOid;
      }

--- 396,405 ----
      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, pqStrerror(errno, sebuf, sizeof(sebuf)));
          return InvalidOid;
      }

***************
*** 479,487 ****
      fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
      if (fd < 0)
      {                            /* error */
          printfPQExpBuffer(&conn->errorMessage,
                         libpq_gettext("could not open file \"%s\": %s\n"),
!                           filename, strerror(errno));
          (void) lo_close(conn, lobj);
          return -1;
      }
--- 480,489 ----
      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, pqStrerror(errno, sebuf, sizeof(sebuf)));
          (void) lo_close(conn, lobj);
          return -1;
      }
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.95
diff -c -c -r1.95 fe-misc.c
*** src/interfaces/libpq/fe-misc.c    12 Jun 2003 08:15:29 -0000    1.95
--- src/interfaces/libpq/fe-misc.c    14 Jun 2003 17:12:24 -0000
***************
*** 536,541 ****
--- 536,542 ----
  {
      int            someread = 0;
      int            nread;
+     char sebuf[256];

      if (conn->sock < 0)
      {
***************
*** 606,612 ****
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("could not receive data from server: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
          return -1;
      }
      if (nread > 0)
--- 607,613 ----
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("could not receive data from server: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
          return -1;
      }
      if (nread > 0)
***************
*** 686,692 ****
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("could not receive data from server: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
          return -1;
      }
      if (nread > 0)
--- 687,693 ----
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("could not receive data from server: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
          return -1;
      }
      if (nread > 0)
***************
*** 740,745 ****
--- 741,747 ----
      while (len > 0)
      {
          int            sent;
+         char sebuf[256];

          sent = pqsecure_write(conn, ptr, len);

***************
*** 787,793 ****
                  default:
                      printfPQExpBuffer(&conn->errorMessage,
                      libpq_gettext("could not send data to server: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO));
                      /* We don't assume it's a fatal error... */
                      conn->outCount = 0;
                      return -1;
--- 789,795 ----
                  default:
                      printfPQExpBuffer(&conn->errorMessage,
                      libpq_gettext("could not send data to server: %s\n"),
!                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                      /* We don't assume it's a fatal error... */
                      conn->outCount = 0;
                      return -1;
***************
*** 963,971 ****

      if (result < 0)
      {
          printfPQExpBuffer(&conn->errorMessage,
                            libpq_gettext("select() failed: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
      }

      return result;
--- 965,975 ----

      if (result < 0)
      {
+         char sebuf[256];
+
          printfPQExpBuffer(&conn->errorMessage,
                            libpq_gettext("select() failed: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
      }

      return result;
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.23
diff -c -c -r1.23 fe-secure.c
*** src/interfaces/libpq/fe-secure.c    8 Jun 2003 17:43:00 -0000    1.23
--- src/interfaces/libpq/fe-secure.c    14 Jun 2003 17:12:26 -0000
***************
*** 298,311 ****
                   */
                  goto rloop;
              case SSL_ERROR_SYSCALL:
                  if (n == -1)
                      printfPQExpBuffer(&conn->errorMessage,
                                  libpq_gettext("SSL SYSCALL error: %s\n"),
!                                   SOCK_STRERROR(SOCK_ERRNO));
                  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());
--- 298,316 ----
                   */
                  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, 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,373 ****
                  n = 0;
                  break;
              case SSL_ERROR_SYSCALL:
                  if (n == -1)
                      printfPQExpBuffer(&conn->errorMessage,
                                  libpq_gettext("SSL SYSCALL error: %s\n"),
!                                   SOCK_STRERROR(SOCK_ERRNO));
                  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());
--- 365,382 ----
                  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, 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());
***************
*** 434,442 ****
      len = sizeof(addr);
      if (getpeername(conn->sock, &addr, &len) == -1)
      {
          printfPQExpBuffer(&conn->errorMessage,
                            libpq_gettext("error querying socket: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO));
          return -1;
      }

--- 443,452 ----
      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, sebuf, sizeof(sebuf)));
          return -1;
      }

***************
*** 514,527 ****
  static DH  *
  load_dh_file(int keylength)
  {
!     struct passwd *pwd;
      FILE       *fp;
      char        fnbuf[2048];
      DH           *dh = NULL;
      int            codes;

!     if ((pwd = getpwuid(getuid())) == NULL)
!         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",
--- 524,539 ----
  static DH  *
  load_dh_file(int keylength)
  {
!     char pwdbuf[BUFSIZ];
!     struct passwd pwdstr;
!     struct passwd *pwd = NULL;
      FILE       *fp;
      char        fnbuf[2048];
      DH           *dh = NULL;
      int            codes;

!     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,668 ****
  static int
  client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
  {
!     struct passwd *pwd;
      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 */

!     if ((pwd = getpwuid(getuid())) == NULL)
      {
          printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("could not get user information\n"));
--- 666,684 ----
  static int
  client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
  {
!     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( pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0 )
      {
          printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("could not get user information\n"));
***************
*** 678,684 ****
      {
          printfPQExpBuffer(&conn->errorMessage,
                    libpq_gettext("could not open certificate (%s): %s\n"),
!                           fnbuf, strerror(errno));
          return -1;
      }
      if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
--- 694,700 ----
      {
          printfPQExpBuffer(&conn->errorMessage,
                    libpq_gettext("could not open certificate (%s): %s\n"),
!                           fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
          return -1;
      }
      if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
***************
*** 714,720 ****
      {
          printfPQExpBuffer(&conn->errorMessage,
               libpq_gettext("could not open private key file (%s): %s\n"),
!                           fnbuf, strerror(errno));
          X509_free(*x509);
          return -1;
      }
--- 730,736 ----
      {
          printfPQExpBuffer(&conn->errorMessage,
               libpq_gettext("could not open private key file (%s): %s\n"),
!                           fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
          X509_free(*x509);
          return -1;
      }
***************
*** 758,764 ****
  initialize_SSL(PGconn *conn)
  {
      struct stat buf;
!     struct passwd *pwd;
      char        fnbuf[2048];

      if (!SSL_context)
--- 774,782 ----
  initialize_SSL(PGconn *conn)
  {
      struct stat buf;
!     char pwdbuf[BUFSIZ];
!     struct passwd pwdstr;
!     struct passwd *pwd = NULL;
      char        fnbuf[2048];

      if (!SSL_context)
***************
*** 775,781 ****
          }
      }

!     if ((pwd = getpwuid(getuid())) != NULL)
      {
          snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
                   pwd->pw_dir);
--- 793,799 ----
          }
      }

!     if( pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0 )
      {
          snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
                   pwd->pw_dir);
***************
*** 783,792 ****
          {
              return 0;
  #ifdef NOT_USED
              /* 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));
              return -1;
  #endif
          }
--- 801,811 ----
          {
              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, pqStrerror(errno, sebuf, sizeof(sebuf)));
              return -1;
  #endif
          }
***************
*** 846,861 ****
                  return PGRES_POLLING_WRITING;

              case SSL_ERROR_SYSCALL:
                  if (r == -1)
                      printfPQExpBuffer(&conn->errorMessage,
                                  libpq_gettext("SSL SYSCALL error: %s\n"),
!                                   SOCK_STRERROR(SOCK_ERRNO));
                  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());
--- 865,883 ----
                  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, 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());
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.73
diff -c -c -r1.73 libpq-int.h
*** src/interfaces/libpq/libpq-int.h    12 Jun 2003 07:36:51 -0000    1.73
--- src/interfaces/libpq/libpq-int.h    14 Jun 2003 17:12:27 -0000
***************
*** 26,31 ****
--- 26,32 ----
  #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,454 ****
  #define SOCK_STRERROR winsock_strerror
  #else
  #define SOCK_ERRNO errno
! #define SOCK_STRERROR strerror
  #endif

  #endif   /* LIBPQ_INT_H */
--- 449,455 ----
  #define SOCK_STRERROR winsock_strerror
  #else
  #define SOCK_ERRNO errno
! #define SOCK_STRERROR pqStrerror
  #endif

  #endif   /* LIBPQ_INT_H */
Index: src/interfaces/libpq/win32.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/win32.c,v
retrieving revision 1.4
diff -c -c -r1.4 win32.c
*** src/interfaces/libpq/win32.c    4 Sep 2002 20:31:47 -0000    1.4
--- src/interfaces/libpq/win32.c    14 Jun 2003 17:12:27 -0000
***************
*** 271,283 ****
   */

  const char *
! winsock_strerror(int err)
  {
-     static char buf[512];        /* Not threadsafe */
      unsigned long flags;
      int            offs,
                  i;
!     int            success = LookupWSErrorMessage(err, buf);

      for (i = 0; !success && i < DLLS_SIZE; i++)
      {
--- 271,282 ----
   */

  const char *
! winsock_strerror(int err, char *strerrbuf, size_t buflen)
  {
      unsigned long flags;
      int            offs,
                  i;
!     int            success = LookupWSErrorMessage(err, strerrbuf);

      for (i = 0; !success && i < DLLS_SIZE; i++)
      {
***************
*** 302,321 ****
                                       flags,
                                       dlls[i].handle, err,
                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
!                                      buf, sizeof(buf) - 64,
                                       0
              );
      }

      if (!success)
!         sprintf(buf, "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);
      }
!     return buf;
  }
--- 301,320 ----
                                       flags,
                                       dlls[i].handle, err,
                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
!                                      strerrbuf, buflen - 64,
                                       0
              );
      }

      if (!success)
!         sprintf(strerrbuf, "Unknown socket error (0x%08X/%lu)", err, err);
      else
      {
!         strerrbuf[buflen - 1] = '\0';
!         offs = strlen(strerrbuf);
!         if (offs > buflen - 64)
!             offs = buflen - 64;
!         sprintf(strerrbuf + offs, " (0x%08X/%lu)", err, err);
      }
!     return strerrbuf;
  }
Index: src/interfaces/libpq/win32.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/win32.h,v
retrieving revision 1.22
diff -c -c -r1.22 win32.h
*** src/interfaces/libpq/win32.h    9 May 2003 16:59:43 -0000    1.22
--- src/interfaces/libpq/win32.h    14 Jun 2003 17:12:27 -0000
***************
*** 37,43 ****
  /*
   * support for handling Windows Socket errors
   */
! extern const char *winsock_strerror(int eno);
!

  #endif
--- 37,42 ----
  /*
   * support for handling Windows Socket errors
   */
! extern const char *winsock_strerror(int err, char *strerrbuf, size_t buflen);

  #endif

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Add thread.c and linkage
Next
From: Tom Lane
Date:
Subject: Re: Add thread.c and linkage