mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
Merge bitcoin/bitcoin#22365: guix: Avoid relying on newer symbols by rebasing our cross toolchains on older glibcs
647f7e5f1d
guix: Also sort SHA256SUMS.part (Carl Dong)dc4137a60c
guix: Build depends/qt with our platform definition (Carl Dong)16b0a936e1
guix: Rebase toolchain on glibc 2.24 (2.27 for riscv64) (Carl Dong) Pull request description: After this PR, we'll have the following: - riscv64 -> build with a toolchain targeting glibc 2.27 - everything else -> builds with a toolchain targeting glibc 2.24, but will not have symbols > 2.17 (checked by `symbol-check.py`) ACKs for top commit: achow101: reACK647f7e5f1d
hebasto: ACK647f7e5f1d
MarcoFalke: review ACK647f7e5f1d
fanquake: ACK647f7e5f1d
- documentation can be fixed shortly. Tree-SHA512: ddff57a5d7c053687b0a273720d4ad7d28c6fc8816226d4304869284d017af5e3630d4b57565d91e74f2e1b7583c9c83ee8b2e5e70e41d619ab618e602c97a94
This commit is contained in:
commit
2711559845
8 changed files with 522 additions and 2 deletions
|
@ -214,6 +214,7 @@ make -C depends --jobs="$JOBS" HOST="$HOST" \
|
|||
x86_64_linux_NM=x86_64-linux-gnu-nm \
|
||||
x86_64_linux_STRIP=x86_64-linux-gnu-strip \
|
||||
qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \
|
||||
qt_config_opts_x86_64_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \
|
||||
FORCE_USE_SYSTEM_CLANG=1
|
||||
|
||||
|
||||
|
@ -445,5 +446,6 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
|
|||
find "$ACTUAL_OUTDIR" -type f
|
||||
} | xargs realpath --relative-base="$PWD" \
|
||||
| xargs sha256sum \
|
||||
| sort -k2 \
|
||||
| sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part
|
||||
)
|
||||
|
|
|
@ -108,5 +108,6 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
|
|||
find "$ACTUAL_OUTDIR" -type f
|
||||
} | xargs realpath --relative-base="$PWD" \
|
||||
| xargs sha256sum \
|
||||
| sort -k2 \
|
||||
| sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part
|
||||
)
|
||||
|
|
|
@ -135,11 +135,25 @@ chain for " target " development."))
|
|||
(package-with-extra-patches gcc-8
|
||||
(search-our-patches "gcc-8-sort-libtool-find-output.patch")))
|
||||
|
||||
;; Building glibc with stack smashing protector first landed in glibc 2.25, use
|
||||
;; this function to disable for older glibcs
|
||||
;;
|
||||
;; From glibc 2.25 changelog:
|
||||
;;
|
||||
;; * Most of glibc can now be built with the stack smashing protector enabled.
|
||||
;; It is recommended to build glibc with --enable-stack-protector=strong.
|
||||
;; Implemented by Nick Alcock (Oracle).
|
||||
(define (make-glibc-without-ssp xglibc)
|
||||
(package-with-extra-configure-variable
|
||||
(package-with-extra-configure-variable
|
||||
xglibc "libc_cv_ssp" "no")
|
||||
"libc_cv_ssp_strong" "no"))
|
||||
|
||||
(define* (make-bitcoin-cross-toolchain target
|
||||
#:key
|
||||
(base-gcc-for-libc gcc-7)
|
||||
(base-kernel-headers linux-libre-headers-5.4)
|
||||
(base-libc glibc) ; glibc 2.31
|
||||
(base-libc (make-glibc-without-ssp glibc-2.24))
|
||||
(base-gcc (make-gcc-rpath-link base-gcc)))
|
||||
"Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values
|
||||
desirable for building Bitcoin Core release binaries."
|
||||
|
@ -557,6 +571,28 @@ and endian independent.")
|
|||
inspecting signatures in Mach-O binaries.")
|
||||
(license license:expat))))
|
||||
|
||||
(define-public glibc-2.24
|
||||
(package
|
||||
(inherit glibc)
|
||||
(version "2.24")
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://sourceware.org/git/glibc.git")
|
||||
(commit "0d7f1ed30969886c8dde62fbf7d2c79967d4bace")))
|
||||
(file-name (git-file-name "glibc" "0d7f1ed30969886c8dde62fbf7d2c79967d4bace"))
|
||||
(sha256
|
||||
(base32
|
||||
"0g5hryia5v1k0qx97qffgwzrz4lr4jw3s5kj04yllhswsxyjbic3"))
|
||||
(patches (search-our-patches "glibc-ldd-x86_64.patch"
|
||||
"glibc-versioned-locpath.patch"
|
||||
"glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch"
|
||||
"glibc-2.24-no-build-time-cxx-header-run.patch"))))))
|
||||
|
||||
(define glibc-2.27/bitcoin-patched
|
||||
(package-with-extra-patches glibc-2.27
|
||||
(search-our-patches "glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch")))
|
||||
|
||||
(packages->manifest
|
||||
(append
|
||||
(list ;; The Basics
|
||||
|
@ -606,7 +642,10 @@ inspecting signatures in Mach-O binaries.")
|
|||
(make-nsis-with-sde-support nsis-x86_64)
|
||||
osslsigncode))
|
||||
((string-contains target "-linux-")
|
||||
(list (make-bitcoin-cross-toolchain target)))
|
||||
(list (cond ((string-contains target "riscv64-")
|
||||
(make-bitcoin-cross-toolchain target #:base-libc glibc-2.27/bitcoin-patched))
|
||||
(else
|
||||
(make-bitcoin-cross-toolchain target)))))
|
||||
((string-contains target "darwin")
|
||||
(list clang-toolchain-10 binutils imagemagick libtiff librsvg font-tuffy cmake xorriso python-signapple))
|
||||
(else '())))))
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
commit 6b02af31e9a721bb15a11380cd22d53b621711f8
|
||||
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Wed Oct 18 17:26:23 2017 +0100
|
||||
|
||||
[AARCH64] Rewrite elf_machine_load_address using _DYNAMIC symbol
|
||||
|
||||
This patch rewrites aarch64 elf_machine_load_address to use special _DYNAMIC
|
||||
symbol instead of _dl_start.
|
||||
|
||||
The static address of _DYNAMIC symbol is stored in the first GOT entry.
|
||||
Here is the change which makes this solution work (part of binutils 2.24):
|
||||
https://sourceware.org/ml/binutils/2013-06/msg00248.html
|
||||
|
||||
i386, x86_64 targets use the same method to do this as well.
|
||||
|
||||
The original implementation relies on a trick that R_AARCH64_ABS32 relocation
|
||||
being resolved at link time and the static address fits in the 32bits.
|
||||
However, in LP64, normally, the address is defined to be 64 bit.
|
||||
|
||||
Here is the C version one which should be portable in all cases.
|
||||
|
||||
* sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use
|
||||
_DYNAMIC symbol to calculate load address.
|
||||
|
||||
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
|
||||
index e86d8b5b63..5a5b8a5de5 100644
|
||||
--- a/sysdeps/aarch64/dl-machine.h
|
||||
+++ b/sysdeps/aarch64/dl-machine.h
|
||||
@@ -49,26 +49,11 @@ elf_machine_load_address (void)
|
||||
/* To figure out the load address we use the definition that for any symbol:
|
||||
dynamic_addr(symbol) = static_addr(symbol) + load_addr
|
||||
|
||||
- The choice of symbol is arbitrary. The static address we obtain
|
||||
- by constructing a non GOT reference to the symbol, the dynamic
|
||||
- address of the symbol we compute using adrp/add to compute the
|
||||
- symbol's address relative to the PC.
|
||||
- This depends on 32bit relocations being resolved at link time
|
||||
- and that the static address fits in the 32bits. */
|
||||
-
|
||||
- ElfW(Addr) static_addr;
|
||||
- ElfW(Addr) dynamic_addr;
|
||||
-
|
||||
- asm (" \n"
|
||||
-" adrp %1, _dl_start; \n"
|
||||
-" add %1, %1, #:lo12:_dl_start \n"
|
||||
-" ldr %w0, 1f \n"
|
||||
-" b 2f \n"
|
||||
-"1: \n"
|
||||
-" .word _dl_start \n"
|
||||
-"2: \n"
|
||||
- : "=r" (static_addr), "=r" (dynamic_addr));
|
||||
- return dynamic_addr - static_addr;
|
||||
+ _DYNAMIC sysmbol is used here as its link-time address stored in
|
||||
+ the special unrelocated first GOT entry. */
|
||||
+
|
||||
+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
|
||||
+ return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
|
||||
}
|
||||
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
|
@ -0,0 +1,98 @@
|
|||
commit dc23a45db566095e83ff0b7a57afc87fb5ca89a1
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Sep 21 10:45:32 2016 +0200
|
||||
|
||||
Avoid running $(CXX) during build to obtain header file paths
|
||||
|
||||
This reduces the build time somewhat and is particularly noticeable
|
||||
during rebuilds with few code changes.
|
||||
|
||||
diff --git a/Makerules b/Makerules
|
||||
index 7e4077ee50..c338850de5 100644
|
||||
--- a/Makerules
|
||||
+++ b/Makerules
|
||||
@@ -121,14 +121,10 @@ ifneq (,$(CXX))
|
||||
# will be used instead of /usr/include/stdlib.h and /usr/include/math.h.
|
||||
before-compile := $(common-objpfx)cstdlib $(common-objpfx)cmath \
|
||||
$(before-compile)
|
||||
-cstdlib=$(shell echo "\#include <cstdlib>" | $(CXX) -M -MP -x c++ - \
|
||||
- | sed -n "/cstdlib:/{s/:$$//;p}")
|
||||
-$(common-objpfx)cstdlib: $(cstdlib)
|
||||
+$(common-objpfx)cstdlib: $(c++-cstdlib-header)
|
||||
$(INSTALL_DATA) $< $@T
|
||||
$(move-if-change) $@T $@
|
||||
-cmath=$(shell echo "\#include <cmath>" | $(CXX) -M -MP -x c++ - \
|
||||
- | sed -n "/cmath:/{s/:$$//;p}")
|
||||
-$(common-objpfx)cmath: $(cmath)
|
||||
+$(common-objpfx)cmath: $(c++-cmath-header)
|
||||
$(INSTALL_DATA) $< $@T
|
||||
$(move-if-change) $@T $@
|
||||
endif
|
||||
diff --git a/config.make.in b/config.make.in
|
||||
index 95c6f36876..04a8b3ed7f 100644
|
||||
--- a/config.make.in
|
||||
+++ b/config.make.in
|
||||
@@ -45,6 +45,8 @@ defines = @DEFINES@
|
||||
sysheaders = @sysheaders@
|
||||
sysincludes = @SYSINCLUDES@
|
||||
c++-sysincludes = @CXX_SYSINCLUDES@
|
||||
+c++-cstdlib-header = @CXX_CSTDLIB_HEADER@
|
||||
+c++-cmath-header = @CXX_CMATH_HEADER@
|
||||
all-warnings = @all_warnings@
|
||||
enable-werror = @enable_werror@
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 17625e1041..6ff252744b 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -635,6 +635,8 @@ BISON
|
||||
INSTALL_INFO
|
||||
PERL
|
||||
BASH_SHELL
|
||||
+CXX_CMATH_HEADER
|
||||
+CXX_CSTDLIB_HEADER
|
||||
CXX_SYSINCLUDES
|
||||
SYSINCLUDES
|
||||
AUTOCONF
|
||||
@@ -5054,6 +5056,18 @@ fi
|
||||
|
||||
|
||||
|
||||
+# Obtain some C++ header file paths. This is used to make a local
|
||||
+# copy of those headers in Makerules.
|
||||
+if test -n "$CXX"; then
|
||||
+ find_cxx_header () {
|
||||
+ echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}"
|
||||
+ }
|
||||
+ CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)"
|
||||
+ CXX_CMATH_HEADER="$(find_cxx_header cmath)"
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
# Test if LD_LIBRARY_PATH contains the notation for the current directory
|
||||
# since this would lead to problems installing/building glibc.
|
||||
# LD_LIBRARY_PATH contains the current directory if one of the following
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 33bcd62180..9938ab0dc2 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1039,6 +1039,18 @@ fi
|
||||
AC_SUBST(SYSINCLUDES)
|
||||
AC_SUBST(CXX_SYSINCLUDES)
|
||||
|
||||
+# Obtain some C++ header file paths. This is used to make a local
|
||||
+# copy of those headers in Makerules.
|
||||
+if test -n "$CXX"; then
|
||||
+ find_cxx_header () {
|
||||
+ echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}"
|
||||
+ }
|
||||
+ CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)"
|
||||
+ CXX_CMATH_HEADER="$(find_cxx_header cmath)"
|
||||
+fi
|
||||
+AC_SUBST(CXX_CSTDLIB_HEADER)
|
||||
+AC_SUBST(CXX_CMATH_HEADER)
|
||||
+
|
||||
# Test if LD_LIBRARY_PATH contains the notation for the current directory
|
||||
# since this would lead to problems installing/building glibc.
|
||||
# LD_LIBRARY_PATH contains the current directory if one of the following
|
|
@ -0,0 +1,70 @@
|
|||
From 562c52cc81a4e456a62e6455feb32732049e9070 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Mon, 31 Dec 2018 09:26:42 -0800
|
||||
Subject: [PATCH] riscv: Use __has_include__ to include <asm/syscalls.h> [BZ
|
||||
#24022]
|
||||
|
||||
<asm/syscalls.h> has been removed by
|
||||
|
||||
commit 27f8899d6002e11a6e2d995e29b8deab5aa9cc25
|
||||
Author: David Abdurachmanov <david.abdurachmanov@gmail.com>
|
||||
Date: Thu Nov 8 20:02:39 2018 +0100
|
||||
|
||||
riscv: add asm/unistd.h UAPI header
|
||||
|
||||
Marcin Juszkiewicz reported issues while generating syscall table for riscv
|
||||
using 4.20-rc1. The patch refactors our unistd.h files to match some other
|
||||
architectures.
|
||||
|
||||
- Add asm/unistd.h UAPI header, which has __ARCH_WANT_NEW_STAT only for 64-bit
|
||||
- Remove asm/syscalls.h UAPI header and merge to asm/unistd.h
|
||||
- Adjust kernel asm/unistd.h
|
||||
|
||||
So now asm/unistd.h UAPI header should show all syscalls for riscv.
|
||||
|
||||
<asm/syscalls.h> may be restored by
|
||||
|
||||
Subject: [PATCH] riscv: restore asm/syscalls.h UAPI header
|
||||
Date: Tue, 11 Dec 2018 09:09:35 +0100
|
||||
|
||||
UAPI header asm/syscalls.h was merged into UAPI asm/unistd.h header,
|
||||
which did resolve issue with missing syscalls macros resulting in
|
||||
glibc (2.28) build failure. It also broke glibc in a different way:
|
||||
asm/syscalls.h is being used by glibc. I noticed this while doing
|
||||
Fedora 30/Rawhide mass rebuild.
|
||||
|
||||
The patch returns asm/syscalls.h header and incl. it into asm/unistd.h.
|
||||
I plan to send a patch to glibc to use asm/unistd.h instead of
|
||||
asm/syscalls.h
|
||||
|
||||
In the meantime, we use __has_include__, which was added to GCC 5, to
|
||||
check if <asm/syscalls.h> exists before including it. Tested with
|
||||
build-many-glibcs.py for riscv against kernel 4.19.12 and 4.20-rc7.
|
||||
|
||||
[BZ #24022]
|
||||
* sysdeps/unix/sysv/linux/riscv/flush-icache.c: Check if
|
||||
<asm/syscalls.h> exists with __has_include__ before including it.
|
||||
---
|
||||
sysdeps/unix/sysv/linux/riscv/flush-icache.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
|
||||
index d612ef4c6c..0b2042620b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/flush-icache.c
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
|
||||
@@ -21,7 +21,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <atomic.h>
|
||||
#include <sys/cachectl.h>
|
||||
-#include <asm/syscalls.h>
|
||||
+#if __has_include__ (<asm/syscalls.h>)
|
||||
+# include <asm/syscalls.h>
|
||||
+#else
|
||||
+# include <asm/unistd.h>
|
||||
+#endif
|
||||
|
||||
typedef int (*func_type) (void *, void *, unsigned long int);
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
10
contrib/guix/patches/glibc-ldd-x86_64.patch
Normal file
10
contrib/guix/patches/glibc-ldd-x86_64.patch
Normal file
|
@ -0,0 +1,10 @@
|
|||
By default, 'RTDLLIST' in 'ldd' refers to 'lib64/ld-linux-x86-64.so', whereas
|
||||
it's in 'lib/' for us. This patch fixes that.
|
||||
|
||||
--- glibc-2.17/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed 2012-12-25 04:02:13.000000000 +0100
|
||||
+++ glibc-2.17/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed 2013-09-15 23:08:03.000000000 +0200
|
||||
@@ -1,3 +1,3 @@
|
||||
/LD_TRACE_LOADED_OBJECTS=1/a\
|
||||
add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
|
||||
-s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \264\4-x86-64\6 \2x32\4-x32\6"_
|
||||
+s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \2\4-x86-64\6 \2x32\4-x32\6"_
|
240
contrib/guix/patches/glibc-versioned-locpath.patch
Normal file
240
contrib/guix/patches/glibc-versioned-locpath.patch
Normal file
|
@ -0,0 +1,240 @@
|
|||
The format of locale data can be incompatible between libc versions, and
|
||||
loading incompatible data can lead to 'setlocale' returning EINVAL at best
|
||||
or triggering an assertion failure at worst. See
|
||||
https://lists.gnu.org/archive/html/guix-devel/2015-09/msg00717.html
|
||||
for background information.
|
||||
|
||||
To address that, this patch changes libc to honor a new 'GUIX_LOCPATH'
|
||||
variable, and to look for locale data in version-specific sub-directories of
|
||||
that variable. So, if GUIX_LOCPATH=/foo:/bar, locale data is searched for in
|
||||
/foo/X.Y and /bar/X.Y, where X.Y is the libc version number.
|
||||
|
||||
That way, a single 'GUIX_LOCPATH' setting can work even if different libc
|
||||
versions coexist on the system.
|
||||
|
||||
--- a/locale/newlocale.c
|
||||
+++ b/locale/newlocale.c
|
||||
@@ -30,6 +30,7 @@
|
||||
/* Lock for protecting global data. */
|
||||
__libc_rwlock_define (extern , __libc_setlocale_lock attribute_hidden)
|
||||
|
||||
+extern error_t compute_locale_search_path (char **, size_t *);
|
||||
|
||||
/* Use this when we come along an error. */
|
||||
#define ERROR_RETURN \
|
||||
@@ -48,7 +49,6 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
|
||||
__locale_t result_ptr;
|
||||
char *locale_path;
|
||||
size_t locale_path_len;
|
||||
- const char *locpath_var;
|
||||
int cnt;
|
||||
size_t names_len;
|
||||
|
||||
@@ -102,17 +102,8 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
|
||||
locale_path = NULL;
|
||||
locale_path_len = 0;
|
||||
|
||||
- locpath_var = getenv ("LOCPATH");
|
||||
- if (locpath_var != NULL && locpath_var[0] != '\0')
|
||||
- {
|
||||
- if (__argz_create_sep (locpath_var, ':',
|
||||
- &locale_path, &locale_path_len) != 0)
|
||||
- return NULL;
|
||||
-
|
||||
- if (__argz_add_sep (&locale_path, &locale_path_len,
|
||||
- _nl_default_locale_path, ':') != 0)
|
||||
- return NULL;
|
||||
- }
|
||||
+ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
|
||||
+ return NULL;
|
||||
|
||||
/* Get the names for the locales we are interested in. We either
|
||||
allow a composite name or a single name. */
|
||||
diff --git a/locale/setlocale.c b/locale/setlocale.c
|
||||
index ead030d..0c0e314 100644
|
||||
--- a/locale/setlocale.c
|
||||
+++ b/locale/setlocale.c
|
||||
@@ -215,12 +215,65 @@ setdata (int category, struct __locale_data *data)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Return in *LOCALE_PATH and *LOCALE_PATH_LEN the locale data search path as
|
||||
+ a colon-separated list. Return ENOMEN on error, zero otherwise. */
|
||||
+error_t
|
||||
+compute_locale_search_path (char **locale_path, size_t *locale_path_len)
|
||||
+{
|
||||
+ char* guix_locpath_var = getenv ("GUIX_LOCPATH");
|
||||
+ char *locpath_var = getenv ("LOCPATH");
|
||||
+
|
||||
+ if (guix_locpath_var != NULL && guix_locpath_var[0] != '\0')
|
||||
+ {
|
||||
+ /* Entries in 'GUIX_LOCPATH' take precedence over 'LOCPATH'. These
|
||||
+ entries are systematically prefixed with "/X.Y" where "X.Y" is the
|
||||
+ libc version. */
|
||||
+ if (__argz_create_sep (guix_locpath_var, ':',
|
||||
+ locale_path, locale_path_len) != 0
|
||||
+ || __argz_suffix_entries (locale_path, locale_path_len,
|
||||
+ "/" VERSION) != 0)
|
||||
+ goto bail_out;
|
||||
+ }
|
||||
+
|
||||
+ if (locpath_var != NULL && locpath_var[0] != '\0')
|
||||
+ {
|
||||
+ char *reg_locale_path = NULL;
|
||||
+ size_t reg_locale_path_len = 0;
|
||||
+
|
||||
+ if (__argz_create_sep (locpath_var, ':',
|
||||
+ ®_locale_path, ®_locale_path_len) != 0)
|
||||
+ goto bail_out;
|
||||
+
|
||||
+ if (__argz_append (locale_path, locale_path_len,
|
||||
+ reg_locale_path, reg_locale_path_len) != 0)
|
||||
+ goto bail_out;
|
||||
+
|
||||
+ free (reg_locale_path);
|
||||
+ }
|
||||
+
|
||||
+ if (*locale_path != NULL)
|
||||
+ {
|
||||
+ /* Append the system default locale directory. */
|
||||
+ if (__argz_add_sep (locale_path, locale_path_len,
|
||||
+ _nl_default_locale_path, ':') != 0)
|
||||
+ goto bail_out;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ bail_out:
|
||||
+ free (*locale_path);
|
||||
+ *locale_path = NULL;
|
||||
+ *locale_path_len = 0;
|
||||
+
|
||||
+ return ENOMEM;
|
||||
+}
|
||||
+
|
||||
char *
|
||||
setlocale (int category, const char *locale)
|
||||
{
|
||||
char *locale_path;
|
||||
size_t locale_path_len;
|
||||
- const char *locpath_var;
|
||||
char *composite;
|
||||
|
||||
/* Sanity check for CATEGORY argument. */
|
||||
@@ -251,17 +304,10 @@ setlocale (int category, const char *locale)
|
||||
locale_path = NULL;
|
||||
locale_path_len = 0;
|
||||
|
||||
- locpath_var = getenv ("LOCPATH");
|
||||
- if (locpath_var != NULL && locpath_var[0] != '\0')
|
||||
+ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
|
||||
{
|
||||
- if (__argz_create_sep (locpath_var, ':',
|
||||
- &locale_path, &locale_path_len) != 0
|
||||
- || __argz_add_sep (&locale_path, &locale_path_len,
|
||||
- _nl_default_locale_path, ':') != 0)
|
||||
- {
|
||||
- __libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
- return NULL;
|
||||
- }
|
||||
+ __libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
if (category == LC_ALL)
|
||||
diff --git a/string/Makefile b/string/Makefile
|
||||
index 8424a61..f925503 100644
|
||||
--- a/string/Makefile
|
||||
+++ b/string/Makefile
|
||||
@@ -38,7 +38,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
|
||||
swab strfry memfrob memmem rawmemchr strchrnul \
|
||||
$(addprefix argz-,append count create ctsep next \
|
||||
delete extract insert stringify \
|
||||
- addsep replace) \
|
||||
+ addsep replace suffix) \
|
||||
envz basename \
|
||||
strcoll_l strxfrm_l string-inlines memrchr \
|
||||
xpg-strerror strerror_l
|
||||
diff --git a/string/argz-suffix.c b/string/argz-suffix.c
|
||||
new file mode 100644
|
||||
index 0000000..505b0f2
|
||||
--- /dev/null
|
||||
+++ b/string/argz-suffix.c
|
||||
@@ -0,0 +1,56 @@
|
||||
+/* Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Ludovic Courtès <ludo@gnu.org>.
|
||||
+
|
||||
+ 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 <argz.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+
|
||||
+error_t
|
||||
+__argz_suffix_entries (char **argz, size_t *argz_len, const char *suffix)
|
||||
+
|
||||
+{
|
||||
+ size_t suffix_len = strlen (suffix);
|
||||
+ size_t count = __argz_count (*argz, *argz_len);
|
||||
+ size_t new_argz_len = *argz_len + count * suffix_len;
|
||||
+ char *new_argz = malloc (new_argz_len);
|
||||
+
|
||||
+ if (new_argz)
|
||||
+ {
|
||||
+ char *p = new_argz, *entry;
|
||||
+
|
||||
+ for (entry = *argz;
|
||||
+ entry != NULL;
|
||||
+ entry = argz_next (*argz, *argz_len, entry))
|
||||
+ {
|
||||
+ p = stpcpy (p, entry);
|
||||
+ p = stpcpy (p, suffix);
|
||||
+ p++;
|
||||
+ }
|
||||
+
|
||||
+ free (*argz);
|
||||
+ *argz = new_argz;
|
||||
+ *argz_len = new_argz_len;
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ return ENOMEM;
|
||||
+}
|
||||
+weak_alias (__argz_suffix_entries, argz_suffix_entries)
|
||||
diff --git a/string/argz.h b/string/argz.h
|
||||
index bb62a31..d276a35 100644
|
||||
--- a/string/argz.h
|
||||
+++ b/string/argz.h
|
||||
@@ -134,6 +134,16 @@ extern error_t argz_replace (char **__restrict __argz,
|
||||
const char *__restrict __str,
|
||||
const char *__restrict __with,
|
||||
unsigned int *__restrict __replace_count);
|
||||
+
|
||||
+/* Suffix each entry of ARGZ & ARGZ_LEN with SUFFIX. Return 0 on success,
|
||||
+ and ENOMEN if memory cannot be allocated. */
|
||||
+extern error_t __argz_suffix_entries (char **__restrict __argz,
|
||||
+ size_t *__restrict __argz_len,
|
||||
+ const char *__restrict __suffix);
|
||||
+extern error_t argz_suffix_entries (char **__restrict __argz,
|
||||
+ size_t *__restrict __argz_len,
|
||||
+ const char *__restrict __suffix);
|
||||
+
|
||||
|
||||
/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
|
||||
are no more. If entry is NULL, then the first entry is returned. This
|
Loading…
Add table
Reference in a new issue