This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.28.9000-58-gfdb16de


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  fdb16de38705ccff0dbf38af9956eb4165710106 (commit)
      from  599cf3976679e1b345307d9c02057f02aa95528f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fdb16de38705ccff0dbf38af9956eb4165710106

commit fdb16de38705ccff0dbf38af9956eb4165710106
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 14 13:36:10 2018 +0200

    error, warn, warnx: Use __fxprintf for wide printing [BZ #23519]
    
    Also introduce the __vfxprintf function.

diff --git a/ChangeLog b/ChangeLog
index b3493b9..90b693b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-08-14  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23519]
+	* include/stdio.h (__vfxprintf): Declare.
+	* stdio-common/fxprintf.c (__vfxprintf): New function.
+	(__fxprintf): Call it.
+	* misc/err.c (convert_and_print): Remove function.
+	(vwarnx, vwarn): Call __fxprintf and __vfxprintf.
+	* misc/error.c [_LIBC] (error_tail): Call __vfxprintf.
+	* misc/Makefile (tests): Add tst-warn-wide.
+	* misc/tst-warn-wide.c: New file.
+
 2018-08-14  Wilco Dijkstra  <wdijkstr@arm.com>
 	    Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
diff --git a/include/stdio.h b/include/stdio.h
index 9162d4e..49383fb 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -126,6 +126,8 @@ extern int __fxprintf (FILE *__fp, const char *__fmt, ...)
      __attribute__ ((__format__ (__printf__, 2, 3))) attribute_hidden;
 extern int __fxprintf_nocancel (FILE *__fp, const char *__fmt, ...)
      __attribute__ ((__format__ (__printf__, 2, 3))) attribute_hidden;
+int __vfxprintf (FILE *__fp, const char *__fmt, __gnuc_va_list)
+  attribute_hidden;
 
 /* Read the next line from FP into BUFFER, of LENGTH bytes.  LINE will
    include the line terminator and a NUL terminator.  On success,
diff --git a/misc/Makefile b/misc/Makefile
index b7be2bc..9a87e81 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -84,7 +84,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
 	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
 	 tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240 \
 	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
-	 tst-preadvwritev2 tst-preadvwritev64v2
+	 tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide
 
 tests-internal := tst-atomic tst-atomic-long tst-allocate_once
 tests-static := tst-empty
diff --git a/misc/err.c b/misc/err.c
index 2b836e8..b6afe65 100644
--- a/misc/err.c
+++ b/misc/err.c
@@ -37,68 +37,14 @@ extern char *__progname;
   va_end (ap);								      \
 }
 
-static void
-convert_and_print (const char *format, __gnuc_va_list ap)
-{
-#define ALLOCA_LIMIT	2000
-  size_t len;
-  wchar_t *wformat = NULL;
-  mbstate_t st;
-  size_t res;
-  const char *tmp;
-
-  if (format == NULL)
-    return;
-
-  len = strlen (format) + 1;
-
-  do
-    {
-      if (len < ALLOCA_LIMIT)
-	wformat = (wchar_t *) alloca (len * sizeof (wchar_t));
-      else
-	{
-	  if (wformat != NULL && len / 2 < ALLOCA_LIMIT)
-	    wformat = NULL;
-
-	  wformat = (wchar_t *) realloc (wformat, len * sizeof (wchar_t));
-
-	  if (wformat == NULL)
-	    {
-	      fputws_unlocked (L"out of memory\n", stderr);
-	      return;
-	    }
-	}
-
-      memset (&st, '\0', sizeof (st));
-      tmp =format;
-    }
-  while ((res = __mbsrtowcs (wformat, &tmp, len, &st)) == len);
-
-  if (res == (size_t) -1)
-    /* The string cannot be converted.  */
-    wformat = (wchar_t *) L"???";
-
-  __vfwprintf (stderr, wformat, ap);
-}
-
 void
 vwarnx (const char *format, __gnuc_va_list ap)
 {
   flockfile (stderr);
-  if (_IO_fwide (stderr, 0) > 0)
-    {
-      __fwprintf (stderr, L"%s: ", __progname);
-      convert_and_print (format, ap);
-      putwc_unlocked (L'\n', stderr);
-    }
-  else
-    {
-      fprintf (stderr, "%s: ", __progname);
-      if (format)
-	vfprintf (stderr, format, ap);
-      putc_unlocked ('\n', stderr);
-    }
+  __fxprintf (stderr, "%s: ", __progname);
+  if (format != NULL)
+    __vfxprintf (stderr, format, ap);
+  __fxprintf (stderr, "\n");
   funlockfile (stderr);
 }
 libc_hidden_def (vwarnx)
@@ -109,27 +55,17 @@ vwarn (const char *format, __gnuc_va_list ap)
   int error = errno;
 
   flockfile (stderr);
-  if (_IO_fwide (stderr, 0) > 0)
+  if (format != NULL)
     {
-      __fwprintf (stderr, L"%s: ", __progname);
-      if (format)
-	{
-	  convert_and_print (format, ap);
-	  fputws_unlocked (L": ", stderr);
-	}
+      __fxprintf (stderr, "%s: ", __progname);
+      __vfxprintf (stderr, format, ap);
       __set_errno (error);
-      __fwprintf (stderr, L"%m\n");
+      __fxprintf (stderr, ": %m\n");
     }
   else
     {
-      fprintf (stderr, "%s: ", __progname);
-      if (format)
-	{
-	  vfprintf (stderr, format, ap);
-	  fputs_unlocked (": ", stderr);
-	}
       __set_errno (error);
-      fprintf (stderr, "%m\n");
+      __fxprintf (stderr, "%s: %m\n", __progname);
     }
   funlockfile (stderr);
 }
