[glib] More g_strerror() fixes
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] More g_strerror() fixes
- Date: Fri, 11 Sep 2015 16:40:07 +0000 (UTC)
commit 19eb511ba4f4914c1914472132d3601069bef906
Author: Dan Winship <danw gnome org>
Date: Wed Sep 9 11:16:30 2015 -0400
More g_strerror() fixes
Add a check to configure.ac for strerror_r, since we don't currently
require POSIX.1-2001 conformance in general. Add back a
plain-strerror() case as a fallback, and rearrange the glibc-vs-POSIX
strerror_r() branches.
Update the docs to not claim that "not all platforms support the
strerror() function" (we require C90), but still mention the UTF-8 and
always-valid-string benefits. (And make test_strerror() check that
last part.)
https://bugzilla.gnome.org/show_bug.cgi?id=754788
configure.ac | 2 +-
glib/gstrfuncs.c | 27 +++++++++++++++------------
glib/tests/strfuncs.c | 11 +++++++++++
3 files changed, 27 insertions(+), 13 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5cda0a7..ffca7a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -525,7 +525,7 @@ AM_CONDITIONAL(OS_WIN32_AND_DLL_COMPILATION, [test x$glib_native_win32 = xyes -a
# Checks for library functions.
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2 issetugid)
-AC_CHECK_FUNCS(timegm gmtime_r)
+AC_CHECK_FUNCS(timegm gmtime_r strerror_r)
AC_CACHE_CHECK([for __libc_enable_secure], glib_cv_have_libc_enable_secure,
[AC_TRY_LINK([#include <unistd.h>
diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c
index 2f0cda1..7d6e8ef 100644
--- a/glib/gstrfuncs.c
+++ b/glib/gstrfuncs.c
@@ -1238,13 +1238,15 @@ g_ascii_strtoll (const gchar *nptr,
* @errnum: the system error number. See the standard C %errno
* documentation
*
- * Returns a string corresponding to the given error code, e.g.
- * "no such process". You should use this function in preference to
- * strerror(), because it returns a string in UTF-8 encoding, and since
- * not all platforms support the strerror() function.
+ * Returns a string corresponding to the given error code, e.g. "no
+ * such process". Unlike strerror(), this always returns a string in
+ * UTF-8 encoding, and the pointer is guaranteed to remain valid for
+ * the lifetime of the process.
*
* Note that the string may be translated according to the current locale.
*
+ * The value of %errno will not be changed by this function.
+ *
* Returns: a UTF-8 string describing the error code. If the error code
* is unknown, it returns a string like "unknown error (<code>)".
*/
@@ -1258,19 +1260,20 @@ g_strerror (gint errnum)
gint saved_errno = errno;
GError *error = NULL;
-#ifdef G_OS_WIN32
+#if defined(G_OS_WIN32)
strerror_s (buf, sizeof (buf), errnum);
msg = buf;
- /* If we're using glibc, since we are building with _GNU_SOURCE, we
- * expect to get the GNU variant of strerror_r. However, use the
- * provided check from man strerror_r(3) in case we ever stop using
- * _GNU_SOURCE (admittedly unlikely).
- */
-#elif (defined __GLIBC__) && !((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
+#elif defined(HAVE_STRERROR_R)
+ /* Match the condition in strerror_r(3) for glibc */
+# if defined(__GLIBC__) && !((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
msg = strerror_r (errnum, buf, sizeof (buf));
-#else
+# else
strerror_r (errnum, buf, sizeof (buf));
msg = buf;
+# endif /* HAVE_STRERROR_R */
+#else
+ g_strlcpy (buf, strerror (errnum), sizeof (buf));
+ msg = buf;
#endif
if (!g_get_charset (NULL))
{
diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
index ad14a3c..cbf5be7 100644
--- a/glib/tests/strfuncs.c
+++ b/glib/tests/strfuncs.c
@@ -1317,17 +1317,28 @@ test_strip_context (void)
static void
test_strerror (void)
{
+ GHashTable *strs;
gint i;
const gchar *str;
+ GHashTableIter iter;
setlocale (LC_ALL, "C");
+ strs = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 1; i < 200; i++)
{
str = g_strerror (i);
g_assert (str != NULL);
g_assert (g_utf8_validate (str, -1, NULL));
+ g_assert_false (g_hash_table_contains (strs, str));
+ g_hash_table_add (strs, (char *)str);
}
+
+ g_hash_table_iter_init (&iter, strs);
+ while (g_hash_table_iter_next (&iter, (gpointer *)&str, NULL))
+ g_assert (g_utf8_validate (str, -1, NULL));
+
+ g_hash_table_unref (strs);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]