diff --git a/Makeconfig b/Makeconfig
index 522182abdc..2bde0276ce 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -153,6 +153,11 @@ libdir = $(exec_prefix)/lib
endif
inst_libdir = $(install_root)$(libdir)
+# Compat places to look for libraries
+ifndef extra_libdir
+extra_libdir = /lib:$(exec_prefix)/lib
+endif
+
# Where to install the shared library.
ifndef slibdir
slibdir = $(exec_prefix)/lib
@@ -635,6 +640,10 @@ else
default-rpath = $(libdir)
endif
+ifdef extra_libdir
+default-rpath += :$(extra_libdir)
+endif
+
ifndef link-extra-libs
link-extra-libs = $(LDLIBS-$(@F))
link-extra-libs-static = $(link-extra-libs)
diff --git a/Makefile b/Makefile
index 2e351c0321..7c7e18b1df 100644
--- a/Makefile
+++ b/Makefile
@@ -448,6 +448,14 @@ $(inst_includedir)/gnu/stubs.h: $(+force)
install-others-nosubdir: $(installed-stubs)
endif
+# If we're bootstrapping, install a dummy gnu/stubs.h along with the
+# other headers, so 'make install-headers' produces a useable include
+# tree. Otherwise, install gnu/stubs.h later, after the rest of the
+# build is done.
+ifeq ($(install-bootstrap-headers),yes)
+install-headers: $(inst_includedir)/gnu/stubs.h $(installed-stubs) \
+ $(inst_includedir)/$(lib-names-h-abi)
+endif
# Since stubs.h is never needed when building the library, we simplify the
# hairy installation process by producing it in place only as the last part
@@ -455,6 +463,14 @@ endif
# iterates over all the subdirs; subdir_install in each subdir depends on
# the subdir's stubs file. Having more direct dependencies would result in
# extra iterations over the list for subdirs and many recursive makes.
+ifeq ($(install-bootstrap-headers),yes)
+# gnu/stubs.h depends (via the subdir 'stubs' targets) on all the .o
+# files in GLIBC. For bootstrapping a GCC/GLIBC pair, an empty
+# gnu/stubs.h is good enough.
+$(installed-stubs): include/stubs-bootstrap.h $(+force)
+ $(make-target-directory)
+ $(INSTALL_DATA) $< $@
+else
$(installed-stubs): include/stubs-prologue.h subdir_install
$(make-target-directory)
@rm -f $(objpfx)stubs.h
@@ -463,6 +479,7 @@ $(installed-stubs): include/stubs-prologue.h subdir_install
then echo 'stubs.h unchanged'; \
else $(INSTALL_DATA) $(objpfx)stubs.h $@; fi
rm -f $(objpfx)stubs.h
+endif
# This makes the Info or DVI file of the documentation from the Texinfo source.
.PHONY: info dvi pdf html
@@ -658,7 +675,7 @@ endif
# Setting INSTALL_UNCOMPRESSED causes localedata/Makefile to
# install the charmaps uncompressed, as the testroot does not
# provide a gunzip program.
- $(MAKE) install DESTDIR=$(objpfx)testroot.pristine \
+ $(MAKE) install install_root=$(objpfx)testroot.pristine \
INSTALL_UNCOMPRESSED=yes subdirs='$(sorted-subdirs)'
rm -f $(symbolic-link-list)
touch $(objpfx)testroot.pristine/install.stamp
diff --git a/Makerules b/Makerules
index 00365bc58b..de43396b34 100644
--- a/Makerules
+++ b/Makerules
@@ -1016,6 +1016,9 @@ $(inst_libdir)/libc.so: $(common-objpfx)format.lds \
'$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
' AS_NEEDED (' $(rtlddir)/$(rtld-installed-name) ') )' \
) > $@.new
+ifeq ($(patsubst gnu%,,$(config-os)),)
+ echo 'INPUT ( AS_NEEDED ( -lmachuser -lhurduser ) )' >> $@.new
+endif
mv -f $@.new $@
endif
diff --git a/NEWS b/NEWS
index 1b89f9c010..610aa5e923 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,90 @@ See the end for copying conditions.
Please send GNU C library bug reports via
using `glibc' in the "product" field.
+Version 2.39.1
+
+Deprecated and removed features, and other changes affecting compatibility:
+
+* __rseq_size now denotes the size of the active rseq area (20 bytes
+ initially), not the size of struct rseq (32 bytes initially).
+
+Security related changes:
+
+The following CVEs were fixed in this release:
+
+ GLIBC-SA-2024-0004:
+ ISO-2022-CN-EXT: fix out-of-bound writes when writing escape
+ sequence (CVE-2024-2961)
+
+ GLIBC-SA-2024-0005:
+ nscd: Stack-based buffer overflow in netgroup cache (CVE-2024-33599)
+
+ GLIBC-SA-2024-0006:
+ nscd: Null pointer crash after notfound response (CVE-2024-33600)
+
+ GLIBC-SA-2024-0007:
+ nscd: netgroup cache may terminate daemon on memory allocation
+ failure (CVE-2024-33601)
+
+ GLIBC-SA-2024-0008:
+ nscd: netgroup cache assumes NSS callback uses in-buffer strings
+ (CVE-2024-33602)
+
+The following bugs are resolved with this release:
+
+ [19622] network: Support aliasing with struct sockaddr
+ [30081] resolv: Do not wait for non-existing second DNS response after error
+ [30701] time: getutxent misbehaves on 32-bit x86 when _TIME_BITS=64
+ [30994] REP MOVSB performance suffers from page aliasing on Zen 4
+ [31339] libc: arm32 loader crash after cleanup in 2.36
+ [31325] mips: clone3 is wrong for o32
+ [31335] math: Compile glibc with -march=x86-64-v3 should disable FMA4
+ multi-arch version
+ [31402] libc: clone (NULL, NULL, ...) clobbers %r7 register on
+ s390{,x}
+ [31479] libc: Missing #include in sched_getcpu.c may
+ result in a loss of rseq acceleration
+ [31316] build: Fails test misc/tst-dirname "Didn't expect signal from
+ child: got `Illegal instruction'" on non SSE CPUs
+ [31371] x86-64: APX and Tile registers aren't preserved in ld.so
+ trampoline
+ [31372] dynamic-link: _dl_tlsdesc_dynamic doesn't preserve all caller-
+ saved registers
+ [31429] build: Glibc failed to build with -march=x86-64-v3
+ [31476] resolv: Track single-request fallback via _res._flags
+ [31501] dynamic-link: _dl_tlsdesc_dynamic_xsavec may clobber %rbx
+ [31612] libc: arc4random fails to fallback to /dev/urandom if
+ getrandom is not present
+ [31640] dynamic-link: POWER10 ld.so crashes in
+ elf_machine_load_address with GCC 14
+ [31676] Configuring with CC="gcc -march=x86-64-v3"
+ --with-rtld-early-cflags=-march=x86-64 results in linker failure
+ [31677] nscd: nscd: netgroup cache: invalid memcpy under low
+ memory/storage conditions
+ [31678] nscd: nscd: Null pointer dereferences after failed netgroup
+ cache insertion
+ [31679] nscd: nscd: netgroup cache may terminate daemon on memory
+ allocation failure
+ [31680] nscd: nscd: netgroup cache assumes NSS callback uses in-buffer
+ strings
+ [31686] dynamic-link: Stack-based buffer overflow in
+ parse_tunables_string
+ [31695] libc: pidfd_spawn/pidfd_spawnp leak an fd if clone3 succeeds
+ [31719] dynamic-link: --enable-hardcoded-path-in-tests doesn't work
+ with -Wl,--enable-new-dtags
+ [31782] Test build failure with recent GCC trunk
+ (x86/tst-cpu-features-supports.c:69:3: error: parameter to builtin
+ not valid: avx5124fmaps)
+ [31798] pidfd_getpid.c is miscompiled by GCC 6.4
+ [31867] build: "CPU ISA level is lower than required" on SSE2-free
+ CPUs
+ [31883] build: ISA level support configure check relies on bashism /
+ is otherwise broken for arithmetic
+ [31890] resolv: Allow short error responses to match any DNS query
+ [31965] rseq extension mechanism does not work as intended
+ [31968] mremap implementation in C does not handle arguments correctly
+ [32052] Name space violation in fortify wrappers
+
Version 2.39
Major new features:
diff --git a/assert/assert.h b/assert/assert.h
index 266a41df06..8c1cb5fd37 100644
--- a/assert/assert.h
+++ b/assert/assert.h
@@ -61,6 +61,8 @@
#else /* Not NDEBUG. */
+#ifndef _ASSERT_H_DECLS
+#define _ASSERT_H_DECLS
__BEGIN_DECLS
/* This prints an "Assertion failed" message and aborts. */
@@ -81,6 +83,7 @@ extern void __assert (const char *__assertion, const char *__file, int __line)
__END_DECLS
+#endif /* Not _ASSERT_H_DECLS */
/* When possible, define assert so that it does not add extra
parentheses around EXPR. Otherwise, those added parentheses would
diff --git a/bits/socket.h b/bits/socket.h
index 13de124bac..772074d52a 100644
--- a/bits/socket.h
+++ b/bits/socket.h
@@ -149,7 +149,7 @@ enum __socket_type
#include
/* Structure describing a generic socket address. */
-struct sockaddr
+struct __attribute_struct_may_alias__ sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
@@ -166,7 +166,7 @@ struct sockaddr
#define _SS_PADSIZE \
(_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
-struct sockaddr_storage
+struct __attribute_struct_may_alias__ sockaddr_storage
{
__SOCKADDR_COMMON (ss_); /* Address family, etc. */
char __ss_padding[_SS_PADSIZE];
diff --git a/config.h.in b/config.h.in
index 1e647de585..3b936655e9 100644
--- a/config.h.in
+++ b/config.h.in
@@ -162,6 +162,9 @@
/* Mach/i386 specific: define if the `i386_set_gdt' RPC is available. */
#undef HAVE_I386_SET_GDT
+/* Hurd specific; define if the `proc_getchildren_rusage' RPC is available. */
+#undef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+
/* Define if inlined system calls are available. */
#undef HAVE_INLINED_SYSCALLS
diff --git a/elf/Makefile b/elf/Makefile
index a50a988e73..3a5ec6aafc 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1366,7 +1366,7 @@ $(objpfx)trusted-dirs.st: Makefile $(..)Makeconfig
$(make-target-directory)
echo "$(subst :, ,$(default-rpath) $(user-defined-trusted-dirs))" \
| $(AWK) -f gen-trusted-dirs.awk > ${@:st=T};
- echo '#define DL_DST_LIB "$(notdir $(slibdir))"' >> ${@:st=T}
+ echo '#define DL_DST_LIB "$(shell echo $(slibdir) | sed 's,/,,')"' >> ${@:st=T}
$(move-if-change) ${@:st=T} ${@:st=h}
touch $@
CPPFLAGS-dl-load.c += -I$(objpfx). -I$(csu-objpfx).
@@ -2787,9 +2787,8 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
$(objpfx)tst-ro-dynamic-mod.os
$(objpfx)tst-rtld-list-diagnostics.out: tst-rtld-list-diagnostics.py \
- $(..)manual/dynlink.texi $(objpfx)$(rtld-installed-name)
+ $(objpfx)$(rtld-installed-name)
$(PYTHON) tst-rtld-list-diagnostics.py \
- --manual=$(..)manual/dynlink.texi \
"$(test-wrapper-env) $(objpfx)$(rtld-installed-name) --list-diagnostics" \
> $@; \
$(evaluate-test)
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 08bc1530a8..85f3f179ed 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -390,52 +390,6 @@ _dl_cache_libcmp (const char *p1, const char *p2)
return *p1 - *p2;
}
-/* Special value representing the lack of an ld.so cache. */
-static const char ld_so_cache_lacking[] = "/ld.so cache is lacking";
-
-/* Return the per-application ld.so cache, relative to $ORIGIN, or NULL if
- that fails for some reason. Do not return the system-wide LD_SO_CACHE
- since on a foreign distro it would contain invalid information. */
-static const char *
-ld_so_cache (void)
-{
- static const char *loader_cache;
-
- if (loader_cache == NULL)
- {
- static const char store[] = @STORE_DIRECTORY@;
- const char *origin = _dl_get_origin ();
-
- /* Check whether ORIGIN is something like "/gnu/store/…-foo/bin". */
- if (origin != (char *) -1 /* _dl_get_origin reported failure */
- && strncmp (store, origin, strlen (store)) == 0
- && origin[sizeof store - 1] == '/')
- {
- char *store_item_end = strchr (origin + sizeof store, '/');
-
- if (store_item_end != NULL)
- {
- static const char suffix[] = "/etc/ld.so.cache";
- size_t store_item_len = store_item_end - origin;
-
- /* Note: We can't use 'malloc' because it can be interposed.
- Likewise, 'strncpy' is not available. */
- char *cache = alloca (strlen (origin) + sizeof suffix);
-
- strcpy (cache, origin);
- strcpy (cache + store_item_len, suffix);
-
- loader_cache = __strdup (cache) ?: ld_so_cache_lacking;
- }
- else
- loader_cache = ld_so_cache_lacking;
- }
- else
- loader_cache = ld_so_cache_lacking;
- }
-
- return loader_cache;
-}
/* Look up NAME in ld.so.cache and return the file name stored there, or null
if none is found. The cache is loaded if it was not already. If loading
@@ -449,15 +403,12 @@ _dl_load_cache_lookup (const char *name)
{
/* Print a message if the loading of libs is traced. */
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
- _dl_debug_printf (" search cache=%s\n", ld_so_cache ());
-
- if (__glibc_unlikely (ld_so_cache () == ld_so_cache_lacking))
- return NULL;
+ _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
if (cache == NULL)
{
/* Read the contents of the file. */
- void *file = _dl_sysdep_read_whole_file (ld_so_cache (), &cachesize,
+ void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize,
PROT_READ);
/* We can handle three different cache file formats here:
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 5835506d3f..6fcd96d2ae 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1700,6 +1700,25 @@ open_verify (const char *name, int fd,
__set_errno (ENOENT);
return -1;
}
+#ifdef __arm__
+ else if (!VALID_FLOAT_ABI (ehdr->e_flags))
+ {
+ /* This is not a fatal error. On architectures where
+ soft-float and hard-float binaries can be run this
+ might happen. */
+ __close_nocancel (fd);
+ __set_errno (ENOENT);
+ return -1;
+ }
+#endif
+ else if (! __builtin_expect (elf_machine_matches_host (ehdr), 1))
+ {
+ /* Another non-fatal error, let's skip right past the
+ the libraries obviously built for other machines. */
+ __close_nocancel (fd);
+ __set_errno (ENOENT);
+ return -1;
+ }
else if (ehdr->e_ident[EI_DATA] != byteorder)
{
if (BYTE_ORDER == BIG_ENDIAN)
@@ -2083,6 +2102,28 @@ _dl_map_object (struct link_map *loader, const char *name,
loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
LA_SER_LIBPATH, &found_other_class);
+ /* Look at the RUNPATH information for this binary. */
+ if (fd == -1 && loader != NULL
+ && cache_rpath (loader, &loader->l_runpath_dirs,
+ DT_RUNPATH, "RUNPATH"))
+ fd = open_path (name, namelen, mode,
+ &loader->l_runpath_dirs, &realname, &fb, loader,
+ LA_SER_RUNPATH, &found_other_class);
+
+ if (fd == -1)
+ {
+ realname = _dl_sysdep_open_object (name, namelen, &fd);
+ if (realname != NULL)
+ {
+ fd = open_verify (realname, fd,
+ &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+ LA_SER_CONFIG, mode, &found_other_class,
+ false);
+ if (fd == -1)
+ free (realname);
+ }
+ }
+
#ifdef USE_LDCONFIG
if (fd == -1
&& (__glibc_likely ((mode & __RTLD_SECURE) == 0)
@@ -2141,28 +2182,6 @@ _dl_map_object (struct link_map *loader, const char *name,
}
#endif
- /* Look at the RUNPATH information for this binary. */
- if (fd == -1 && loader != NULL
- && cache_rpath (loader, &loader->l_runpath_dirs,
- DT_RUNPATH, "RUNPATH"))
- fd = open_path (name, namelen, mode,
- &loader->l_runpath_dirs, &realname, &fb, loader,
- LA_SER_RUNPATH, &found_other_class);
-
- if (fd == -1)
- {
- realname = _dl_sysdep_open_object (name, namelen, &fd);
- if (realname != NULL)
- {
- fd = open_verify (realname, fd,
- &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
- LA_SER_CONFIG, mode, &found_other_class,
- false);
- if (fd == -1)
- free (realname);
- }
- }
-
/* Finally, try the default path. */
if (fd == -1
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 7b3dd9ab60..670dbc42fc 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -819,7 +819,14 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
dtv entry free it. Note: this is not AS-safe. */
/* XXX Ideally we will at some point create a memory
pool. */
- free (dtv[modid].pointer.to_free);
+ /* Avoid calling free on a null pointer. Some mallocs
+ incorrectly use dynamic TLS, and depending on how the
+ free function was compiled, it could call
+ __tls_get_addr before the null pointer check in the
+ free implementation. Checking here papers over at
+ least some dynamic TLS usage by interposed mallocs. */
+ if (dtv[modid].pointer.to_free != NULL)
+ free (dtv[modid].pointer.to_free);
dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
dtv[modid].pointer.to_free = NULL;
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index b64c54b53e..560ff052e0 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -55,6 +55,17 @@
#define PACKAGE _libc_intl_domainname
+/* Get the generated information about the trusted/standard directories. */
+#include "trusted-dirs.h"
+
+static const char system_dirs[] = SYSTEM_DIRS;
+static const size_t system_dirs_len[] =
+{
+ SYSTEM_DIRS_LEN
+};
+#define nsystem_dirs_len \
+ (sizeof (system_dirs_len) / sizeof (system_dirs_len[0]))
+
/* List of directories to handle. */
struct dir_entry
{
@@ -448,6 +459,25 @@ chroot_stat (const char *real_path, const char *path, struct stat *st)
return ret;
}
+static const char * const ld_sonames[] =
+{
+ "ld-kfreebsd-x86-64.so.1",
+ "ld-linux-aarch64.so.1",
+ "ld-linux-aarch64_be.so.1",
+ "ld-linux-armhf.so.3",
+ "ld-linux-ia64.so.2",
+ "ld-linux-mipsn8.so.1",
+ "ld-linux-riscv64-lp64.so.1"
+ "ld-linux-riscv64-lp64d.so.1"
+ "ld-linux-x32.so.2",
+ "ld-linux-x86-64.so.2",
+ "ld-linux.so.2",
+ "ld-linux.so.3",
+ "ld.so.1",
+ "ld64.so.1",
+ "ld64.so.2",
+};
+
/* Create a symbolic link from soname to libname in directory path. */
static void
create_links (const char *real_path, const char *path, const char *libname,
@@ -458,6 +488,7 @@ create_links (const char *real_path, const char *path, const char *libname,
struct stat stat_lib, stat_so, lstat_so;
int do_link = 1;
int do_remove = 1;
+ int i;
/* XXX: The logics in this function should be simplified. */
/* Get complete path. */
@@ -486,6 +517,18 @@ create_links (const char *real_path, const char *path, const char *libname,
error (0, 0, _("Can't stat %s\n"), full_libname);
return;
}
+
+ /* Do not change the symlink pointer to the dynamic linker except for
+ non-existing symlinks, as it might break multiarch systems. */
+ for (i = 0; i < sizeof (ld_sonames) / sizeof (ld_sonames[0]); i++)
+ if (__glibc_unlikely(!strcmp(soname, ld_sonames[i])))
+ {
+ if (opt_verbose)
+ error (0, 0, _("%s is the dynamic linker, ignoring\n"),
+ full_libname);
+ do_link = 0;
+ }
+
if (stat_lib.st_dev == stat_so.st_dev
&& stat_lib.st_ino == stat_so.st_ino)
/* Link is already correct. */
@@ -1296,12 +1339,19 @@ main (int argc, char **argv)
if (!opt_only_cline)
{
+ const char *strp = system_dirs;
+ size_t idx = 0;
+
parse_conf (config_file, true);
/* Always add the standard search paths. */
- add_system_dir (SLIBDIR);
- if (strcmp (SLIBDIR, LIBDIR))
- add_system_dir (LIBDIR);
+ do
+ {
+ add_system_dir (strp);
+ strp += system_dirs_len[idx] + 1;
+ idx++;
+ }
+ while (idx < nsystem_dirs_len);
}
const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
diff --git a/elf/ldd.bash.in b/elf/ldd.bash.in
index d6b640df66..5dea16a4f4 100644
--- a/elf/ldd.bash.in
+++ b/elf/ldd.bash.in
@@ -150,17 +150,18 @@ for file do
echo "ldd: ${file}:" $"not regular file" >&2
result=1
elif test -r "$file"; then
- test -x "$file" || echo 'ldd:' $"\
-warning: you do not have execution permission for" "\`$file'" >&2
RTLD=
ret=1
for rtld in ${RTLDLIST}; do
if test -x $rtld; then
- verify_out=`${rtld} --verify "$file"`
- ret=$?
- case $ret in
- [02]) RTLD=${rtld}; break;;
- esac
+ dummy=`$rtld --version 2>&1`
+ if test $? = 0; then
+ verify_out=`${rtld} --verify "$file"`
+ ret=$?
+ case $ret in
+ [02]) RTLD=${rtld}; break;;
+ esac
+ fi
fi
done
case $ret in
diff --git a/gmon/gmon.c b/gmon/gmon.c
index 6439ed1caa..402a66de01 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -390,8 +390,11 @@ write_gmon (void)
if (fd == -1)
{
+ do
fd = __open_nocancel ("gmon.out", O_CREAT | O_TRUNC | O_WRONLY
| O_NOFOLLOW | O_CLOEXEC, 0666);
+ while (fd < 0 && errno == EINTR);
+
if (fd < 0)
{
char buf[300];
diff --git a/htl/Versions b/htl/Versions
index 710051756a..02192ad184 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -3,6 +3,16 @@ libc {
GLIBC_2.12 {
pthread_self;
__pthread_self;
+ pthread_attr_getdetachstate;
+ pthread_attr_getinheritsched;
+ pthread_attr_getschedparam;
+ pthread_attr_getschedpolicy;
+ pthread_attr_setdetachstate;
+ pthread_attr_setinheritsched;
+ pthread_attr_setschedpolicy;
+ pthread_equal;
+ pthread_getschedparam;
+ pthread_setschedparam;
}
GLIBC_2.21 {
@@ -38,6 +48,7 @@ libc {
__pthread_cleanup_stack;
__pthread_total;
___pthread_self;
+ __pthread_init_thread;
}
}
diff --git a/hurd/Makefile b/hurd/Makefile
index 7138e3a6ae..8736d56572 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -29,11 +29,11 @@ inline-headers = hurd.h $(addprefix hurd/,fd.h signal.h \
# The RPC interfaces go in a separate library.
interface-library := libhurduser
user-interfaces := $(addprefix hurd/,\
- auth startup \
+ auth auth_request auth_reply startup \
process process_request \
msg msg_reply msg_request \
- exec exec_startup crash interrupt \
- fs fsys io io_reply io_request \
+ exec exec_experimental exec_startup crash interrupt \
+ fs fs_experimental fsys io io_reply io_request \
term tioctl socket ifsock \
login password pfinet pci \
)
@@ -56,6 +56,7 @@ routines = hurdstartup hurdinit \
ports-get ports-set hurdports hurdmsg \
errno-loc \
hurdlock \
+ sysvshm \
$(sig) $(dtable) $(inlines) \
fd-cleanup port-cleanup report-wait xattr
sig = hurdsig hurdfault siginfo hurd-raise preempt-sig \
diff --git a/hurd/Versions b/hurd/Versions
index 439e8abf32..d3410232e7 100644
--- a/hurd/Versions
+++ b/hurd/Versions
@@ -117,6 +117,10 @@ libc {
# functions used in macros & inline functions
__errno_location;
}
+ GLIBC_2.21 {
+ # "quasi-internal" functions
+ _hurd_exec_file_name;
+ }
GLIBC_2.26 {
# "quasi-internal" functions
_hurd_exec_paths;
diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
index 1616c635d5..7bdb4d0ea9 100644
--- a/hurd/hurd/fd.h
+++ b/hurd/hurd/fd.h
@@ -300,8 +300,6 @@ __hurd_at_flags (int *at_flags, int *flags)
*flags &= ~O_NOLINK;
*at_flags &= ~AT_SYMLINK_FOLLOW;
- if (*at_flags & AT_NO_AUTOMOUNT)
- *flags |= O_NOTRANS;
*at_flags &= ~AT_NO_AUTOMOUNT;
if (*at_flags != 0)
diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
index 3178f70075..3da2df83bb 100644
--- a/hurd/hurdexec.c
+++ b/hurd/hurdexec.c
@@ -25,9 +25,12 @@
#include
#include
#include
+#include
#include
#include
+#include
+
/* Overlay TASK, executing FILE with arguments ARGV and environment ENVP.
If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
ARGV and ENVP are terminated by NULL pointers.
@@ -39,6 +42,13 @@ _hurd_exec (task_t task, file_t file,
return _hurd_exec_paths (task, file, NULL, NULL, argv, envp);
}
+error_t
+__hurd_exec_file_name (task_t task, file_t file, const char *filename,
+ char *const argv[], char *const envp[])
+{
+ return _hurd_exec_paths (task, file, filename, filename, argv, envp);
+}
+
link_warning (_hurd_exec,
"_hurd_exec is deprecated, use _hurd_exec_paths instead");
@@ -128,7 +138,6 @@ _hurd_exec_paths (task_t task, file_t file,
ss = _hurd_self_sigstate ();
retry:
- assert (! __spin_lock_locked (&ss->critical_section_lock));
__spin_lock (&ss->critical_section_lock);
_hurd_sigstate_lock (ss);
@@ -442,6 +451,18 @@ retry:
portnames, nportnames);
/* Fall back for backwards compatibility. This can just be removed
when __file_exec goes away. */
+ if (err == MIG_BAD_ID)
+ err = __file_exec_file_name (file, task, flags,
+ path ? path : "",
+ args, argslen, env, envlen,
+ dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
+ ports, MACH_MSG_TYPE_COPY_SEND,
+ _hurd_nports,
+ ints, INIT_INT_MAX,
+ please_dealloc, pdp - please_dealloc,
+ portnames, nportnames);
+ /* Fall back for backwards compatibility. This can just be removed
+ when __file_exec goes away. */
if (err == MIG_BAD_ID)
err = __file_exec (file, task, flags,
args, argslen, env, envlen,
@@ -490,3 +511,9 @@ retry:
return err;
}
libc_hidden_def (_hurd_exec_paths)
+extern error_t _hurd_exec_file_name (task_t task,
+ file_t file,
+ const char *filename,
+ char *const argv[],
+ char *const envp[]);
+versioned_symbol (libc, __hurd_exec_file_name, _hurd_exec_file_name, GLIBC_2_21);
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 882a03471d..1d732508f4 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -1611,28 +1611,53 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
static void
reauth_proc (mach_port_t new)
{
- mach_port_t ref, ignore;
+ error_t err;
+ mach_port_t ref, newproc;
ref = __mach_reply_port ();
- if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
+ err = HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
__proc_reauthenticate (port, ref,
- MACH_MSG_TYPE_MAKE_SEND)
- || __auth_user_authenticate (new, ref,
- MACH_MSG_TYPE_MAKE_SEND,
- &ignore))
- && ignore != MACH_PORT_NULL)
- __mach_port_deallocate (__mach_task_self (), ignore);
+ MACH_MSG_TYPE_MAKE_SEND));
+ if (err)
+ {
+ __mach_port_destroy (__mach_task_self (), ref);
+ return;
+ }
+
+ err = __auth_user_authenticate (new, ref,
+ MACH_MSG_TYPE_MAKE_SEND,
+ &newproc);
__mach_port_destroy (__mach_task_self (), ref);
+ if (err)
+ return;
+
+ if (newproc == MACH_PORT_NULL)
+ {
+ /* Old versions of the proc server did not recreate the process
+ port when reauthenticating, and passed MACH_PORT_NULL through
+ the auth server. That must be what we're dealing with. */
+
+ /* Set the owner of the process here too. */
+ __mutex_lock (&_hurd_id.lock);
+ if (!_hurd_check_ids ())
+ HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
+ __proc_setowner (port,
+ (_hurd_id.gen.nuids
+ ? _hurd_id.gen.uids[0] : 0),
+ !_hurd_id.gen.nuids));
+ __mutex_unlock (&_hurd_id.lock);
+
+ return;
+ }
+
+ err = __proc_reauthenticate_complete (newproc);
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), newproc);
+ return;
+ }
- /* Set the owner of the process here too. */
- __mutex_lock (&_hurd_id.lock);
- if (!_hurd_check_ids ())
- HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
- __proc_setowner (port,
- (_hurd_id.gen.nuids
- ? _hurd_id.gen.uids[0] : 0),
- !_hurd_id.gen.nuids));
- __mutex_unlock (&_hurd_id.lock);
+ _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], newproc);
(void) &reauth_proc; /* Silence compiler warning. */
}
diff --git a/hurd/sysvshm.c b/hurd/sysvshm.c
new file mode 100644
index 0000000000..8557d68d6c
--- /dev/null
+++ b/hurd/sysvshm.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2005 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Description of an shm attachment. */
+struct sysvshm_attach
+{
+ /* Linked list. */
+ struct sysvshm_attach *next;
+
+ /* Map address. */
+ void *addr;
+
+ /* Map size. */
+ size_t size;
+};
+
+/* List of attachments. */
+static struct sysvshm_attach *attach_list;
+
+/* A lock to protect the linked list of shared memory attachments. */
+static unsigned int sysvshm_lock = LLL_LOCK_INITIALIZER;
+
+
+/* Adds a segment attachment. */
+error_t
+__sysvshm_add (void *addr, size_t size)
+{
+ struct sysvshm_attach *shm;
+
+ shm = malloc (sizeof (*shm));
+ if (!shm)
+ return errno;
+
+ __mutex_lock (&sysvshm_lock);
+ shm->addr = addr;
+ shm->size = size;
+ shm->next = attach_list;
+ attach_list = shm;
+ __mutex_unlock (&sysvshm_lock);
+
+ return 0;
+}
+
+/* Removes a segment attachment. Returns its size if found, or EINVAL
+ otherwise. */
+error_t
+__sysvshm_remove (void *addr, size_t *size)
+{
+ struct sysvshm_attach *shm;
+ struct sysvshm_attach **pshm = &attach_list;
+
+ __mutex_lock (&sysvshm_lock);
+ shm = attach_list;
+ while (shm)
+ {
+ shm = *pshm;
+ if (shm->addr == addr)
+ {
+ *pshm = shm->next;
+ *size = shm->size;
+ __mutex_unlock (&sysvshm_lock);
+ free (shm);
+ return 0;
+ }
+ pshm = &shm->next;
+ shm = shm->next;
+ }
+ __mutex_unlock (&sysvshm_lock);
+ return EINVAL;
+}
diff --git a/hurd/sysvshm.h b/hurd/sysvshm.h
new file mode 100644
index 0000000000..1204db8339
--- /dev/null
+++ b/hurd/sysvshm.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2005 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include
+#include
+
+/* The area (from top to bottom) that is used for private keys. These
+ are all keys that have the second highest bit set. */
+#define SHM_PRIV_KEY_START INT_MAX
+#define SHM_PRIV_KEY_END ((INT_MAX / 2) + 1)
+
+#define SHM_PREFIX "sysvshm-"
+#define SHM_DIR _PATH_DEV "shm/"
+
+/* The maximum number of characters in a shared memory segment file name.
+ 32 is the max number of characters in a 128 bit number in hex. */
+#if __WORDSIZE > 128
+#error Need to increase SHM_NAMEMAX.
+#else
+#define SHM_NAMEMAX (sizeof (SHM_PREFIX) - 1 + 32 + 1)
+#endif
+
+/* Use this with printf and its variants. */
+#define SHM_NAMEPRI SHM_PREFIX "%0x"
+
+
+/* Adds a segment attachment. */
+error_t __sysvshm_add (void *addr, size_t size);
+
+/* Removes a segment attachment. Returns its size if found, or EINVAL
+ otherwise. */
+error_t __sysvshm_remove (void *addr, size_t *size);
diff --git a/hurd/thread-cancel.c b/hurd/thread-cancel.c
index faa923febe..5e3629c97e 100644
--- a/hurd/thread-cancel.c
+++ b/hurd/thread-cancel.c
@@ -42,7 +42,6 @@ hurd_thread_cancel (thread_t thread)
return 0;
}
- assert (! __spin_lock_locked (&ss->critical_section_lock));
__spin_lock (&ss->critical_section_lock);
__spin_lock (&ss->lock);
err = __thread_suspend (thread);
@@ -82,7 +81,6 @@ hurd_check_cancel (void)
int cancel;
__spin_lock (&ss->lock);
- assert (! __spin_lock_locked (&ss->critical_section_lock));
cancel = ss->cancel;
ss->cancel = 0;
__spin_unlock (&ss->lock);
diff --git a/hurd/xattr.c b/hurd/xattr.c
index 0715ad7b02..2d83edf2fe 100644
--- a/hurd/xattr.c
+++ b/hurd/xattr.c
@@ -50,7 +50,15 @@ _hurd_xattr_get (io_t port, const char *name, void *value, size_t *size)
else if (value)
{
if (*size < sizeof st.st_author)
- return ERANGE;
+ {
+ if (*size > 0)
+ return ERANGE;
+ else
+ {
+ *size = sizeof st.st_author;
+ return 0;
+ }
+ }
memcpy (value, &st.st_author, sizeof st.st_author);
}
*size = sizeof st.st_author;
@@ -61,15 +69,33 @@ _hurd_xattr_get (io_t port, const char *name, void *value, size_t *size)
{
char *buf = value;
mach_msg_type_number_t bufsz = value ? *size : 0;
- error_t err = __file_get_translator (port, &buf, &bufsz);
+ struct stat64 st;
+ error_t err;
+
+ err = __io_stat (port, &st);
+ if (err)
+ return err;
+ if ((st.st_mode & S_IPTRANS) == 0)
+ return ENODATA;
+
+ err = __file_get_translator (port, &buf, &bufsz);
if (err)
return err;
- if (value != NULL && *size < bufsz)
+
+ if (*size < bufsz)
{
if (buf != value)
__munmap (buf, bufsz);
- return ERANGE;
+
+ if (*size > 0)
+ return ERANGE;
+ else
+ {
+ *size = bufsz;
+ return 0;
+ }
}
+
if (buf != value && bufsz > 0)
{
if (value != NULL)
@@ -149,10 +175,9 @@ _hurd_xattr_set (io_t port, const char *name, const void *value, size_t size,
if (err)
return err;
if (bufsz > 0)
- {
- __munmap (buf, bufsz);
- return ENODATA;
- }
+ __munmap (buf, bufsz);
+ else
+ return ENODATA;
}
return __file_set_translator (port,
FS_TRANS_SET | ((flags & XATTR_CREATE)
@@ -193,7 +218,7 @@ _hurd_xattr_list (io_t port, void *buffer, size_t *size)
if (st.st_mode & S_IPTRANS)
add ("gnu.translator");
- if (buffer != NULL && total > *size)
+ if (*size > 0 && total > *size)
return ERANGE;
*size = total;
return 0;
diff --git a/include/features.h b/include/features.h
index fc164d332a..19b46d4fdc 100644
--- a/include/features.h
+++ b/include/features.h
@@ -409,10 +409,9 @@
# define __USE_GNU 1
#endif
-#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0
-# if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
-# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
-# elif !__GNUC_PREREQ (4, 1)
+#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \
+ && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
+# if !__GNUC_PREREQ (4, 1)
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
# elif _FORTIFY_SOURCE > 2 && (__glibc_clang_prereq (9, 0) \
|| __GNUC_PREREQ (12, 0))
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index e21bb599b3..e47d071958 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -208,12 +208,12 @@
#define __make_section_unallocated(section_string) \
asm (".section " section_string "\n\t.previous");
-/* Tacking on "\n\t#" to the section name makes gcc put it's bogus
+/* Tacking on "\n#APP\n\t#" to the section name makes gcc put it's bogus
section attributes on what looks like a comment to the assembler. */
#ifdef HAVE_SECTION_QUOTES
-# define __sec_comment "\"\n\t#\""
+# define __sec_comment "\"\n#APP\n\t#\""
#else
-# define __sec_comment "\n\t#"
+# define __sec_comment "\n#APP\n\t#"
#endif
#define link_warning(symbol, msg) \
__make_section_unallocated (".gnu.warning." #symbol) \
diff --git a/include/stubs-bootstrap.h b/include/stubs-bootstrap.h
new file mode 100644
index 0000000000..8d962019e2
--- /dev/null
+++ b/include/stubs-bootstrap.h
@@ -0,0 +1,12 @@
+/* Placeholder stubs.h file for bootstrapping.
+
+ When bootstrapping a GCC/GLIBC pair, GCC requires that the GLIBC
+ headers be installed, but we can't fully build GLIBC without that
+ GCC. So we run the command:
+
+ make install-headers install-bootstrap-headers=yes
+
+ to install the headers GCC needs, but avoid building certain
+ difficult headers. The header depends, via the
+ GLIBC subdir 'stubs' make targets, on every .o file in GLIBC, but
+ an empty stubs.h like this will do fine for GCC. */
diff --git a/include/stubs-prologue.h b/include/stubs-prologue.h
index 0577bc6a5f..cf8eba0165 100644
--- a/include/stubs-prologue.h
+++ b/include/stubs-prologue.h
@@ -8,7 +8,7 @@
every time called, usually setting errno to ENOSYS. */
#ifdef _LIBC
- #error Applications may not define the macro _LIBC
+# error Applications may not define the macro _LIBC
#endif
@ Placeholder line so we remember to keep the preceding blank line here.
diff --git a/inet/netinet/in.h b/inet/netinet/in.h
index fa57b61079..f684be5beb 100644
--- a/inet/netinet/in.h
+++ b/inet/netinet/in.h
@@ -244,7 +244,7 @@ extern const struct in6_addr in6addr_loopback; /* ::1 */
/* Structure describing an Internet socket address. */
-struct sockaddr_in
+struct __attribute_struct_may_alias__ sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
@@ -257,9 +257,11 @@ struct sockaddr_in
- sizeof (struct in_addr)];
};
-#if !__USE_KERNEL_IPV6_DEFS
+#if __USE_KERNEL_IPV6_DEFS
+struct __attribute_struct_may_alias__ sockaddr_in6;
+#else
/* Ditto, for IPv6. */
-struct sockaddr_in6
+struct __attribute_struct_may_alias__ sockaddr_in6
{
__SOCKADDR_COMMON (sin6_);
in_port_t sin6_port; /* Transport layer port # */
diff --git a/intl/locale.alias b/intl/locale.alias
index 4e952d5b72..21baef05be 100644
--- a/intl/locale.alias
+++ b/intl/locale.alias
@@ -43,8 +43,8 @@ danish da_DK.ISO-8859-1
dansk da_DK.ISO-8859-1
deutsch de_DE.ISO-8859-1
dutch nl_NL.ISO-8859-1
-eesti et_EE.ISO-8859-1
-estonian et_EE.ISO-8859-1
+eesti et_EE.ISO-8859-15
+estonian et_EE.ISO-8859-15
finnish fi_FI.ISO-8859-1
french fr_FR.ISO-8859-1
galego gl_ES.ISO-8859-1
@@ -72,7 +72,7 @@ nynorsk nn_NO.ISO-8859-1
polish pl_PL.ISO-8859-2
portuguese pt_PT.ISO-8859-1
romanian ro_RO.ISO-8859-2
-russian ru_RU.ISO-8859-5
+russian ru_RU.KOI8-R
slovak sk_SK.ISO-8859-2
slovene sl_SI.ISO-8859-2
slovenian sl_SI.ISO-8859-2
diff --git a/io/bits/poll2.h b/io/bits/poll2.h
index 6152a8c5e4..efc8b85403 100644
--- a/io/bits/poll2.h
+++ b/io/bits/poll2.h
@@ -43,7 +43,7 @@ poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
#ifdef __USE_GNU
-# ifdef __USE_TIME_BITS64
+# ifdef __USE_TIME64_REDIRECTS
extern int __REDIRECT (__ppoll64_alias, (struct pollfd *__fds, nfds_t __nfds,
const struct timespec *__timeout,
const __sigset_t *__ss), __ppoll64);
diff --git a/io/fcntl.h b/io/fcntl.h
index 9cee0b5900..666b7e5eb6 100644
--- a/io/fcntl.h
+++ b/io/fcntl.h
@@ -172,7 +172,7 @@ typedef __pid_t pid_t;
This function is a cancellation point and therefore not marked with
__THROW. */
-#ifndef __USE_TIME_BITS64
+#ifndef __USE_TIME64_REDIRECTS
# ifndef __USE_FILE_OFFSET64
extern int fcntl (int __fd, int __cmd, ...);
# else
@@ -185,7 +185,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64);
# ifdef __USE_LARGEFILE64
extern int fcntl64 (int __fd, int __cmd, ...);
# endif
-#else /* __USE_TIME_BITS64 */
+#else /* __USE_TIME64_REDIRECTS */
# ifdef __REDIRECT
extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...),
__fcntl_time64);
diff --git a/io/fts.h b/io/fts.h
index 61f95bb441..97a031ebbd 100644
--- a/io/fts.h
+++ b/io/fts.h
@@ -187,7 +187,7 @@ FTSENT *fts_read (FTS *);
int fts_set (FTS *, FTSENT *, int) __THROW;
#else
# ifdef __REDIRECT
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
FTSENT *__REDIRECT (fts_children, (FTS *, int), fts64_children);
int __REDIRECT (fts_close, (FTS *), fts64_close);
FTS *__REDIRECT (fts_open, (char * const *, int,
@@ -206,7 +206,7 @@ int __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int),
__fts64_set_time64);
# endif
# else
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
# define fts_children fts64_children
# define fts_close fts64_close
# define fts_open fts64_open
@@ -217,7 +217,7 @@ int __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int),
# endif
#endif
#ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
FTSENT64 *fts64_children (FTS64 *, int);
int fts64_close (FTS64 *);
FTS64 *fts64_open (char * const *, int,
diff --git a/io/ftw.h b/io/ftw.h
index e4d1b84d53..39cf595b27 100644
--- a/io/ftw.h
+++ b/io/ftw.h
@@ -137,7 +137,7 @@ extern int ftw (const char *__dir, __ftw_func_t __func, int __descriptors)
__nonnull ((1, 2));
#else
# ifdef __REDIRECT
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
int __descriptors), ftw64) __nonnull ((1, 2));
# else
@@ -146,7 +146,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
__nonnull ((1, 2));
# endif
# else
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
# define ftw ftw64
# else
# define ftw __ftw64_time64
@@ -154,7 +154,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
# endif
#endif
#ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int ftw64 (const char *__dir, __ftw64_func_t __func,
int __descriptors) __nonnull ((1, 2));
# else
@@ -180,7 +180,7 @@ extern int nftw (const char *__dir, __nftw_func_t __func, int __descriptors,
int __flag) __nonnull ((1, 2));
# else
# ifdef __REDIRECT
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
int __descriptors, int __flag), nftw64)
__nonnull ((1, 2));
@@ -190,7 +190,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
__nonnull ((1, 2));
# endif
# else
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
# define nftw nftw64
# else
# define nftw __nftw64_time64
@@ -198,7 +198,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
# endif
# endif
# ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int nftw64 (const char *__dir, __nftw64_func_t __func,
int __descriptors, int __flag) __nonnull ((1, 2));
# else
diff --git a/io/sys/poll.h b/io/sys/poll.h
index 7858fad6b9..c324ff5dad 100644
--- a/io/sys/poll.h
+++ b/io/sys/poll.h
@@ -66,7 +66,7 @@ extern int ppoll (struct pollfd *__fds, nfds_t __nfds,
const __sigset_t *__ss)
__fortified_attr_access (__write_only__, 1, 2);
-# ifdef __USE_TIME_BITS64
+# ifdef __USE_TIME64_REDIRECTS
# ifdef __REDIRECT
extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds,
const struct timespec *__timeout,
diff --git a/io/sys/stat.h b/io/sys/stat.h
index 1fa6d6e62e..3b4ba80132 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -209,7 +209,7 @@ extern int stat (const char *__restrict __file,
that file descriptor FD is open on and put them in BUF. */
extern int fstat (int __fd, struct stat *__buf) __THROW __nonnull ((2));
#else
-# ifdef __USE_TIME_BITS64
+# ifdef __USE_TIME64_REDIRECTS
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
struct stat *__restrict __buf),
@@ -236,7 +236,7 @@ extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf), fstat64)
# endif
#endif
#ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int stat64 (const char *__restrict __file,
struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2));
extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
@@ -265,7 +265,7 @@ extern int fstatat (int __fd, const char *__restrict __file,
struct stat *__restrict __buf, int __flag)
__THROW __nonnull ((2, 3));
# else
-# ifdef __USE_TIME_BITS64
+# ifdef __USE_TIME64_REDIRECTS
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
struct stat *__restrict __buf,
@@ -287,7 +287,7 @@ extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
# endif
# ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int fstatat64 (int __fd, const char *__restrict __file,
struct stat64 *__restrict __buf, int __flag)
__THROW __nonnull ((2, 3));
@@ -313,7 +313,7 @@ extern int __REDIRECT_NTH (fstatat64, (int __fd,
extern int lstat (const char *__restrict __file,
struct stat *__restrict __buf) __THROW __nonnull ((1, 2));
# else
-# ifdef __USE_TIME_BITS64
+# ifdef __USE_TIME64_REDIRECTS
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (lstat,
(const char *__restrict __file,
@@ -334,7 +334,7 @@ extern int __REDIRECT_NTH (lstat,
# endif
# endif
# ifdef __USE_LARGEFILE64
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
extern int lstat64 (const char *__restrict __file,
struct stat64 *__restrict __buf)
__THROW __nonnull ((1, 2));
@@ -427,7 +427,7 @@ extern int mkfifoat (int __fd, const char *__path, __mode_t __mode)
#endif
#ifdef __USE_ATFILE
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
/* Set file access and modification times relative to directory file
descriptor. */
extern int utimensat (int __fd, const char *__path,
@@ -447,7 +447,7 @@ extern int __REDIRECT_NTH (utimensat, (int fd, const char *__path,
#endif
#ifdef __USE_XOPEN2K8
-# ifndef __USE_TIME_BITS64
+# ifndef __USE_TIME64_REDIRECTS
/* Set file access and modification times of the file associated with FD. */
extern int futimens (int __fd, const struct timespec __times[2]) __THROW;
diff --git a/io/utime.h b/io/utime.h
index c5eacedd6a..1c7587d9c1 100644
--- a/io/utime.h
+++ b/io/utime.h
@@ -35,7 +35,7 @@ __BEGIN_DECLS
/* Structure describing file times. */
struct utimbuf
{
-#ifdef __USE_TIME_BITS64
+#ifdef __USE_TIME64_REDIRECTS
__time64_t actime; /* Access time. */
__time64_t modtime; /* Modification time. */
#else
@@ -46,7 +46,7 @@ struct utimbuf
/* Set the access and modification times of FILE to those given in
*FILE_TIMES. If FILE_TIMES is NULL, set them to the current time. */
-#ifndef __USE_TIME_BITS64
+#ifndef __USE_TIME64_REDIRECTS
extern int utime (const char *__file,
const struct utimbuf *__file_times)
__THROW __nonnull ((1));
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index f9e8d37610..0dc4e87c65 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -195,24 +195,24 @@ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2)
__nonnull ((3)) char *
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
{
- size_t sz = __glibc_objsize (__s);
- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
+ size_t __sz = __glibc_objsize (__s);
+ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
return __fgets_alias (__s, __n, __stream);
- if (__glibc_unsafe_len (__n, sizeof (char), sz))
- return __fgets_chk_warn (__s, sz, __n, __stream);
- return __fgets_chk (__s, sz, __n, __stream);
+ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
+ return __fgets_chk_warn (__s, __sz, __n, __stream);
+ return __fgets_chk (__s, __sz, __n, __stream);
}
__fortify_function __wur __nonnull ((4)) size_t
fread (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
- size_t sz = __glibc_objsize0 (__ptr);
- if (__glibc_safe_or_unknown_len (__n, __size, sz))
+ size_t __sz = __glibc_objsize0 (__ptr);
+ if (__glibc_safe_or_unknown_len (__n, __size, __sz))
return __fread_alias (__ptr, __size, __n, __stream);
- if (__glibc_unsafe_len (__n, __size, sz))
- return __fread_chk_warn (__ptr, sz, __size, __n, __stream);
- return __fread_chk (__ptr, sz, __size, __n, __stream);
+ if (__glibc_unsafe_len (__n, __size, __sz))
+ return __fread_chk_warn (__ptr, __sz, __size, __n, __stream);
+ return __fread_chk (__ptr, __sz, __size, __n, __stream);
}
#ifdef __USE_GNU
@@ -220,12 +220,12 @@ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2)
__nonnull ((3)) char *
fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
{
- size_t sz = __glibc_objsize (__s);
- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
+ size_t __sz = __glibc_objsize (__s);
+ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
return __fgets_unlocked_alias (__s, __n, __stream);
- if (__glibc_unsafe_len (__n, sizeof (char), sz))
- return __fgets_unlocked_chk_warn (__s, sz, __n, __stream);
- return __fgets_unlocked_chk (__s, sz, __n, __stream);
+ if (__glibc_unsafe_len (__n, sizeof (char), __sz))
+ return __fgets_unlocked_chk_warn (__s, __sz, __n, __stream);
+ return __fgets_unlocked_chk (__s, __sz, __n, __stream);
}
#endif
@@ -235,8 +235,8 @@ __fortify_function __wur __nonnull ((4)) size_t
fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
- size_t sz = __glibc_objsize0 (__ptr);
- if (__glibc_safe_or_unknown_len (__n, __size, sz))
+ size_t __sz = __glibc_objsize0 (__ptr);
+ if (__glibc_safe_or_unknown_len (__n, __size, __sz))
{
# ifdef __USE_EXTERN_INLINES
if (__builtin_constant_p (__size)
@@ -261,9 +261,9 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
# endif
return __fread_unlocked_alias (__ptr, __size, __n, __stream);
}
- if (__glibc_unsafe_len (__n, __size, sz))
- return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream);
- return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream);
+ if (__glibc_unsafe_len (__n, __size, __sz))
+ return __fread_unlocked_chk_warn (__ptr, __sz, __size, __n, __stream);
+ return __fread_unlocked_chk (__ptr, __sz, __size, __n, __stream);
}
#endif
diff --git a/locale/Makefile b/locale/Makefile
index 0da4e1c958..2810f28605 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -160,9 +160,7 @@ localepath = "$(complocaledir):$(i18ndir)"
# -Iprograms doesn't really belong here, but this gets it at the head
# of the list instead of the tail, where CPPFLAGS-$(lib) gets added.
# We need it before the standard -I's to see programs/config.h first.
-# Define 'LOCALEDIR' for use in 'compute_locale_search_path'.
locale-CPPFLAGS = -DCOMPLOCALEDIR='"$(complocaledir)"' \
- -DLOCALEDIR='"$(libdir)/locale"' \
-DLOCALE_ALIAS_PATH='"$(localedir)"' \
-Iprograms
diff --git a/locale/newlocale.c b/locale/newlocale.c
index 538bbac233..6d95e029a0 100644
--- a/locale/newlocale.c
+++ b/locale/newlocale.c
@@ -29,7 +29,6 @@
/* 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,6 +47,7 @@ __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;
@@ -101,8 +101,17 @@ __newlocale (int category_mask, const char *locale, locale_t base)
locale_path = NULL;
locale_path_len = 0;
- if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
- return NULL;
+ 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;
+ }
/* Get the names for the locales we are interested in. We either
allow a composite name or a single name. */
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 5048adbd9f..29731c562f 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -3515,8 +3515,20 @@ error while adding equivalent collating symbol"));
}
else if (arg != NULL)
{
+ void *ptr = NULL;
symstr = arg->val.str.startmb;
symlen = arg->val.str.lenmb;
+ if (state != 5
+ && find_entry (&charmap->char_table, symstr, symlen, &ptr) != 0
+ && (repertoire == NULL ||
+ find_entry (&repertoire->char_table, symstr, symlen, &ptr) != 0)
+ && find_entry (&collate->elem_table, symstr, symlen, &ptr) != 0
+ && find_entry (&collate->sym_table, symstr, symlen, &ptr) != 0)
+ {
+ if (verbose)
+ lr_error (ldfile, _("%s: symbol `%.*s' not known"),
+ "LC_COLLATE", (int) symlen, symstr);
+ }
}
else
{
diff --git a/locale/programs/ld-identification.c b/locale/programs/ld-identification.c
index f4fe40959b..f148593556 100644
--- a/locale/programs/ld-identification.c
+++ b/locale/programs/ld-identification.c
@@ -144,6 +144,9 @@ No definition for %s category found"), "LC_IDENTIFICATION");
#cat); \
identification->cat = ""; \
}
+#define TEST_ELEM_OPT(cat) \
+ if (identification->cat == NULL) \
+ identification->cat = ""; \
TEST_ELEM (title);
TEST_ELEM (source);
@@ -154,9 +157,9 @@ No definition for %s category found"), "LC_IDENTIFICATION");
TEST_ELEM (fax);
TEST_ELEM (language);
TEST_ELEM (territory);
- TEST_ELEM (audience);
- TEST_ELEM (application);
- TEST_ELEM (abbreviation);
+ TEST_ELEM_OPT (audience);
+ TEST_ELEM_OPT (application);
+ TEST_ELEM_OPT (abbreviation);
TEST_ELEM (revision);
TEST_ELEM (date);
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index c7ee1874e8..018e5a54dd 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -797,11 +797,15 @@ static void
show_locale_vars (void)
{
const char *lcall = getenv ("LC_ALL") ?: "";
+ const char *language = getenv ("LANGUAGE") ?: "";
const char *lang = getenv ("LANG") ?: "";
/* LANG has to be the first value. */
print_assignment ("LANG", lang, false);
+ if (getenv ("POSIXLY_CORRECT") == NULL)
+ printf ("LANGUAGE=%s\n", language);
+
/* Now all categories in an unspecified order. */
for (size_t cat_no = 0; cat_no < NCATEGORIES; ++cat_no)
if (cat_no != LC_ALL)
diff --git a/locale/setlocale.c b/locale/setlocale.c
index afaa8b483e..7bd27e5398 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -213,60 +213,12 @@ setdata (int category, struct __locale_data *data)
}
}
-/* Return in *LOCALE_PATH and *LOCALE_PATH_LEN the locale data search path as
- an argz 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_add_sep (locale_path, locale_path_len,
- guix_locpath_var, ':') != 0
- || __argz_suffix_entries (locale_path, locale_path_len,
- "/" VERSION) != 0)
- goto bail_out;
- }
-
- if (locpath_var != NULL && locpath_var[0] != '\0')
- {
- if (__argz_add_sep (locale_path, locale_path_len,
- locpath_var, ':') != 0)
- goto bail_out;
-
- }
-
- /* Append the system default locale directory. */
- if (__argz_add_sep (locale_path, locale_path_len,
- _nl_default_locale_path, ':') != 0)
- goto bail_out;
-
- /* Last, unconditionally append our own locale directory, which should
- contain data for C.UTF-8. */
- if (__argz_add_sep (locale_path, locale_path_len,
- LOCALEDIR "/" VERSION, ':') != 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. */
@@ -297,10 +249,17 @@ setlocale (int category, const char *locale)
locale_path = NULL;
locale_path_len = 0;
- if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
+ locpath_var = getenv ("LOCPATH");
+ if (locpath_var != NULL && locpath_var[0] != '\0')
{
- __libc_rwlock_unlock (__libc_setlocale_lock);
- return NULL;
+ 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;
+ }
}
if (category == LC_ALL)
diff --git a/locale/tst-locale-locpath.sh b/locale/tst-locale-locpath.sh
index 527732953d..b2bd26e55d 100644
--- a/locale/tst-locale-locpath.sh
+++ b/locale/tst-locale-locpath.sh
@@ -54,6 +54,7 @@ EOF
cat > "$testroot/stdout-expected" <> LOCALES; \
- done
- $(make-target-directory)
- $(INSTALL_DATA) LOCALES $@
-
INSTALL-SUPPORTED-LOCALE-ARCHIVE=$(addprefix install-archive-, $(SUPPORTED-LOCALES))
INSTALL-SUPPORTED-LOCALE-FILES=$(addprefix install-files-, $(SUPPORTED-LOCALES))
diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
index a2f3132480..974d91c3d3 100644
--- a/localedata/SUPPORTED
+++ b/localedata/SUPPORTED
@@ -137,9 +137,11 @@ en_BW/ISO-8859-1 \
en_CA.UTF-8/UTF-8 \
en_CA/ISO-8859-1 \
en_DK.UTF-8/UTF-8 \
+en_DK.ISO-8859-15/ISO-8859-15 \
en_DK/ISO-8859-1 \
en_GB.UTF-8/UTF-8 \
en_GB/ISO-8859-1 \
+en_GB.ISO-8859-15/ISO-8859-15 \
en_HK.UTF-8/UTF-8 \
en_HK/ISO-8859-1 \
en_IE.UTF-8/UTF-8 \
@@ -157,6 +159,7 @@ en_SG.UTF-8/UTF-8 \
en_SG/ISO-8859-1 \
en_US.UTF-8/UTF-8 \
en_US/ISO-8859-1 \
+en_US.ISO-8859-15/ISO-8859-15 \
en_ZA.UTF-8/UTF-8 \
en_ZA/ISO-8859-1 \
en_ZM/UTF-8 \
@@ -211,6 +214,9 @@ et_EE.ISO-8859-15/ISO-8859-15 \
eu_ES.UTF-8/UTF-8 \
eu_ES/ISO-8859-1 \
eu_ES@euro/ISO-8859-15 \
+eu_FR.UTF-8/UTF-8 \
+eu_FR/ISO-8859-1 \
+eu_FR@euro/ISO-8859-15 \
fa_IR/UTF-8 \
ff_SN/UTF-8 \
fi_FI.UTF-8/UTF-8 \
@@ -260,8 +266,8 @@ hif_FJ/UTF-8 \
hne_IN/UTF-8 \
hr_HR.UTF-8/UTF-8 \
hr_HR/ISO-8859-2 \
-hsb_DE/ISO-8859-2 \
hsb_DE.UTF-8/UTF-8 \
+hsb_DE/ISO-8859-2 \
ht_HT/UTF-8 \
hu_HU.UTF-8/UTF-8 \
hu_HU/ISO-8859-2 \
@@ -280,19 +286,20 @@ it_IT.UTF-8/UTF-8 \
it_IT/ISO-8859-1 \
it_IT@euro/ISO-8859-15 \
iu_CA/UTF-8 \
-ja_JP.EUC-JP/EUC-JP \
ja_JP.UTF-8/UTF-8 \
+ja_JP.EUC-JP/EUC-JP \
ka_GE.UTF-8/UTF-8 \
ka_GE/GEORGIAN-PS \
kab_DZ/UTF-8 \
kk_KZ.UTF-8/UTF-8 \
kk_KZ/PT154 \
+kk_KZ.RK1048/RK1048 \
kl_GL.UTF-8/UTF-8 \
kl_GL/ISO-8859-1 \
km_KH/UTF-8 \
kn_IN/UTF-8 \
-ko_KR.EUC-KR/EUC-KR \
ko_KR.UTF-8/UTF-8 \
+ko_KR.EUC-KR/EUC-KR \
kok_IN/UTF-8 \
ks_IN/UTF-8 \
ks_IN@devanagari/UTF-8 \
@@ -383,9 +390,10 @@ raj_IN/UTF-8 \
rif_MA/UTF-8 \
ro_RO.UTF-8/UTF-8 \
ro_RO/ISO-8859-2 \
-ru_RU.KOI8-R/KOI8-R \
ru_RU.UTF-8/UTF-8 \
+ru_RU.KOI8-R/KOI8-R \
ru_RU/ISO-8859-5 \
+ru_RU.CP1251/CP1251 \
ru_UA.UTF-8/UTF-8 \
ru_UA/KOI8-U \
rw_RW/UTF-8 \
@@ -429,6 +437,7 @@ sv_FI/ISO-8859-1 \
sv_FI@euro/ISO-8859-15 \
sv_SE.UTF-8/UTF-8 \
sv_SE/ISO-8859-1 \
+sv_SE.ISO-8859-15/ISO-8859-15 \
sw_KE/UTF-8 \
sw_TZ/UTF-8 \
syr/UTF-8 \
@@ -470,9 +479,9 @@ uz_UZ/ISO-8859-1 \
uz_UZ@cyrillic/UTF-8 \
ve_ZA/UTF-8 \
vi_VN/UTF-8 \
+wa_BE.UTF-8/UTF-8 \
wa_BE/ISO-8859-1 \
wa_BE@euro/ISO-8859-15 \
-wa_BE.UTF-8/UTF-8 \
wae_CH/UTF-8 \
wal_ET/UTF-8 \
wo_SN/UTF-8 \
@@ -484,17 +493,17 @@ yo_NG/UTF-8 \
yue_HK/UTF-8 \
yuw_PG/UTF-8 \
zgh_MA/UTF-8 \
+zh_CN.UTF-8/UTF-8 \
zh_CN.GB18030/GB18030 \
zh_CN.GBK/GBK \
-zh_CN.UTF-8/UTF-8 \
zh_CN/GB2312 \
zh_HK.UTF-8/UTF-8 \
zh_HK/BIG5-HKSCS \
zh_SG.UTF-8/UTF-8 \
zh_SG.GBK/GBK \
zh_SG/GB2312 \
-zh_TW.EUC-TW/EUC-TW \
zh_TW.UTF-8/UTF-8 \
+zh_TW.EUC-TW/EUC-TW \
zh_TW/BIG5 \
zu_ZA.UTF-8/UTF-8 \
zu_ZA/ISO-8859-1 \
diff --git a/localedata/locales/ar_SA b/localedata/locales/ar_SA
index 6c6f6b37fc..b072757a4d 100644
--- a/localedata/locales/ar_SA
+++ b/localedata/locales/ar_SA
@@ -47,223 +47,8 @@ END LC_CTYPE
% Set up the LC_COLLATE category
LC_COLLATE
-
-
-order_start forward; forward
-
-
-
-
-
-
-
-
-
-
-
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-