From patchwork Wed May 13 20:26:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 39238 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2F897388B035; Wed, 13 May 2020 20:26:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2F897388B035 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1589401602; bh=C5XFmFn873uIxpf6/6D//Mx+VTC84X5VXCaCZN49KyI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=aPgR1L2apxWXcbmIZ5OoXA+B5l6+mYIyyRY6DoJCGwLemqYzBBsvt0eGaJl9EU3Zz fbt0MJXYcijslWjvkHp8aI6Mn9T2jBun6tfEk5pnWjC/5oJZsDc8BcM2C68qV0GK85 yq3JKx0guzvRofQDkCBUYGQp+eUKQ0uGF53rfv7g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by sourceware.org (Postfix) with ESMTPS id F07D33894E54 for ; Wed, 13 May 2020 20:26:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org F07D33894E54 Received: by mail-qk1-x72b.google.com with SMTP id i5so700590qkl.12 for ; Wed, 13 May 2020 13:26:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C5XFmFn873uIxpf6/6D//Mx+VTC84X5VXCaCZN49KyI=; b=Au0qjedsm2UBKbBq+S7Q+Wy6dwroQZCy69mwZxlXIkHXIgbWrjWaLsaGAJDrc8zby5 eFLInGcFYAhhyDaGpqnM6PpzMmtlrMEh5cukSKfN9GGcYhOg4T5alxihUUHI5bPZbHl+ qU9F2IJR1uTGQOjiCyaRV2fSlZu1dYF2sQkspQq1sJwrm+1B7tr2/nOa1bC4JhKUO1m2 DcTIk8l4g8wCYesCn6zWy646kph6tHc417+sM2+o3ibcxq08fCJASIqhhUfAM322MsJ6 qRJEO6Xs/J3RymuZmVRhV8sY/kSxyRQ21gqsxFf6mdqgo0NcLDsbpUi4JL7gEUdlXGFJ K+VA== X-Gm-Message-State: AOAM531tzRlZ0/ODvR+VROEQnD/G2WBaokIe0gYVNyq4qc59CxMMMrL5 jJWCebTRQR3+rYWis1HdnB5hZtgHrSA= X-Google-Smtp-Source: ABdhPJzhaH4GX79IHY2VUOHscTxGLGp5+f5ezOiw5tyvAj/d6LK0SUkv70eIAyALdQkDOOMRsgGuNQ== X-Received: by 2002:a05:620a:208f:: with SMTP id e15mr1579256qka.440.1589401596774; Wed, 13 May 2020 13:26:36 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id 62sm806465qkh.113.2020.05.13.13.26.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2020 13:26:36 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [RFC 1/4] string: Make strsignal async-signal-safe Date: Wed, 13 May 2020 17:26:27 -0300 Message-Id: <20200513202630.2123238-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> References: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-16.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" To accomplish it a per-thread static buffer is used for unknown signals and the resulting message is not translated (this will be covered by a new function). To setup the per-thread static buffer, two strategies are used: 1. The default one uses a TLS structure, which will be place in the static TLS space. 2. Linux allocates on struct pthread and access it through THREAD_* macros. The default strategy has the disadvantage of increasing libc.so static TLS consumption and thus descreasing the possible surplus used in some scenarios (which might be mitigated by BZ#25051 fix). It is used only on Hurd, where accessing the thread point in single thread case is not straightforward (afaiu, Hurd developers could correct me here). Checked on x86-64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, and s390x-linux-gnu. --- manual/signal.texi | 6 +- nptl/descr.h | 5 +- string/strsignal.c | 119 +++++++------------------ sysdeps/generic/Makefile | 1 + sysdeps/generic/tls_internal-struct.h | 32 +++++++ sysdeps/generic/tls_internal.c | 3 + sysdeps/generic/tls_internal.h | 32 +++++++ sysdeps/unix/sysv/linux/tls_internal.c | 1 + sysdeps/unix/sysv/linux/tls_internal.h | 30 +++++++ time/strftime_l.c | 10 +-- 10 files changed, 139 insertions(+), 100 deletions(-) create mode 100644 sysdeps/generic/tls_internal-struct.h create mode 100644 sysdeps/generic/tls_internal.c create mode 100644 sysdeps/generic/tls_internal.h create mode 100644 sysdeps/unix/sysv/linux/tls_internal.c create mode 100644 sysdeps/unix/sysv/linux/tls_internal.h diff --git a/manual/signal.texi b/manual/signal.texi index 33e6646975..08f0edb306 100644 --- a/manual/signal.texi +++ b/manual/signal.texi @@ -830,8 +830,8 @@ termination status of a child process (@pxref{Process Completion}) or it may come from a signal handler in the same process. @deftypefun {char *} strsignal (int @var{signum}) -@standards{GNU, string.h} -@safety{@prelim{}@mtunsafe{@mtasurace{:strsignal} @mtslocale{}}@asunsafe{@asuinit{} @ascuintl{} @asucorrupt{} @ascuheap{}}@acunsafe{@acuinit{} @acucorrupt{} @acsmem{}}} +@standards{POSIX-1.2008, string.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} @c strsignal @mtasurace:strsignal @mtslocale @asuinit @ascuintl @asucorrupt @ascuheap @acucorrupt @acsmem @c uses a static buffer if tsd key creation fails @c [once] init @@ -852,7 +852,7 @@ rewritten on subsequent calls, you should save a copy of it if you need to reference it later. @pindex string.h -This function is a GNU extension, declared in the header file +This function is declared in the header file @file{string.h}. @end deftypefun diff --git a/nptl/descr.h b/nptl/descr.h index e1c7db5473..ee8f4b0e37 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -34,6 +34,7 @@ #include #include #include +#include #ifndef TCB_ALIGNMENT # define TCB_ALIGNMENT sizeof (double) @@ -116,7 +117,6 @@ struct priority_protection_data unsigned int priomap[]; }; - /* Thread descriptor data structure. */ struct pthread { @@ -398,6 +398,9 @@ struct pthread /* Indicates whether is a C11 thread created by thrd_creat. */ bool c11; + /* Used on strsignal. */ + struct tls_internal_t tls_state; + /* This member must be last. */ char end_padding[]; diff --git a/string/strsignal.c b/string/strsignal.c index 1551480026..5fbc3d9a60 100644 --- a/string/strsignal.c +++ b/string/strsignal.c @@ -16,110 +16,55 @@ . */ #include -#include -#include #include -#include -#include - -static __libc_key_t key; - -/* If nonzero the key allocation failed and we should better use a - static buffer than fail. */ -#define BUFFERSIZ 100 -static char local_buf[BUFFERSIZ]; -static char *static_buf; +#include +#include +#include -/* Destructor for the thread-specific data. */ -static void init (void); -static void free_key_mem (void *mem); -static char *getbuffer (void); +#define RT_STR "Real-time signal " +_Static_assert (sizeof (RT_STR) <= strsignal_str_len, + RT_STR " > strsignal_str_len"); +#define UNK_STR "Unknown signal " +_Static_assert (sizeof (UNK_STR) <= strsignal_str_len, + UNK_STR " > strsignal_str_len"); /* Return a string describing the meaning of the signal number SIGNUM. */ char * strsignal (int signum) { - __libc_once_define (static, once); - const char *desc; + const char *desc = NULL; + + if (signum >= 0 && signum <= NSIG + && signum < array_length (__sys_siglist_internal)) + desc = __sys_siglist_internal[signum]; - /* If we have not yet initialized the buffer do it now. */ - __libc_once (once, init); + if (desc != NULL) + return (char *) desc; - if ( + const char* prefix = UNK_STR; #ifdef SIGRTMIN - (signum >= SIGRTMIN && signum <= SIGRTMAX) || -#endif - signum < 0 || signum >= NSIG - || (desc = __sys_siglist_internal[signum]) == NULL) + if (signum >= SIGRTMIN && signum <= SIGRTMAX) { - char *buffer = getbuffer (); - int len; -#ifdef SIGRTMIN - if (signum >= SIGRTMIN && signum <= SIGRTMAX) - len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"), - signum - SIGRTMIN); - else -#endif - len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"), - signum); - if (len >= BUFFERSIZ) - buffer = NULL; - else - buffer[len] = '\0'; - - return buffer; + prefix = RT_STR; + signum -= SIGRTMIN; } +#endif - return (char *) _(desc); -} - - -/* Initialize buffer. */ -static void -init (void) -{ - if (__libc_key_create (&key, free_key_mem)) - /* Creating the key failed. This means something really went - wrong. In any case use a static buffer which is better than - nothing. */ - static_buf = local_buf; -} - - -/* Free the thread specific data, this is done if a thread terminates. */ -static void -free_key_mem (void *mem) -{ - free (mem); - __libc_setspecific (key, NULL); -} - + char *buffer = __glibc_tls_internal ()->strsignal_buf; -/* Return the buffer to be used. */ -static char * -getbuffer (void) -{ - char *result; + char *q = __stpcpy (buffer, prefix); - if (static_buf != NULL) - result = static_buf; - else + if (signum < 0) { - /* We don't use the static buffer and so we have a key. Use it - to get the thread-specific buffer. */ - result = __libc_getspecific (key); - if (result == NULL) - { - /* No buffer allocated so far. */ - result = malloc (BUFFERSIZ); - if (result == NULL) - /* No more memory available. We use the static buffer. */ - result = local_buf; - else - __libc_setspecific (key, result); - } + *q++ = '-'; + signum = abs (signum); } + for (int d = signum; q++, (d /= 10) != 0; ) + continue; + *q = '\0'; + for (int d = signum; *--q = '0' + d % 10, (d /= 10) != 0; ) + continue; - return result; + return buffer; } diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile index bd4f9425ca..9bed5d7fa2 100644 --- a/sysdeps/generic/Makefile +++ b/sysdeps/generic/Makefile @@ -16,6 +16,7 @@ # . ifeq ($(subdir),string) +sysdep_routines += tls_internal CFLAGS-wordcopy.c += -Wno-uninitialized endif diff --git a/sysdeps/generic/tls_internal-struct.h b/sysdeps/generic/tls_internal-struct.h new file mode 100644 index 0000000000..dac967b2f3 --- /dev/null +++ b/sysdeps/generic/tls_internal-struct.h @@ -0,0 +1,32 @@ +/* Per-thread state. Generic version. + Copyright (C) 2020 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 + . */ + +#ifndef _TLS_INTERNAL_STRUCT_H +#define _TLS_INTERNAL_STRUCT_H 1 + +#include + +enum { strsignal_str_len = 20 }; + +struct tls_internal_t +{ + /* Used on strsignal.c. */ + char strsignal_buf[strsignal_str_len + INT_STRLEN_BOUND (int) + 1]; +}; + +#endif diff --git a/sysdeps/generic/tls_internal.c b/sysdeps/generic/tls_internal.c new file mode 100644 index 0000000000..e988a608b2 --- /dev/null +++ b/sysdeps/generic/tls_internal.c @@ -0,0 +1,3 @@ +#include + +__thread struct tls_internal_t tls_internal; diff --git a/sysdeps/generic/tls_internal.h b/sysdeps/generic/tls_internal.h new file mode 100644 index 0000000000..6edc4e574c --- /dev/null +++ b/sysdeps/generic/tls_internal.h @@ -0,0 +1,32 @@ +/* Per-thread state. Generic version. + Copyright (C) 2020 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 + . */ + +#ifndef _TLS_INTERNAL_H +#define _TLS_INTERNAL_H 1 + +#include + +extern __thread struct tls_internal_t tls_internal attribute_hidden; + +static inline struct tls_internal_t * +__glibc_tls_internal (void) +{ + return &tls_internal; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/tls_internal.c b/sysdeps/unix/sysv/linux/tls_internal.c new file mode 100644 index 0000000000..6e25b021ab --- /dev/null +++ b/sysdeps/unix/sysv/linux/tls_internal.c @@ -0,0 +1 @@ +/* Empty. */ diff --git a/sysdeps/unix/sysv/linux/tls_internal.h b/sysdeps/unix/sysv/linux/tls_internal.h new file mode 100644 index 0000000000..f1d3161e08 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tls_internal.h @@ -0,0 +1,30 @@ +/* Per-thread state. Linux version. + Copyright (C) 2020 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 + . */ + +#ifndef _TLS_INTERNAL_H +#define _TLS_INTERNAL_H 1 + +#include + +static inline struct tls_internal_t * +__glibc_tls_internal (void) +{ + return &THREAD_SELF->tls_state; +} + +#endif diff --git a/time/strftime_l.c b/time/strftime_l.c index a9aae42191..83a62dbb6b 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -136,15 +136,7 @@ extern char *tzname[]; # define NULL 0 #endif -#define TYPE_SIGNED(t) ((t) -1 < 0) - -/* Bound on length of the string representing an integer value of type t. - Subtract one for the sign bit if t is signed; - 302 / 1000 is log10 (2) rounded up; - add one for integer division truncation; - add one more for a minus sign if t is signed. */ -#define INT_STRLEN_BOUND(t) \ - ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t)) +#include #define TM_YEAR_BASE 1900 From patchwork Wed May 13 20:26:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 39239 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AFFF73851C34; Wed, 13 May 2020 20:26:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AFFF73851C34 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1589401603; bh=vEfxd6VX5MAaILfjN4dy2fRItE0bJfaTcyOZZWl4tPc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=P2N9YMlGZEw9tZr//xhDcfxECKP3vyL+K2voyM18F4CMV77mVpcFlZ9qXoOxMvo5t 5V/9SZsAkAU8KH6ynIJ/XeumLb6mNZAVn7Dgpkecgzeon12h7E1sOFXKX5la6BwaXl h2lUr41AMAy9wZMjr25e+IDDOKce/pailI0RJTqQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x836.google.com (mail-qt1-x836.google.com [IPv6:2607:f8b0:4864:20::836]) by sourceware.org (Postfix) with ESMTPS id B149F385DC14 for ; Wed, 13 May 2020 20:26:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B149F385DC14 Received: by mail-qt1-x836.google.com with SMTP id i68so998080qtb.5 for ; Wed, 13 May 2020 13:26:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vEfxd6VX5MAaILfjN4dy2fRItE0bJfaTcyOZZWl4tPc=; b=fzvFl3TpqnjgHesh7Dfyol5n7ubIB9LBr/6YZZoWZaUHG2zeIkGax07MF4JmrlTcP7 vF5ywkyGFvzMOywAGOAo0ViB3eMw2k2TxMxrKmO3d5QfKlXj+TpjkknKXW1QOcPEcPfD QRycTwL+jM8tC+Ab9B6NwWMwLB4lzhFBBx+fMGDWxVYxerDqegnRw+l0f3rZFyJh/4hq 27VyxEih5u2cWEAh6hKPjLY70C25X/Kf4VS5cmrWfyr/AegaPyzW7E24JBwVQAyTllD3 m2m91i/lhqNonzmNrtpLIsmGNUg5TYvVIzopvsHLu32onjA2CKaSAoznwJ+C407iNMFn HZtQ== X-Gm-Message-State: AOAM532fTCWwA13b4Wh7oNKW/w1PhqSpcnbveUkJ9lYpngpo1yw5F78I yrd5nS21/nWnsS3+6l6DYCa5TWLi3xE= X-Google-Smtp-Source: ABdhPJwrF5qAI/v8vPhz7+y4KcYiUyXXt4THr269orYvQv4D4M7oTEWkOeLZV6pjaDP9ELK5gotKRw== X-Received: by 2002:ac8:1491:: with SMTP id l17mr951308qtj.322.1589401598451; Wed, 13 May 2020 13:26:38 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id 62sm806465qkh.113.2020.05.13.13.26.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2020 13:26:38 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [RFC 2/4] string: Add strsignal_l Date: Wed, 13 May 2020 17:26:28 -0300 Message-Id: <20200513202630.2123238-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> References: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-16.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Similar to strsignal, but maps the input signal to a locale-dependent signal description. The internal buffer is allocated with malloc (as previously done by strsignal) and its pointer is stored in the same per-thread structure used on strsignal (making is thread-safe). The behavior of strsignal_l is undefined if locale is the special locale object LC_GLOBAL_LOCALE or is not a valid locale object handle. Checked on x86-64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, and s390x-linux-gnu. --- include/string.h | 1 + malloc/thread-freeres.c | 1 + string/Makefile | 2 +- string/Versions | 3 + string/string.h | 5 ++ string/strsignal_l.c | 68 +++++++++++++++++++ sysdeps/generic/tls_internal-struct.h | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 37 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 string/strsignal_l.c diff --git a/include/string.h b/include/string.h index 4d622f1c03..24a61bcff7 100644 --- a/include/string.h +++ b/include/string.h @@ -51,6 +51,7 @@ extern int __ffs (int __i) __attribute__ ((const)); extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen); /* Called as part of the thread shutdown sequence. */ +void __strsignal_thread_freeres (void) attribute_hidden; void __strerror_thread_freeres (void) attribute_hidden; /* Get _STRING_ARCH_unaligned. */ diff --git a/malloc/thread-freeres.c b/malloc/thread-freeres.c index c71ca4fc33..d42eea770b 100644 --- a/malloc/thread-freeres.c +++ b/malloc/thread-freeres.c @@ -32,6 +32,7 @@ __libc_thread_freeres (void) call_function_static_weak (__rpc_thread_destroy); call_function_static_weak (__res_thread_freeres); call_function_static_weak (__strerror_thread_freeres); + call_function_static_weak (__strsignal_thread_freeres); /* This should come last because it shuts down malloc for this thread and the other shutdown functions might well call free. */ diff --git a/string/Makefile b/string/Makefile index c46785f1a1..4ec56c5fce 100644 --- a/string/Makefile +++ b/string/Makefile @@ -44,7 +44,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \ addsep replace) \ envz basename \ strcoll_l strxfrm_l string-inlines memrchr \ - xpg-strerror strerror_l explicit_bzero + xpg-strerror strerror_l explicit_bzero strsignal_l strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ diff --git a/string/Versions b/string/Versions index 9b709d12a9..3830c577f8 100644 --- a/string/Versions +++ b/string/Versions @@ -85,4 +85,7 @@ libc { GLIBC_2.25 { explicit_bzero; } + GLIBC_2.32 { + strsignal_l; + } } diff --git a/string/string.h b/string/string.h index d7ce0f4a1b..f36f3ac69f 100644 --- a/string/string.h +++ b/string/string.h @@ -454,6 +454,11 @@ extern char *strsep (char **__restrict __stringp, /* Return a string describing the meaning of the signal number in SIG. */ extern char *strsignal (int __sig) __THROW; +# ifdef __USE_GNU +/* Translate the meaning of the signal in SIG according to the locale L. */ +extern char *strsignal_l (int __sig, locale_t __l) __THROW; +# endif + /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src) __THROW __nonnull ((1, 2)); diff --git a/string/strsignal_l.c b/string/strsignal_l.c new file mode 100644 index 0000000000..054593da34 --- /dev/null +++ b/string/strsignal_l.c @@ -0,0 +1,68 @@ +/* Return the translated string describing signal. + Copyright (C) 2020 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char * +translate (const char *str, locale_t loc) +{ + locale_t oldloc = __uselocale (loc); + const char *res = _(str); + __uselocale (oldloc); + return res; +} + +char * +strsignal_l (int signum, locale_t loc) +{ + const char *desc = NULL; + + if (signum >= 0 && signum <= NSIG + && signum < array_length (__sys_siglist_internal)) + desc = __sys_siglist_internal[signum]; + + if (desc != NULL) + return (char *) translate (desc, loc); + + const char* prefix = "Unknown signal "; +#ifdef SIGRTMIN + if (signum >= SIGRTMIN && signum <= SIGRTMAX) + prefix = "Real-time signal "; +#endif + + struct tls_internal_t *tls_internal = __glibc_tls_internal (); + free (tls_internal->strsignal_l_buf); + if (__asprintf (&tls_internal->strsignal_l_buf, "%s%d", + translate (prefix, loc), signum) == -1) + tls_internal->strsignal_l_buf = NULL; + return tls_internal->strsignal_l_buf; +} + +void +__strsignal_thread_freeres (void) +{ + free (__glibc_tls_internal()->strsignal_l_buf); +} +text_set_element (__libc_subfreeres, __strsignal_thread_freeres); diff --git a/sysdeps/generic/tls_internal-struct.h b/sysdeps/generic/tls_internal-struct.h index dac967b2f3..ca235a93db 100644 --- a/sysdeps/generic/tls_internal-struct.h +++ b/sysdeps/generic/tls_internal-struct.h @@ -27,6 +27,7 @@ struct tls_internal_t { /* Used on strsignal.c. */ char strsignal_buf[strsignal_str_len + INT_STRLEN_BOUND (int) + 1]; + char *strsignal_l_buf; }; #endif diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 41bb214bb9..ff9f9cc8b9 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2147,3 +2147,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 6430af207f..d97e08958f 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2227,6 +2227,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index f4ea1756d5..deafe483fb 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -134,6 +134,7 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index f1456b26b2..e92d2f620d 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -131,6 +131,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index c54aed2f8e..16788d6e72 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2091,3 +2091,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 87373f755b..0df921a1c5 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2048,6 +2048,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 1bd2e02f79..c67bcd575d 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2214,6 +2214,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 07e51d46bf..19f13dae24 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2080,6 +2080,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 42ea4c24bf..88c60ac4ce 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -135,6 +135,7 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index e9358fb092..89a2fe6b96 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2160,6 +2160,7 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 2cefe739c0..ba8119f080 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2142,3 +2142,4 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 3474ef1490..e5db46bf46 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2139,3 +2139,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index a6f99a7369..9d655367d2 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2131,6 +2131,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 48222af11c..d5d85ddf7e 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2129,6 +2129,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 99965cfb0f..7ce3f58728 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2137,6 +2137,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 2c8bafc669..5ed3392638 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2131,6 +2131,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 52cf72052c..fa62ca14c8 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2180,3 +2180,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 2ca5bbccf3..8ad2ab5a1a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2187,6 +2187,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index e6c4d002d5..81d1622da2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2220,6 +2220,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 82d77b7e48..d289bc9dbc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2050,6 +2050,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 0c2513a4b3..cc52e4bc74 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2342,3 +2342,4 @@ GLIBC_2.32 __wprintf_chkieee128 F GLIBC_2.32 __wprintfieee128 F GLIBC_2.32 __wscanfieee128 F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 234d34929a..fcee77e8de 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2109,3 +2109,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 1f06cce028..9c776e41c4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2185,6 +2185,7 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 26c2ce32e5..797429f31f 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2086,6 +2086,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 7ad2e920c3..1e8bf1ace9 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2055,6 +2055,7 @@ GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d2611bf0a5..4914ec8a8d 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2052,6 +2052,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 18a528f0e9..672f5bda1b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2176,6 +2176,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index a1d48b0f3c..18f0685684 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2103,6 +2103,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 6418ace78a..581a403365 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2061,6 +2061,7 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index edb9f2f004..5961531257 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2160,3 +2160,4 @@ GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.32 pthread_sigmask F +GLIBC_2.32 strsignal_l F From patchwork Wed May 13 20:26:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 39240 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 39266389202A; Wed, 13 May 2020 20:26:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 39266389202A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1589401604; bh=imrg7RDq+uxNxd5hjVAn2I7Dmk/vAz0valmfMj+FuyQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=C1/u/Zthmf0hac6gFPcGnFLQ6GRQFzR2hhu2BBa0oLveJhyO19+6D9E1kSdCQUICb 2mgjoNxSlaAKO68oMufMAVBAANcDmzB98rqmRxLx7KENfxYCmjjGKyGDU2Vr8NuD8W tgvL2S9A0kXM5NxTKFCBmac96T0pVbibSbuQXwBg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x830.google.com (mail-qt1-x830.google.com [IPv6:2607:f8b0:4864:20::830]) by sourceware.org (Postfix) with ESMTPS id E1C11385DC1B for ; Wed, 13 May 2020 20:26:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E1C11385DC1B Received: by mail-qt1-x830.google.com with SMTP id o19so969247qtr.10 for ; Wed, 13 May 2020 13:26:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=imrg7RDq+uxNxd5hjVAn2I7Dmk/vAz0valmfMj+FuyQ=; b=mYbzjgsqETKqKqwwDfSdG9t2a3TRo0GRRKZlp27Gdi5Zbi50QeiJxqhmljW01JXkEu gyziS7NP4QMtSFa2OBtuafp0CRVIk6wAV34Bky8+P73mOJQME9w1yVFjIQ+ISNFtQePQ KC/rpEXJO2/z04b1SJ8JVH52+PGpO4Bc6mUU0E1nljTXLfw0V8lkKoAMfeAdDpoKK9NO hxebT0AXVazUvF+nsReJfY5g8zJp9EPBsTQNlmQVL6llY/gowoJ2SzUidEp/lZyQOOF4 WwOI57L/aWQGjNJMT+VbnyHVN1zdgNmooSJSHwO+6weQmBxyKswx7etKmE7jIu4V3cUr FQVw== X-Gm-Message-State: AOAM530AA0VGYBzjkt3/X/+BMO6iWkLGyrxQHS7AEy1BZVMyeRsO+iYZ gJDwB9g9hSzBDHhSdJccrk1vQa9Grkw= X-Google-Smtp-Source: ABdhPJy/wZD3/0wZmIGhc1nTZKg6JWXuxE6u5s9naK5OURz4Uy+ahcUCoZdmQj6JLsu7s4WFkLsp9g== X-Received: by 2002:ac8:2a70:: with SMTP id l45mr995774qtl.232.1589401599890; Wed, 13 May 2020 13:26:39 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id 62sm806465qkh.113.2020.05.13.13.26.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2020 13:26:39 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [RFC 3/4] string: Make strerror async-signal-safe Date: Wed, 13 May 2020 17:26:29 -0300 Message-Id: <20200513202630.2123238-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> References: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-16.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" To accomplish it a per-thread static buffer is used for unknown errnos and the resulting message is not translated (this is already covered by strerror_l). The buffer allocation uses the same strategy of strsignal. Its size should cover both the generic and Hurd requirements (although Hurd could use more extensive _Static_assert to check if all its subsystem specific messages would be handled by the buffer size). Checked on x86-64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, and s390x-linux-gnu. --- include/string.h | 1 + manual/errno.texi | 2 +- string/_strerror.c | 80 ++++++++++++++------------- string/strerror.c | 26 +++------ sysdeps/generic/tls_internal-struct.h | 5 ++ sysdeps/mach/_strerror.c | 48 +++++++++++----- 6 files changed, 91 insertions(+), 71 deletions(-) diff --git a/include/string.h b/include/string.h index 24a61bcff7..3c784be997 100644 --- a/include/string.h +++ b/include/string.h @@ -49,6 +49,7 @@ extern void __bzero (void *__s, size_t __n) __THROW __nonnull ((1)); extern int __ffs (int __i) __attribute__ ((const)); extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen); +extern char *__strerror_lookup (int errnum) attribute_hidden; /* Called as part of the thread shutdown sequence. */ void __strsignal_thread_freeres (void) attribute_hidden; diff --git a/manual/errno.texi b/manual/errno.texi index 8cb4ce8b48..dbb0c4a66d 100644 --- a/manual/errno.texi +++ b/manual/errno.texi @@ -1147,7 +1147,7 @@ name of the program that encountered the error. @deftypefun {char *} strerror (int @var{errnum}) @standards{ISO, string.h} -@safety{@prelim{}@mtunsafe{@mtasurace{:strerror}}@asunsafe{@ascuheap{} @ascuintl{}}@acunsafe{@acsmem{}}} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} @c Calls strerror_r with a static buffer allocated with malloc on the @c first use. The @code{strerror} function maps the error code (@pxref{Checking for diff --git a/string/_strerror.c b/string/_strerror.c index 985fd4e3c6..f6a0b89b38 100644 --- a/string/_strerror.c +++ b/string/_strerror.c @@ -15,60 +15,64 @@ License along with the GNU C Library; if not, see . */ -#include -#include #include -#include #include +#include +#include #include -#include <_itoa.h> +#include + +#define UNK_ERR_STR "Unknown error " +_Static_assert (sizeof (UNK_ERR_STR) <= strerror_str_len, + UNK_ERR_STR " > strerror_str_len"); -/* It is critical here that we always use the `dcgettext' function for - the message translation. Since only defines the macro - `dgettext' to use `dcgettext' for optimizing programs this is not - always guaranteed. */ -#ifndef dgettext -# include /* We need LC_MESSAGES. */ -# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES) -#endif +char * +__strerror_lookup (int errnum) +{ + if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal)) + return NULL; + return (char *) _sys_errlist_internal[errnum]; +} /* Return a string describing the errno code in ERRNUM. */ char * __strerror_r (int errnum, char *buf, size_t buflen) { - if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL)) - { - /* Buffer we use to print the number in. For a maximum size for - `int' of 8 bytes we never need more than 20 digits. */ - char numbuf[21]; - const char *unk = _("Unknown error "); - size_t unklen = strlen (unk); - char *p, *q; - bool negative = errnum < 0; + char *r = __strerror_lookup (errnum); + if (r != NULL) + return r; - numbuf[20] = '\0'; - p = _itoa_word (abs (errnum), &numbuf[20], 10, 0); + const size_t unklen = array_length (UNK_ERR_STR) - 1; + char *q = __mempcpy (buf, UNK_ERR_STR, MIN (buflen, unklen)); + if (unklen < buflen) + { + char numstr[INT_STRLEN_BOUND (int) + 1]; + size_t numstrlen = 1; - /* Now construct the result while taking care for the destination - buffer size. */ - q = __mempcpy (buf, unk, MIN (unklen, buflen)); - if (negative && unklen < buflen) + char *p = numstr; + long int errn = errnum; + if (errnum < 0) { - *q++ = '-'; - ++unklen; + *p++ = '-'; + errn = labs (errnum); + numstrlen++; } - if (unklen < buflen) - memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen)); + for (long int d = errn; p++, (d /= 10) != 0; ) + continue; + *p = '\0'; + for (long int d = errn; + *--p = '0' + d % 10, (d /= 10) != 0; + numstrlen++) + continue; - /* Terminate the string in any case. */ - if (buflen > 0) - buf[buflen - 1] = '\0'; - - return buf; + memcpy (q, numstr, MIN (MIN (numstrlen, INT_STRLEN_BOUND (int)) + 1, + buflen - unklen)); } - return (char *) _(_sys_errlist_internal[errnum]); + if (buflen > 0) + buf[buflen - 1] = '\0'; + + return buf; } weak_alias (__strerror_r, strerror_r) libc_hidden_def (__strerror_r) diff --git a/string/strerror.c b/string/strerror.c index 283ab70f91..4c6f88c682 100644 --- a/string/strerror.c +++ b/string/strerror.c @@ -15,29 +15,17 @@ License along with the GNU C Library; if not, see . */ -#include -#include #include -#include - -/* Return a string describing the errno code in ERRNUM. - The storage is good only until the next call to strerror. - Writing to the storage causes undefined behavior. */ -libc_freeres_ptr (static char *buf); +#include char * strerror (int errnum) { - char *ret = __strerror_r (errnum, NULL, 0); - int saved_errno; - - if (__glibc_likely (ret != NULL)) + char *ret = __strerror_lookup (errnum); + if (ret != NULL) return ret; - saved_errno = errno; - if (buf == NULL) - buf = malloc (1024); - __set_errno (saved_errno); - if (buf == NULL) - return _("Unknown error"); - return __strerror_r (errnum, buf, 1024); + + char *buffer = __glibc_tls_internal ()->strerror_buf; + __strerror_r (errnum, buffer, TLS_INTERNAL_STRERROR_LEN); + return buffer; } diff --git a/sysdeps/generic/tls_internal-struct.h b/sysdeps/generic/tls_internal-struct.h index ca235a93db..4416228757 100644 --- a/sysdeps/generic/tls_internal-struct.h +++ b/sysdeps/generic/tls_internal-struct.h @@ -22,12 +22,17 @@ #include enum { strsignal_str_len = 20 }; +enum { strerror_str_len = 37 }; struct tls_internal_t { /* Used on strsignal.c. */ char strsignal_buf[strsignal_str_len + INT_STRLEN_BOUND (int) + 1]; char *strsignal_l_buf; + char strerror_buf[strerror_str_len + INT_STRLEN_BOUND (int) + 1]; }; +#define TLS_INTERNAL_STRERROR_LEN \ + sizeof ((struct tls_internal_t){0}.strerror_buf) + #endif diff --git a/sysdeps/mach/_strerror.c b/sysdeps/mach/_strerror.c index d932b1bd58..f3969b576f 100644 --- a/sysdeps/mach/_strerror.c +++ b/sysdeps/mach/_strerror.c @@ -15,22 +15,45 @@ License along with the GNU C Library; if not, see . */ -#include #include #include #include #include #include #include <_itoa.h> +#include -/* It is critical here that we always use the `dcgettext' function for - the message translation. Since only defines the macro - `dgettext' to use `dcgettext' for optimizing programs this is not - always guaranteed. */ -#ifndef dgettext -# include /* We need LC_MESSAGES. */ -# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES) -#endif +#define UNK_SYSTEM_ERR_STR "Error in unknown error system: " +_Static_assert (sizeof (UNK_SYSTEM_ERR_STR) <= strerror_str_len, + UNK_SYSTEM_ERR_STR " > strerror_str_len"); +#define UNK_SUBSYSTEM_ERR_STR "Unknown error " +_Static_assert (sizeof (UNK_SUBSYSTEM_ERR_STR) <= strerror_str_len, + UNK_SUBSYSTEM_ERR_STR " > strerror_str_len"); + +extern void __mach_error_map_compat (int *); + +char * +__strerror_lookup (int errnum) +{ + __mach_error_map_compat (&errnum); + + int system = err_get_system (errnum); + int sub = err_get_sub (errnum); + int code = err_get_code (errnum); + + if (system > err_max_system || ! __mach_error_systems[system].bad_sub) + return NULL; + + const struct error_system *es = &__mach_error_systems[system]; + + if (sub >= es->max_sub) + return (char *) es->bad_sub; + + if (code >= es->subsystem[sub].max_code) + return NULL; + + return (char *) es->subsystem[sub].codes[code]; +} /* Return a string describing the errno code in ERRNUM. */ char * @@ -40,7 +63,6 @@ __strerror_r (int errnum, char *buf, size_t buflen) int sub; int code; const struct error_system *es; - extern void __mach_error_map_compat (int *); __mach_error_map_compat (&errnum); @@ -53,7 +75,7 @@ __strerror_r (int errnum, char *buf, size_t buflen) /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; - const char *unk = _("Error in unknown error system: "); + const char *unk = UNK_SYSTEM_ERR_STR; const size_t unklen = strlen (unk); char *p, *q; @@ -83,7 +105,7 @@ __strerror_r (int errnum, char *buf, size_t buflen) /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; - const char *unk = _("Unknown error "); + const char *unk = UNK_SUBSYSTEM_ERR_STR; const size_t unklen = strlen (unk); char *p, *q; size_t len = strlen (es->subsystem[sub].subsys_name); @@ -114,7 +136,7 @@ __strerror_r (int errnum, char *buf, size_t buflen) return buf; } - return (char *) _(es->subsystem[sub].codes[code]); + return (char *) es->subsystem[sub].codes[code]; } libc_hidden_def (__strerror_r) weak_alias (__strerror_r, strerror_r) From patchwork Wed May 13 20:26:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 39241 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3DAD13959C9D; Wed, 13 May 2020 20:26:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3DAD13959C9D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1589401605; bh=BEYj6xZPD8mCKBU9QHp4F6EeDlRcYTm2uiO7Snmu/YI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=HNY3OyBjfCB3TamNXt97KiyOD+enMHCf19+So0SoNoTlPuxtTYAUvHxF/N8JIRGJs maRWlEnMcyGKT/6YeDBbYgWYx7U+KSry6SsIPiB1VVEjnG1IrJo2cVqYXCFT2om0Sl n70RAx5oznQ4x/fMPM9d0iKWnNn+bdt+0DgqTIEw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x734.google.com (mail-qk1-x734.google.com [IPv6:2607:f8b0:4864:20::734]) by sourceware.org (Postfix) with ESMTPS id EF71E3945C1B for ; Wed, 13 May 2020 20:26:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EF71E3945C1B Received: by mail-qk1-x734.google.com with SMTP id n14so729832qke.8 for ; Wed, 13 May 2020 13:26:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BEYj6xZPD8mCKBU9QHp4F6EeDlRcYTm2uiO7Snmu/YI=; b=AkTAOH1gW3ROuZwscjFOkjcJSm1VV/rUSpkw07OX6+23Hz3Of0uS5bzUMNdENFnZHO YXkWjrNxsjPYNvZjODZlLk4Mh401IuwMkB7McahRZoVulvazeKzAPgowzVSx7FNWdc6c EScSwBvbWUIhVVMncMamAjMkMT56ZYvnr43ja7a37clqgAqgUJnpD8Jxpmwrp0qJW2AF RIvhav3XgUGPydvPBZmGniu04AqUQg9qw2v8UqnWpMUPpjmS+H6zFIm8XWtm7f67JOyx D/OF+Kh8T9zcqRfUxuXUOlzOdnyBm85ulNhZhG5g+Ny6tpWRhBeCKLN+XFOb3vpB/aRF cquw== X-Gm-Message-State: AOAM533+CvXPW60RI6CQ7L0hWI4dMvK8oy5vxrh2/KSAn12Y0YzjIOnQ EXNb21VepbD/NELMVt/OkzINRV4Dkec= X-Google-Smtp-Source: ABdhPJyGqQUTfCpQc6w+siSOWogJCPMPjYNmxWvQ3iVUzTCo2xmWucr4t46caa9m15PlcL/jsz/pCw== X-Received: by 2002:a05:620a:1366:: with SMTP id d6mr1572945qkl.114.1589401601157; Wed, 13 May 2020 13:26:41 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id 62sm806465qkh.113.2020.05.13.13.26.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2020 13:26:40 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [RFC 4/4] string: Move strerror_l pointer to tls_internal.h Date: Wed, 13 May 2020 17:26:30 -0300 Message-Id: <20200513202630.2123238-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> References: <20200513202630.2123238-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, UNWANTED_LANGUAGE_BODY autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Similar to strsignal_l, move the per-thread message pointer to tls_internal.h (which on Linux is allocated on struct per-thread). Checked on x86-64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, and s390x-linux-gnu. --- string/strerror_l.c | 34 ++++++++++++--------------- sysdeps/generic/tls_internal-struct.h | 1 + sysdeps/mach/strerror_l.c | 24 +++++++++---------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/string/strerror_l.c b/string/strerror_l.c index 40e7d0e896..baa489dd90 100644 --- a/string/strerror_l.c +++ b/string/strerror_l.c @@ -15,15 +15,11 @@ License along with the GNU C Library; if not, see . */ +#include #include #include -#include -#include #include -#include -#include - -static __thread char *last_value; +#include static const char * @@ -40,23 +36,23 @@ translate (const char *str, locale_t loc) char * strerror_l (int errnum, locale_t loc) { - if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL)) - { - free (last_value); - if (__asprintf (&last_value, "%s%d", - translate ("Unknown error ", loc), errnum) == -1) - last_value = NULL; - - return last_value; - } - - return (char *) translate (_sys_errlist_internal[errnum], loc); + char *r = __strerror_lookup (errnum); + if (r != NULL) + return (char *) translate (r, loc); + + struct tls_internal_t *tls_internal = __glibc_tls_internal (); + free (tls_internal->strerror_l_buf); + if (__asprintf (&tls_internal->strerror_l_buf, "%s%d", + translate ("Unknown error ", loc), errnum) == -1) + tls_internal->strerror_l_buf = NULL; + + return tls_internal->strerror_l_buf; } void __strerror_thread_freeres (void) { - free (last_value); + free (__glibc_tls_internal()->strerror_l_buf); } text_set_element (__libc_subfreeres, __strerror_thread_freeres); + diff --git a/sysdeps/generic/tls_internal-struct.h b/sysdeps/generic/tls_internal-struct.h index 4416228757..a5ae278f81 100644 --- a/sysdeps/generic/tls_internal-struct.h +++ b/sysdeps/generic/tls_internal-struct.h @@ -30,6 +30,7 @@ struct tls_internal_t char strsignal_buf[strsignal_str_len + INT_STRLEN_BOUND (int) + 1]; char *strsignal_l_buf; char strerror_buf[strerror_str_len + INT_STRLEN_BOUND (int) + 1]; + char *strerror_l_buf; }; #define TLS_INTERNAL_STRERROR_LEN \ diff --git a/sysdeps/mach/strerror_l.c b/sysdeps/mach/strerror_l.c index f514af341e..d6a69c3784 100644 --- a/sysdeps/mach/strerror_l.c +++ b/sysdeps/mach/strerror_l.c @@ -24,10 +24,7 @@ #include #include #include -#include - - -static __thread char *last_value; +#include static const char * @@ -56,15 +53,16 @@ strerror_l (int errnum, locale_t loc) sub = err_get_sub (errnum); code = err_get_code (errnum); + struct tls_internal_t *tls_internal = __glibc_tls_internal (); if (system > err_max_system || ! __mach_error_systems[system].bad_sub) { - free (last_value); - if (__asprintf (&last_value, "%s%X", + free (tls_internal->strerror_l_buf); + if (__asprintf (&tls_internal->strerror_l_buf, "%s%X", translate ("Error in unknown error system: ", loc), errnum) == -1) - last_value = NULL; + tls_internal->strerror_l_buf = NULL; - return last_value; + return tls_internal->strerror_l_buf; } es = &__mach_error_systems[system]; @@ -74,14 +72,14 @@ strerror_l (int errnum, locale_t loc) if (code >= es->subsystem[sub].max_code) { - free (last_value); - if (__asprintf (&last_value, "%s%s %d", + free (tls_internal->strerror_l_buf); + if (__asprintf (&tls_internal->strerror_l_buf, "%s%s %d", translate ("Unknown error ", loc), translate (es->subsystem[sub].subsys_name, loc), errnum) == -1) - last_value = NULL; + tls_internal->strerror_l_buf = NULL; - return last_value; + return tls_internal->strerror_l_buf; } return (char *) translate (es->subsystem[sub].codes[code], loc); @@ -91,6 +89,6 @@ strerror_l (int errnum, locale_t loc) void __strerror_thread_freeres (void) { - free (last_value); + free (__glibc_tls_internal()->strerror_l_buf); } text_set_element (__libc_subfreeres, __strerror_thread_freeres);