This patch fixes strerror_r() by checking the return type from
configure.

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

Tom Lane wrote:
> Bruce Momjian <[EMAIL PROTECTED]> writes:
> >> The code we have appears to assume that the result will always be placed
> >> in the user-supplied buffer, which is apparently NOT what the glibc
> >> version does.
> 
> > What does "may, but need not, use the user-supplied buffer" supposed to
> > mean in practical terms.  How do they expect us to use it?
> 
> AFAICS they expect you to use the function's return value.
> 
> The current PG code is really erroneous for *both* strerror_r specs,
> since the SUS-spec version doesn't promise to put anything into the
> buffer if it returns a failure code.  I think you will have to write
> some autoconf code to detect which return type is provided, and do
> the right things with the return value in both cases.
> 
>                       regards, tom lane
> 

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (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.371
diff -c -c -r1.371 configure
*** configure   28 May 2004 20:52:41 -0000      1.371
--- configure   7 Jun 2004 22:21:45 -0000
***************
*** 13759,13764 ****
--- 13759,13817 ----
  
  fi
  
+ echo "$as_me:$LINENO: checking whether strerror_r returns int" >&5
+ echo $ECHO_N "checking whether strerror_r returns int... $ECHO_C" >&6
+ if test "${pgac_func_strerror_r_int+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ #include <string.h>
+ #ifdef F77_DUMMY_MAIN
+ #  ifdef __cplusplus
+      extern "C"
+ #  endif
+    int F77_DUMMY_MAIN() { return 1; }
+ #endif
+ int
+ main ()
+ {
+ int strerror_r(int, char *, size_t);
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+          { ac_try='test -s conftest.$ac_objext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   pgac_func_strerror_r_int=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ pgac_func_strerror_r_int=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: $pgac_func_strerror_r_int" >&5
+ echo "${ECHO_T}$pgac_func_strerror_r_int" >&6
+ if test x"$pgac_func_strerror_r_int" = xyes ; then
+ 
+ cat >>confdefs.h <<\_ACEOF
+ #define STRERROR_R_INT
+ _ACEOF
+ 
+ fi
+ 
  
  else
  # do not use values from template file
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql-server/configure.in,v
retrieving revision 1.360
diff -c -c -r1.360 configure.in
*** configure.in        28 May 2004 20:52:42 -0000      1.360
--- configure.in        7 Jun 2004 22:21:53 -0000
***************
*** 993,998 ****
--- 993,999 ----
  LIBS="$_LIBS"
  
  PGAC_FUNC_GETPWUID_R_5ARG
+ PGAC_FUNC_STRERROR_R_INT
  
  else
  # do not use values from template file
Index: config/c-library.m4
===================================================================
RCS file: /cvsroot/pgsql-server/config/c-library.m4,v
retrieving revision 1.25
diff -c -c -r1.25 c-library.m4
*** config/c-library.m4 20 Mar 2004 15:39:27 -0000      1.25
--- config/c-library.m4 7 Jun 2004 22:21:53 -0000
***************
*** 96,101 ****
--- 96,118 ----
  ])# PGAC_FUNC_GETPWUID_R_5ARG
  
  
+ # PGAC_FUNC_STRERROR_R_INT
+ # ---------------------------
+ # Check if strerror_r() returns an int (SUSv3) rather than a char * (GNU libc)
+ # If so, define STRERROR_R_INT
+ AC_DEFUN([PGAC_FUNC_STRERROR_R_INT],
+ [AC_CACHE_CHECK(whether strerror_r returns int,
+ pgac_func_strerror_r_int,
+ [AC_TRY_COMPILE([#include <string.h>],
+ [int strerror_r(int, char *, size_t);],
+ [pgac_func_strerror_r_int=yes],
+ [pgac_func_strerror_r_int=no])])
+ if test x"$pgac_func_strerror_r_int" = xyes ; then
+   AC_DEFINE(STRERROR_R_INT,, [Define to 1 if strerror_r() returns a int.])
+ fi
+ ])# PGAC_FUNC_STRERROR_R_INT
+ 
+ 
  # PGAC_UNION_SEMUN
  # ----------------
  # Check if `union semun' exists. Define HAVE_UNION_SEMUN if so.
Index: src/include/pg_config.h.in
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/pg_config.h.in,v
retrieving revision 1.76
diff -c -c -r1.76 pg_config.h.in
*** src/include/pg_config.h.in  22 May 2004 00:34:51 -0000      1.76
--- src/include/pg_config.h.in  7 Jun 2004 22:21:56 -0000
***************
*** 607,612 ****
--- 607,615 ----
  /* Define to 1 if you have the ANSI C header files. */
  #undef STDC_HEADERS
  
+ /* Define to 1 if strerror_r() returns a int. */
+ #undef STRERROR_R_INT
+ 
  /* Define to 1 if your <sys/time.h> declares `struct tm'. */
  #undef TM_IN_SYS_TIME
  
Index: src/port/thread.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/thread.c,v
retrieving revision 1.20
diff -c -c -r1.20 thread.c
*** src/port/thread.c   23 Apr 2004 18:15:55 -0000      1.20
--- src/port/thread.c   7 Jun 2004 22:21:56 -0000
***************
*** 70,81 ****
  {
  #if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_STRERROR_R)
        /* reentrant strerror_r is available */
!       /* some early standards had strerror_r returning char * */
!       strerror_r(errnum, strerrbuf, buflen);
!       return strerrbuf;
! 
  #else
- 
        /* no strerror_r() available, just use strerror */
        StrNCpy(strerrbuf, strerror(errnum), buflen);
  
--- 70,86 ----
  {
  #if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_STRERROR_R)
        /* reentrant strerror_r is available */
! #ifdef STRERROR_R_INT
!       /* SUSv3 version */
!       if (strerror_r(errnum, strerrbuf, buflen) == 0)
!               return strerrbuf;
!       else
!               return NULL;
! #else
!       /* GNU libc */
!       return strerror_r(errnum, strerrbuf, buflen);
! #endif
  #else
        /* no strerror_r() available, just use strerror */
        StrNCpy(strerrbuf, strerror(errnum), buflen);
  
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Reply via email to