diff --git a/misc/error.c b/misc/error.c
index 03378e2..cb0de3a 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -203,72 +203,14 @@ static void _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) _GL_ARG_NONNULL ((3))
 error_tail (int status, int errnum, const char *message, va_list args)
 {
 #if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    {
-      size_t len = strlen (message) + 1;
-      wchar_t *wmessage = NULL;
-      mbstate_t st;
-      size_t res;
-      const char *tmp;
-      bool use_malloc = false;
-
-      while (1)
-	{
-	  if (__libc_use_alloca (len * sizeof (wchar_t)))
-	    wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
-	  else
-	    {
-	      if (!use_malloc)
-		wmessage = NULL;
-
-	      wchar_t *p = (wchar_t *) realloc (wmessage,
-						len * sizeof (wchar_t));
-	      if (p == NULL)
-		{
-		  free (wmessage);
-		  fputws_unlocked (L"out of memory\n", stderr);
-		  return;
-		}
-	      wmessage = p;
-	      use_malloc = true;
-	    }
-
-	  memset (&st, '\0', sizeof (st));
-	  tmp = message;
-
-	  res = mbsrtowcs (wmessage, &tmp, len, &st);
-	  if (res != len)
-	    break;
-
-	  if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0))
-	    {
-	      /* This really should not happen if everything is fine.  */
-	      res = (size_t) -1;
-	      break;
-	    }
-
-	  len *= 2;
-	}
-
-      if (res == (size_t) -1)
-	{
-	  /* The string cannot be converted.  */
-	  if (use_malloc)
-	    {
-	      free (wmessage);
-	      use_malloc = false;
-	    }
-	  wmessage = (wchar_t *) L"???";
-	}
-
-      __vfwprintf (stderr, wmessage, args);
-
-      if (use_malloc)
-	free (wmessage);
-    }
-  else
+  int ret = __vfxprintf (stderr, message, args);
+  if (ret < 0 && errno == ENOMEM && _IO_fwide (stderr, 0) > 0)
+    /* Leave a trace in case the heap allocation of the message string
+       failed.  */
+    fputws_unlocked (L"out of memory\n", stderr);
+#else
+  vfprintf (stderr, message, args);
 #endif
-    vfprintf (stderr, message, args);
   va_end (args);
 
   ++error_message_count;
diff --git a/misc/tst-warn-wide.c b/misc/tst-warn-wide.c
new file mode 100644
index 0000000..773bbba
--- /dev/null
+++ b/misc/tst-warn-wide.c
@@ -0,0 +1,88 @@
+/* Test wide output conversion for warn.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xmemstream.h>
+#include <wchar.h>
+
+/* Used to trigger the large-string path in __fxprintf.  */
+#define PADDING \
+  "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
+  "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
+  "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+
+#define LPADDING \
+  L"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  \
+  "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
+  "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+
+
+static void
+one_test (const char *message, int error_code, const wchar_t *expected)
+{
+  wchar_t *buffer = NULL;
+  size_t length = 0;
+  FILE *fp = open_wmemstream (&buffer, &length);
+  TEST_VERIFY_EXIT (fp != NULL);
+  FILE *old_stderr = stderr;
+  stderr = fp;
+  errno = error_code;
+  switch (error_code)
+    {
+    case E2BIG:
+      warn ("%s with padding " PADDING, message);
+      break;
+    case EAGAIN:
+      warn ("%s", message);
+      break;
+    case -1:
+      warnx ("%s", message);
+      break;
+    case -2:
+      warnx ("%s with padding " PADDING, message);
+      break;
+    }
+  stderr = old_stderr;
+  TEST_VERIFY_EXIT (!ferror (fp));
+  TEST_COMPARE (fclose (fp), 0);
+  if (wcscmp (buffer, expected) != 0)
+    FAIL_EXIT1 ("unexpected output: %ls", buffer);
+  free (buffer);
+}
+
+static int
+do_test (void)
+{
+  one_test ("no errno", -1,
+            L"tst-warn-wide: no errno\n");
+  one_test ("no errno", -2,
+            L"tst-warn-wide: no errno with padding " PADDING "\n");
+  one_test ("with errno", EAGAIN,
+            L"tst-warn-wide: with errno: Resource temporarily unavailable\n");
+  one_test ("with errno", E2BIG,
+            L"tst-warn-wide: with errno with padding " PADDING
+            ": Argument list too long\n");
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
index c4a1146..8d02b71 100644
--- a/stdio-common/fxprintf.c
+++ b/stdio-common/fxprintf.c
@@ -62,18 +62,22 @@ locked_vfxprintf (FILE *fp, const char *fmt, va_list ap)
 }
 
 int
-__fxprintf (FILE *fp, const char *fmt, ...)
+__vfxprintf (FILE *fp, const char *fmt, va_list ap)
 {
   if (fp == NULL)
     fp = stderr;
-
-  va_list ap;
-  va_start (ap, fmt);
   _IO_flockfile (fp);
-
   int res = locked_vfxprintf (fp, fmt, ap);
-
   _IO_funlockfile (fp);
+  return res;
+}
+
+int
+__fxprintf (FILE *fp, const char *fmt, ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  int res = __vfxprintf (fp, fmt, ap);
   va_end (ap);
   return res;
 }

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

Summary of changes:
 ChangeLog               |   12 ++++++
 include/stdio.h         |    2 +
 misc/Makefile           |    2 +-
 misc/err.c              |   82 +++++---------------------------------------
 misc/error.c            |   72 ++++----------------------------------
 misc/tst-warn-wide.c    |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 stdio-common/fxprintf.c |   16 +++++---
 7 files changed, 129 insertions(+), 145 deletions(-)
 create mode 100644 misc/tst-warn-wide.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]