Skip to content

Commit

Permalink
Use strerror_r() where available, since strerror() isn't always
Browse files Browse the repository at this point in the history
thread-safe.  Example systems where strerror() isn't thread-safe:
Linux+glibc, AIX


git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@62503 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
trawick committed Nov 12, 2001
1 parent f9f960c commit 9caca9e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Changes with APR b1

*) Use strerror_r() where available, since strerror() isn't always
thread-safe. Example systems where strerror() isn't thread-safe:
Linux+glibc, AIX [Jeff Trawick]

*) Fix some file cleanup problems in apr_proc_create() which could
result in the pipes for stdin/stdout/stderr being closed
immediately. [Jeff Trawick]
Expand Down
1 change: 1 addition & 0 deletions acconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#undef READDIR_IS_THREAD_SAFE
#undef GETHOSTBYNAME_IS_THREAD_SAFE
#undef GETHOSTBYADDR_IS_THREAD_SAFE
#undef STRERROR_R_RC_INT

#undef NEED_RLIM_T
#undef USEBCOPY
Expand Down
36 changes: 35 additions & 1 deletion build/apr_common.m4
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,41 @@ fi
rm -f conftest*
])dnl


dnl
dnl APR_CHECK_STRERROR_R_RC
dnl
dnl Decide which style of retcode is used by this system's
dnl strerror_r(). It either returns int (0 for success, -1
dnl for failure), or it returns a pointer to the error
dnl string.
dnl
dnl
AC_DEFUN(APR_CHECK_STRERROR_R_RC,[
AC_MSG_CHECKING(for type of return code from strerror_r)
AC_TRY_RUN([
#include <errno.h>
#include <stdio.h>
main()
{
char buf[1024];
if (strerror_r(ERANGE, buf, sizeof buf) < 1) {
exit(0);
}
else {
exit(1);
}
}], [
ac_cv_strerror_r_rc_int=yes ], [
ac_cv_strerror_r_rc_int=no ], [
ac_cv_strerror_r_rc_int=no ] )
if test "x$ac_cv_strerror_r_rc_int" = xyes; then
AC_DEFINE(STRERROR_R_RC_INT)
msg="int"
else
msg="pointer"
fi
AC_MSG_RESULT([$msg])
] )
dnl
dnl APR_CHECK_ICONV_INBUF
dnl
Expand Down
4 changes: 4 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ APR_CHECK_INET_NETWORK
AC_SUBST(apr_inaddr_none)
AC_CHECK_FUNC(_getch)
AC_CHECK_FUNCS(gmtime_r localtime_r)
AC_CHECK_FUNCS(strerror_r, [ strerror_r="1" ], [ strerror_r="0" ])
if test "$strerror_r" = "1"; then
APR_CHECK_STRERROR_R_RC
fi
AC_CHECK_FUNCS(iconv, [ iconv="1" ], [ iconv="0" ])
if test "$iconv" = "1"; then
APR_CHECK_ICONV_INBUF
Expand Down
42 changes: 41 additions & 1 deletion misc/unix/errorcodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,51 @@ static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err)
}
#endif

#if defined(HAVE_STRERROR_R) && defined(STRERROR_R_RC_INT)
/* AIX and Tru64 style */
static char *native_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize)
{
if (strerror_r(statcode, buf, bufsize) < 0) {
return stuffbuffer(buf, bufsize,
"APR does not understand this error code");
}
else {
return buf;
}
}
#elif defined(HAVE_STRERROR_R)
/* glibc style */
static char *native_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize)
{
const char *msg;

buf[0] = '\0';
msg = strerror_r(statcode, buf, bufsize);
if (buf[0] == '\0') { /* libc didn't use our buffer */
return stuffbuffer(buf, bufsize, msg);
}
else {
return buf;
}
}
#else
/* plain old strerror();
* thread-safe on some platforms (e.g., Solaris, OS/390)
*/
static char *native_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize)
{
return stuffbuffer(buf, bufsize, strerror(statcode));
}
#endif

APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
apr_size_t bufsize)
{
if (statcode < APR_OS_START_ERROR) {
return stuffbuffer(buf, bufsize, strerror(statcode));
return native_strerror(statcode, buf, bufsize);
}
else if (statcode < APR_OS_START_USEERR) {
return stuffbuffer(buf, bufsize, apr_error_string(statcode));
Expand Down

0 comments on commit 9caca9e

Please sign in to comment.