From patchwork Tue Aug 14 12:03:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 957456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-95233-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="HaFKmfTx"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41qWTN5q7Jz9s0n for ; Tue, 14 Aug 2018 22:03:36 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; q=dns; s=default; b= WH7WvKk2R2R/JA/xeovTphyZrsz9PfwIcR4bvVb81PlDqwg9yELIt4+xOBQKV1ju pM3u5wDIoXVdSUKAv0/XGf9KGFhfOPWNyEv1Q721odfFHHPRN4x1g6PFGAPy9Mew lwf7vlZRu5ZLQauDPoqe/LX/E7LOwaj3hUfqMm8HCb8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; s=default; bh=D2M3ZP ngmZtn1aPcOQYQPjUzMQc=; b=HaFKmfTxDCC9eh6H8Dv0RSv0PdLtm+8C6Ske00 P6n4DSd1ktMR9VM5Frh6mSuG7jwo+jOmLxOTJLXA5h31yqghgcci6WDEzO0liTY2 nJTOzGqPQ9ZEb511u2qtgOl0HnTy/USIV48TslIwEu7njtgXD3EEQAp35YXis5zP 7W7cg= Received: (qmail 29942 invoked by alias); 14 Aug 2018 12:03:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 29932 invoked by uid 89); 14 Aug 2018 12:03:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Leave X-HELO: mx1.redhat.com Date: Tue, 14 Aug 2018 14:03:25 +0200 To: libc-alpha@sourceware.org Subject: [PATCH] error, warn, warnx: Use __fxprintf for wide printing [BZ #23519] User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20180814120325.5D500405971E1@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) Also introduce the __vfxprintf function. 2018-08-14 Florian Weimer [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. diff --git a/include/stdio.h b/include/stdio.h index 9162d4e247..49383fb2d7 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/err.c b/misc/err.c index 2b836e8358..790ee127d5 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) + __vfxprintf (stderr, format, ap); + __fxprintf (stderr, "\n"); funlockfile (stderr); } libc_hidden_def (vwarnx) @@ -109,28 +55,14 @@ vwarn (const char *format, __gnuc_va_list ap) int error = errno; flockfile (stderr); - if (_IO_fwide (stderr, 0) > 0) + __fxprintf (stderr, "%s: ", __progname); + if (format) { - __fwprintf (stderr, L"%s: ", __progname); - if (format) - { - convert_and_print (format, ap); - fputws_unlocked (L": ", stderr); - } - __set_errno (error); - __fwprintf (stderr, L"%m\n"); - } - else - { - fprintf (stderr, "%s: ", __progname); - if (format) - { - vfprintf (stderr, format, ap); - fputs_unlocked (": ", stderr); - } - __set_errno (error); - fprintf (stderr, "%m\n"); + __vfxprintf (stderr, format, ap); + fputs_unlocked (": ", stderr); } + __set_errno (error); + __fxprintf (stderr, "%m\n"); funlockfile (stderr); } libc_hidden_def (vwarn) diff --git a/misc/error.c b/misc/error.c index 03378e2f2a..cb0de3af28 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/stdio-common/fxprintf.c b/stdio-common/fxprintf.c index c4a1146b20..8d02b71f91 100644 --- a/stdio-common/fxprintf.c +++ b/stdio-common/fxprintf.c @@ -61,19 +61,23 @@ locked_vfxprintf (FILE *fp, const char *fmt, va_list ap) return res; } +int +__vfxprintf (FILE *fp, const char *fmt, va_list ap) +{ + if (fp == NULL) + fp = stderr; + _IO_flockfile (fp); + int res = locked_vfxprintf (fp, fmt, ap); + _IO_funlockfile (fp); + return res; +} + int __fxprintf (FILE *fp, const char *fmt, ...) { - 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); + int res = __vfxprintf (fp, fmt, ap); va_end (ap); return res; }