const char *
MR_strerror(int errnum, char *buf, size_t buflen)
{
#if defined(MR_HAVE_STRERROR_S)
    /*
    ** MSVC has strerror_s.  It also exists in C11 Annex K and is enabled by
    ** defining a preprocessor macro __STDC_WANT_LIB_EXT1__
    */
    if (strerror_s(buf, buflen, errnum) != 0) {
        generic_strerror(buf, buflen, errnum);
    }
    return buf;
#elif defined(MR_HAVE_STRERROR_R)
    /*
    ** The XSI-compliant and Mac OS X strerror_r populates buf unless it fails.
    ** The GNU-specific strerror_r does not always populate buf.
    */
  #if !defined(__GNU_LIBRARY__) || \
       ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
    int x = strerror_r(errnum, buf, buflen);
    if (x != 0) {
        generic_strerror(buf, buflen, errnum);
    }
    return buf;
  #else
    const char *s = strerror_r(errnum, buf, buflen);
    return s;
  #endif
#else
    /*
    ** Fallback using deprecated variables. This is used on MinGW at least.
    **
    ** strerror_l is another thread-safe alternative, specified in POSIX.
    ** It is locale-sensitive and takes a locale argument so we don't use it
    ** for now.
    */
    if (errnum >= 0 && errnum < sys_nerr && sys_errlist[errnum] != NULL) {
        return sys_errlist[errnum];
    } else {
        generic_strerror(buf, buflen, errnum);
        return buf;
    }
#endif
}
Exemple #2
0
const char *
MR_strerror(int errnum, char *buf, size_t buflen)
{
#if defined(MR_HAVE_STRERROR_S) && !defined(MR_MINGW)
    // MSVC has strerror_s. It also exists in C11 Annex K and is enabled by
    // defining a preprocessor macro __STDC_WANT_LIB_EXT1__
    //
    // On MinGW-w64, strerror_s results in an undefined reference to strerror_s
    // in MSVCRT.DLL on Windows XP. Avoid it until we drop support for XP.

    if (strerror_s(buf, buflen, errnum) != 0) {
        generic_strerror(buf, buflen, errnum);
    }
    return buf;
#elif defined(MR_HAVE_STRERROR_R)
    // The XSI-compliant and Mac OS X strerror_r populates buf unless it fails.
    // The GNU-specific strerror_r does not always populate buf.

  #if !defined(__GNU_LIBRARY__) || \
       ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
    int x = strerror_r(errnum, buf, buflen);
    if (x != 0) {
        generic_strerror(buf, buflen, errnum);
    }
    return buf;
  #else
    const char *s = strerror_r(errnum, buf, buflen);
    return s;
  #endif
#else
    // Fallback using deprecated variables. This is used on MinGW at least.
    //
    // strerror_l is another thread-safe alternative, specified in POSIX.
    // It is locale-sensitive and takes a locale argument so we don't use it
    // for now.

    if (errnum >= 0 && errnum < sys_nerr && sys_errlist[errnum] != NULL) {
        return sys_errlist[errnum];
    } else {
        generic_strerror(buf, buflen, errnum);
        return buf;
    }
#endif
}