Skip to content

Commit

Permalink
Handle both XSI and GNU versions of strerror_r
Browse files Browse the repository at this point in the history
Signed-off-by: Zoltan Fridrich <[email protected]>
  • Loading branch information
ZoltanFridrich committed Jun 27, 2023
1 parent 5b7977a commit ccbe143
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 43 deletions.
61 changes: 30 additions & 31 deletions common/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -910,37 +910,6 @@ secure_getenv (const char *name)
return getenv (name);
}

#ifndef HAVE_STRERROR_R

int
strerror_r (int errnum,
char *buf,
size_t buflen)
{
#ifdef OS_WIN32
#if _WIN32_WINNT < 0x502 /* WinXP or older */
int n = sys_nerr;
const char *p;
if (errnum < 0 || errnum >= n)
p = sys_errlist[n];
else
p = sys_errlist[errnum];
if (buf == NULL || buflen == 0)
return EINVAL;
strncpy(buf, p, buflen);
buf[buflen-1] = 0;
return 0;
#else /* Server 2003 or newer */
return strerror_s (buf, buflen, errnum);
#endif /*_WIN32_WINNT*/

#else
#error no strerror_r implementation
#endif
}

#endif /* HAVE_STRERROR_R */

#ifndef HAVE_ISATTY

int
Expand Down Expand Up @@ -1037,6 +1006,36 @@ fdwalk (int (* cb) (void *data, int fd),

#endif /* OS_UNIX */

void
p11_strerror_r (int errnum,
char *buf,
size_t buflen)
{
#if defined(HAVE_XSI_STRERROR_R)
strerror_r (errnum, buf, buflen);
#elif defined(HAVE_GNU_STRERROR_R)
char *str = strerror_r (errnum, buf, buflen);
strncpy (buf, str, buflen);
#elif defined(OS_WIN32)
#if _WIN32_WINNT < 0x502 /* WinXP or older */
int n = sys_nerr;
const char *p;
if (errnum < 0 || errnum >= n)
p = sys_errlist[n];
else
p = sys_errlist[errnum];
if (buf == NULL || buflen == 0)
return;
strncpy(buf, p, buflen);
buf[buflen - 1] = '\0';
#else /* Server 2003 or newer */
strerror_s (buf, buflen, errnum);
#endif /* _WIN32_WINNT */
#else
#error no strerror_r implementation
#endif
}

int
p11_ascii_tolower (int c)
{
Expand Down
12 changes: 4 additions & 8 deletions common/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,6 @@ unsigned long getauxval (unsigned long type);

char * secure_getenv (const char *name);

#ifndef HAVE_STRERROR_R

int strerror_r (int errnum,
char *buf,
size_t buflen);

#endif /* HAVE_STRERROR_R */

#ifndef HAVE_FDWALK

int fdwalk (int (* cb) (void *data, int fd),
Expand Down Expand Up @@ -402,6 +394,10 @@ int isatty (int fd);

#endif

void p11_strerror_r (int errnum,
char *buf,
size_t buflen);

int p11_ascii_tolower (int c);
int p11_ascii_toupper (int c);

Expand Down
2 changes: 1 addition & 1 deletion common/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ p11_debug_message_err (int flag,
if (p11_message_locale != (locale_t) 0)
strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr));
#else
strerror_r (errnum, strerr, sizeof (strerr));
p11_strerror_r (errnum, strerr, sizeof (strerr));
#endif
strerr[P11_DEBUG_MESSAGE_MAX - 1] = 0;
fprintf (stderr, ": %s\n", strerr);
Expand Down
2 changes: 1 addition & 1 deletion common/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ p11_message_err (int errnum,
if (p11_message_locale != (locale_t) 0)
strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr));
#else
strerror_r (errnum, strerr, sizeof (strerr));
p11_strerror_r (errnum, strerr, sizeof (strerr));
#endif
strerr[P11_MESSAGE_MAX - 1] = 0;

Expand Down
20 changes: 19 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ if test "$os_unix" = "yes"; then
AC_CHECK_MEMBERS([struct dirent.d_type],,,[#include <dirent.h>])
AC_CHECK_FUNCS([getprogname getexecname basename mkstemp mkdtemp])
AC_CHECK_FUNCS([getauxval getresuid secure_getenv])
AC_CHECK_FUNCS([strnstr memdup strndup strerror_r])
AC_CHECK_FUNCS([strnstr memdup strndup])
AC_CHECK_FUNCS([reallocarray])
AC_CHECK_DECLS([reallocarray], [], [], [[#include <stdlib.h>]])
AC_CHECK_FUNCS([fdwalk])
Expand All @@ -144,6 +144,24 @@ if test "$os_unix" = "yes"; then
AC_CHECK_FUNCS([issetugid])
AC_CHECK_FUNCS([isatty])

AC_CHECK_FUNC(
[strerror_r],
[AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <errno.h>
#include <string.h>
int main (void)
{
char buf[32];
return strerror_r (EINVAL, buf, 32);
}
]])],
[AC_DEFINE([HAVE_XSI_STRERROR_R], 1, [Whether XSI-compliant strerror_r() is available])],
[AC_DEFINE([HAVE_GNU_STRERROR_R], 1, [Whether GNU-specific strerror_r() is available])],
[])],
[])

AC_CACHE_CHECK([for thread-local storage class],
[ac_cv_tls_keyword],
[ac_cv_tls_keyword=
Expand Down
20 changes: 19 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ functions = [
'reallocarray',
'secure_getenv',
'setenv',
'strerror_r',
'strnstr',
'vasprintf'
]
Expand All @@ -300,6 +299,25 @@ foreach f : functions
endif
endforeach

if cc.has_function('strerror_r', prefix: '#include <string.h>')
strerror_r_code = '''
#include <errno.h>
#include <string.h>
int main (void)
{
char buf[32];
return strerror_r (EINVAL, buf, 32);
}
'''
strerror_r_check = cc.run(strerror_r_code, name : 'strerror_r check')
if strerror_r_check.returncode() == 0
conf.set('HAVE_XSI_STRERROR_R', 1)
else
conf.set('HAVE_GNU_STRERROR_R', 1)
endif
endif

conf.set10('HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME',
cc.has_header_symbol('errno.h',
'program_invocation_short_name',
Expand Down

0 comments on commit ccbe143

Please sign in to comment.