summaryrefslogtreecommitdiff
path: root/debian/patches/git-updates.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/git-updates.diff')
-rw-r--r--debian/patches/git-updates.diff3681
1 files changed, 1 insertions, 3680 deletions
diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff
index 6b663310..f9395175 100644
--- a/debian/patches/git-updates.diff
+++ b/debian/patches/git-updates.diff
@@ -1,3681 +1,2 @@
-GIT update of https://sourceware.org/git/glibc.git/release/2.30/master from glibc-2.30
+GIT update of https://sourceware.org/git/glibc.git/release/2.31/master from glibc-2.31
-diff --git a/ChangeLog b/ChangeLog
-index cdb9e14881..bc2f4aae69 100644
---- a/ChangeLog
-+++ b/ChangeLog
-@@ -1,3 +1,214 @@
-+2019-08-15 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #24899]
-+ * sysdeps/gnu/bits/utmpx.h (struct utmpx): Add
-+ __attribute_nonstring__ to ut_line, ut_id, ut_user, ut_host.
-+ * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmpx):
-+ Likewise.
-+ * sysdeps/gnu/bits/utmp.h (struct utmp): Add
-+ __attribute_nonstring__ to ut_id.
-+ * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmp):
-+ Likewise.
-+
-+2019-08-28 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #24902]
-+ * login/Makefile (tests): Add tst-pututxline-lockfail.
-+ (tst-pututxline-lockfail): Link with -lpthread.
-+ * login/utmp_file.c (internal_getut_r): Remove buffer argument.
-+ (__libc_getutid_r): Adjust.
-+ (__libc_pututline): Likewise. Check for file_offset == -1.
-+ * login/tst-pututxline-lockfail.c: New file.
-+
-+2019-08-15 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #24880]
-+ * login/utmp_file.c (file_locking_failed): Use struct flock64.
-+ (file_locking_unlock): Likewise.
-+
-+2019-08-15 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #24879]
-+ login: Disarm timer after utmp lock acquisition.
-+ * login/utmp_file.c (struct file_locking): Remove.
-+ (try_file_lock): Adjust.
-+ (file_lock_restore): Remove function.
-+ (__libc_getutent_r): .
-+ (internal_getut_r): Likewise.
-+ (__libc_getutline_r): Likewise.
-+ (__libc_pututline): Likewise.
-+ (__libc_updwtmp): Likewise.
-+
-+2019-08-15 Florian Weimer <fweimer@redhat.com>
-+
-+ * login/utmp_file.c (__libc_updwtmp): Unlock the right file
-+ descriptor.
-+ * login/Makefile (tests): Add tst-updwtmpx.
-+ * login/tst-updwtmpx.c: New file.
-+
-+2019-08-13 Florian Weimer <fweimer@redhat.com>
-+
-+ * login/utmp_file.c (LOCK_FILE, LOCKING_FAILED, UNLOCK_FILE):
-+ Remove macros.
-+ (struct file_locking): New.
-+ (try_file_lock, file_unlock, file_lock_restore): New functions.
-+ (__libc_getutent_r): Use the new functions.
-+ (internal_getut_r): Likewise.
-+ (__libc_getutline_r): Likewise.
-+ (__libc_pututline): Likewise.
-+ (__libc_updwtmp): Likewise.
-+
-+2019-08-13 Florian Weimer <fweimer@redhat.com>
-+
-+ * login/getutid_r.c (__getutid_r): _HAVE_UT_ID and _HAVE_UT_TYPE
-+ are always true.
-+ * login/getutmp.c (getutmp): _HAVE_UT_TYPE, _HAVE_UT_PID,
-+ _HAVE_UT_ID, _HAVE_UT_HOST, _HAVE_UT_TV are always true.
-+ * login/getutmpx.c (getutmpx): Likewise.
-+ * login/login.c (login): _HAVE_UT_TYPE, _HAVE_UT_PID are always
-+ true.
-+ * login/logout.c (logout): _HAVE_UT_TYPE, _HAVE_UT_HOST,
-+ _HAVE_UT_TV are always true.
-+ * login/logwtmp.c (logwtmp): _HAVE_UT_PID, _HAVE_UT_TYPE,
-+ _HAVE_UT_HOST, _HAVE_UT_TV are always true.
-+ * login/tst-utmp.c: _HAVE_UT_TYPE, _HAVE_UT_TV are always true.
-+ * login/utmp_file.c (__libc_setutent): _HAVE_UT_TYPE, _HAVE_UT_ID
-+ are always true.
-+ (internal_getut_r): _HAVE_UT_TYPE is always true.
-+ (__libc_pututline): Likewise.
-+ * login/programs/utmpdump.c (print_entry): Assume that
-+ _HAVE_UT_TYPE, _HAVE_UT_PID, _HAVE_UT_ID, _HAVE_UT_HOST,
-+ _HAVE_UT_TV are always true.
-+ * sysdeps/generic/utmp-equal.h (__utmp_equal): _HAVE_UT_TYPE,
-+ _HAVE_UT_ID are always true.
-+ * sysdeps/gnu/bits/utmp.h: Move to ...
-+ * bits/utmp.h: ... here, replacing the old file.
-+
-+2019-08-05 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #23518]
-+ * login/uptmp-private.h (struct ufuncs): Remove definition.
-+ (__libc_utmp_file_functions, __libc_utmp_unknown_functions)
-+ (__libc_utmp_jump_table): Remove declarations.
-+ (__libc_setutent, __libc_getutent_r, __libc_getutid_r)
-+ (__libc_getutline_r, __libc_pututline, __libc_endutent)
-+ (__libc_updwtmp): Declare.
-+ * login/getutent_r.c (__libc_utmp_unknown_functions)
-+ (__libc_utmp_jump_table, setutent_unknown, getutent_r_unknown)
-+ (getutid_r_unknown, getutline_r_unknown, pututline_unknown)
-+ (endutent_unknown): Remove definitions.
-+ (__setutent): Call __libc_setutent.
-+ (__getutent_r): Call __libc_getutent_r.
-+ (__pututline): Call __libc_pututline.
-+ (__endutent): Call __libc_endutent.
-+ * login/getutid_r.c (__getutid_r): Call __libc_getutid_r.
-+ * login/getutline_r.c (__getutline_r): Call __libc_getutline_r.
-+ * login/updwtmp.c (__updwtmp): Call __libc_updwtmp.
-+ * login/utmp_file.c (__libc_utmp_file_functions): Remove definition
-+ (__libc_setutent): Rename from stetutent_file. Drop static.
-+ (maybe_setutent): New function.
-+ (__libc_getutent_r): Rename from getutent_r_file. Drop static.
-+ Check for initialization.
-+ (__libc_getutid_r): Rename from getutid_r_file. Drop static.
-+ Check for initialization.
-+ (__libc_getutline_r): Rename from getutline_r_file. Drop static.
-+ Check for initialization.
-+ (__libc_pututline): Rename from pututline_file. Drop static.
-+ Check for initialization.
-+ (__libc_endutent): Rename from endutent_file. Drop static. Check
-+ for initialization.
-+ (__libc_updwtmp): Rename from updwtmp_file. Drop static.
-+ * login/utmpname.c (__utmpname): Call __libc_endutent.
-+ * sysdeps/unix/getlogin_r (__getlogin_r): Call __libc_setutent,
-+ __libc_getutlien_r, __libc_endutent.
-+ * manual/users.texi (Who Logged In, Manipulating the Database):
-+ Adjust.
-+
-+2019-08-15 Florian Weimer <fweimer@redhat.com>
-+
-+ * malloc/Makefile (tests): Only add tst-mxfast for
-+ $(have-tunables).
-+ * malloc/tst-mxfast.c: Fix copyright year.
-+ (do_test): Fix GNU style issues. Use TEST_COMPARE instead of
-+ assert for checks.
-+
-+2019-08-09 DJ Delorie <dj@redhat.com>
-+
-+ * elf/dl-tunables.list: Add glibc.malloc.mxfast.
-+ * manual/tunables.texi: Document it.
-+ * malloc/malloc.c (do_set_mxfast): New.
-+ (__libc_mallopt): Call it.
-+ * malloc/arena.c: Add mxfast tunable.
-+ * malloc/tst-mxfast.c: New.
-+ * malloc/Makefile: Add it.
-+
-+2019-08-08 Niklas Hambüchen <mail@nh2.me>
-+ Carlos O'Donell <carlos@redhat.com>
-+
-+ [BZ #24026]
-+ * malloc/malloc.c (__malloc_info): Account for top chunk.
-+
-+2019-11-01 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
-+
-+ * sysdeps/unix/sysv/linux/mips/Makefile
-+ (test-xfail-check-execstack):
-+ Move under mips-has-gnustack != yes.
-+ (CFLAGS-.o*, ASFLAGS-.o*): New rules.
-+ Apply -Wa,-execstack if mips-force-execstack == yes.
-+ * sysdeps/unix/sysv/linux/mips/configure: Regenerated.
-+ * sysdeps/unix/sysv/linux/mips/configure.ac
-+ (mips-force-execstack): New var.
-+ Set to yes for hard-float builds with minimum_kernel < 4.8.0
-+ or minimum_kernel not set at all.
-+ (mips-has-gnustack): New var.
-+ Use value of libc_cv_as_noexecstack
-+ if mips-force-execstack != yes, otherwise set to no.
-+
-+2019-10-08 Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
-+
-+ * Makefile: Fix locale dependency for a couple of tests.
-+ ($(objpfx)tst-strftime2.out): New rule.
-+ ($(objpfx)tst-strftime3.out): Likewise.
-+
-+2019-09-20 Joseph Myers <joseph@codesourcery.com>
-+
-+ * sysdeps/unix/sysv/linux/riscv/vfork.S: Do not include
-+ <linux/sched.h>.
-+ (CLONE_VM): New macro.
-+ (CLONE_VFORK): Likewise.
-+
-+2019-09-14 Aurelien Jarno <aurelien@aurel32.net>
-+
-+ [BZ #24986]
-+ * sysdeps/unix/alpha/getegid.S: Move to ...
-+ * sysdeps/unix/sysv/linux/alpha/getegid.S: ... here.
-+ * sysdeps/unix/alpha/geteuid.S: Move to ...
-+ * sysdeps/unix/sysv/linux/alpha/geteuid.S: ... here.
-+ * sysdeps/unix/alpha/getppid.S: Move to ...
-+ * sysdeps/unix/sysv/linux/alpha/getppid.S: ... here
-+
-+2019-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org>
-+
-+ * sysdeps/hppa/fpu/libm-test-ulps: Update.
-+
-+2019-09-03 Aurelien Jarno <aurelien@aurel32.net>
-+
-+ * sysdeps/alpha/fpu/libm-test-ulps: Regenerated using GCC 9.2.
-+
-+2019-08-28 Rafal Luzynski <digitalfreak@lingonborough.com>
-+
-+ [BZ #24682]
-+ * NEWS: Mention this bug fixed.
-+ * localedata/locales/bo_CN (first_weekday): Add, set to 2 (Monday).
-+ * localedata/locales/ug_CN (first_weekday): Likewise.
-+ * localedata/locales/zh_CN (first_weekday): Likewise.
-+
-+2019-08-01 Florian Weimer <fweimer@redhat.com>
-+
-+ [BZ #24867]
-+ * malloc/malloc.c (__malloc_info): Remove unwanted leading
-+ whitespace.
-+
- 2019-08-01 Carlos O'Donell <carlos@redhat.com>
-
- * version.h (RELEASE): Set to "stable".
-diff --git a/NEWS b/NEWS
-index ee9ed4de5a..15df670edc 100644
---- a/NEWS
-+++ b/NEWS
-@@ -4,6 +4,38 @@ See the end for copying conditions.
-
- Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
- using `glibc' in the "product" field.
-+
-+Version 2.30.1
-+
-+Security related changes:
-+
-+CVE-2019-19126: ld.so failed to ignore the LD_PREFER_MAP_32BIT_EXEC
-+ environment variable during program execution after a security
-+ transition, allowing local attackers to restrict the possible mapping
-+ addresses for loaded libraries and thus bypass ASLR for a setuid
-+ program. Reported by Marcin Kościelnicki.
-+
-+The following bugs are resolved with this release:
-+
-+ [23518] login: Remove utmp backend jump tables
-+ [24682] localedata: zh_CN first weekday should be Monday per GB/T
-+ 7408-2005
-+ [24867] malloc: Remove unwanted leading whitespace in malloc_info
-+ [24879] login: Disarm timer after utmp lock acquisition
-+ [24880] login: Use struct flock64 in utmp
-+ [24882] login: Acquire write lock early in pututline
-+ [24986] alpha: new getegid, geteuid and getppid syscalls used
-+ unconditionally
-+ [24899] login: Add nonstring attributes to struct utmp, struct utmpx
-+ [24902] login: pututxline could fail to overwrite existing entries
-+ [25066] FAIL: nptl/tst-tls1 on hppa
-+ [25189] Don't use a custom wrapper macro around __has_include
-+ [25203] libio: Disable vtable validation for pre-2.1 interposed handles
-+ [25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs
-+ [25225] ld.so fails to link on x86 if GCC defaults to -fcf-protection
-+ [25232] No const correctness for strchr et al. for Clang++
-+ [25401] Remove incorrect alloc_size attribute from pvalloc
-+
-
- Version 2.30
-
-diff --git a/bits/utmp.h b/bits/utmp.h
-index 4c36ca19ce..854b342164 100644
---- a/bits/utmp.h
-+++ b/bits/utmp.h
-@@ -1,4 +1,4 @@
--/* The `struct utmp' type, describing entries in the utmp file. Generic/BSDish
-+/* The `struct utmp' type, describing entries in the utmp file.
- Copyright (C) 1993-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
-@@ -21,29 +21,107 @@
- #endif
-
- #include <paths.h>
--#include <time.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+#include <bits/wordsize.h>
-
-
--#define UT_NAMESIZE 8
--#define UT_LINESIZE 8
--#define UT_HOSTSIZE 16
-+#define UT_LINESIZE 32
-+#define UT_NAMESIZE 32
-+#define UT_HOSTSIZE 256
-
-
-+/* The structure describing an entry in the database of
-+ previous logins. */
- struct lastlog
- {
-- time_t ll_time;
-+#if __WORDSIZE_TIME64_COMPAT32
-+ int32_t ll_time;
-+#else
-+ __time_t ll_time;
-+#endif
- char ll_line[UT_LINESIZE];
- char ll_host[UT_HOSTSIZE];
- };
-
--struct utmp
-+
-+/* The structure describing the status of a terminated process. This
-+ type is used in `struct utmp' below. */
-+struct exit_status
- {
-- char ut_line[UT_LINESIZE];
-- char ut_user[UT_NAMESIZE];
--#define ut_name ut_user
-- char ut_host[UT_HOSTSIZE];
-- long int ut_time;
-+ short int e_termination; /* Process termination status. */
-+ short int e_exit; /* Process exit status. */
- };
-
-
--#define _HAVE_UT_HOST 1 /* We have the ut_host field. */
-+/* The structure describing an entry in the user accounting database. */
-+struct utmp
-+{
-+ short int ut_type; /* Type of login. */
-+ pid_t ut_pid; /* Process ID of login process. */
-+ char ut_line[UT_LINESIZE]
-+ __attribute_nonstring__; /* Devicename. */
-+ char ut_id[4]
-+ __attribute_nonstring__; /* Inittab ID. */
-+ char ut_user[UT_NAMESIZE]
-+ __attribute_nonstring__; /* Username. */
-+ char ut_host[UT_HOSTSIZE]
-+ __attribute_nonstring__; /* Hostname for remote login. */
-+ struct exit_status ut_exit; /* Exit status of a process marked
-+ as DEAD_PROCESS. */
-+/* The ut_session and ut_tv fields must be the same size when compiled
-+ 32- and 64-bit. This allows data files and shared memory to be
-+ shared between 32- and 64-bit applications. */
-+#if __WORDSIZE_TIME64_COMPAT32
-+ int32_t ut_session; /* Session ID, used for windowing. */
-+ struct
-+ {
-+ int32_t tv_sec; /* Seconds. */
-+ int32_t tv_usec; /* Microseconds. */
-+ } ut_tv; /* Time entry was made. */
-+#else
-+ long int ut_session; /* Session ID, used for windowing. */
-+ struct timeval ut_tv; /* Time entry was made. */
-+#endif
-+
-+ int32_t ut_addr_v6[4]; /* Internet address of remote host. */
-+ char __glibc_reserved[20]; /* Reserved for future use. */
-+};
-+
-+/* Backwards compatibility hacks. */
-+#define ut_name ut_user
-+#ifndef _NO_UT_TIME
-+/* We have a problem here: `ut_time' is also used otherwise. Define
-+ _NO_UT_TIME if the compiler complains. */
-+# define ut_time ut_tv.tv_sec
-+#endif
-+#define ut_xtime ut_tv.tv_sec
-+#define ut_addr ut_addr_v6[0]
-+
-+
-+/* Values for the `ut_type' field of a `struct utmp'. */
-+#define EMPTY 0 /* No valid user accounting information. */
-+
-+#define RUN_LVL 1 /* The system's runlevel. */
-+#define BOOT_TIME 2 /* Time of system boot. */
-+#define NEW_TIME 3 /* Time after system clock changed. */
-+#define OLD_TIME 4 /* Time when system clock changed. */
-+
-+#define INIT_PROCESS 5 /* Process spawned by the init process. */
-+#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
-+#define USER_PROCESS 7 /* Normal process. */
-+#define DEAD_PROCESS 8 /* Terminated process. */
-+
-+#define ACCOUNTING 9
-+
-+/* Old Linux name for the EMPTY type. */
-+#define UT_UNKNOWN EMPTY
-+
-+
-+/* Tell the user that we have a modern system with UT_HOST, UT_PID,
-+ UT_TYPE, UT_ID and UT_TV fields. */
-+#define _HAVE_UT_TYPE 1
-+#define _HAVE_UT_PID 1
-+#define _HAVE_UT_ID 1
-+#define _HAVE_UT_TV 1
-+#define _HAVE_UT_HOST 1
-diff --git a/configure b/configure
-index c773c487b5..6d26b8246f 100755
---- a/configure
-+++ b/configure
-@@ -3777,11 +3777,32 @@ else
- fi
-
-
-+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+
-+int
-+main ()
-+{
-+
-+#ifndef __CET__
-+#error no CET compiler support
-+#endif
-+ ;
-+ return 0;
-+}
-+_ACEOF
-+if ac_fn_c_try_compile "$LINENO"; then :
-+ libc_cv_compiler_default_cet=yes
-+else
-+ libc_cv_compiler_default_cet=no
-+fi
-+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-+
- # Check whether --enable-cet was given.
- if test "${enable_cet+set}" = set; then :
- enableval=$enable_cet; enable_cet=$enableval
- else
-- enable_cet=no
-+ enable_cet=$libc_cv_compiler_default_cet
- fi
-
-
-diff --git a/configure.ac b/configure.ac
-index 598ba6c4ae..7436485419 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -472,11 +472,18 @@ AC_ARG_ENABLE([mathvec],
- [build_mathvec=$enableval],
- [build_mathvec=notset])
-
-+AC_TRY_COMPILE([], [
-+#ifndef __CET__
-+# error no CET compiler support
-+#endif],
-+ [libc_cv_compiler_default_cet=yes],
-+ [libc_cv_compiler_default_cet=no])
-+
- AC_ARG_ENABLE([cet],
- AC_HELP_STRING([--enable-cet],
- [enable Intel Control-flow Enforcement Technology (CET), x86 only]),
- [enable_cet=$enableval],
-- [enable_cet=no])
-+ [enable_cet=$libc_cv_compiler_default_cet])
-
- # We keep the original values in `$config_*' and never modify them, so we
- # can write them unchanged into config.make. Everything else uses
-diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
-index 1fc2d8886b..525c3767b5 100644
---- a/elf/dl-tunables.list
-+++ b/elf/dl-tunables.list
-@@ -85,6 +85,11 @@ glibc {
- tcache_unsorted_limit {
- type: SIZE_T
- }
-+ mxfast {
-+ type: SIZE_T
-+ minval: 0
-+ security_level: SXID_IGNORE
-+ }
- }
- cpu {
- hwcap_mask {
-diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c
-index 2b861cd754..7503cdd62d 100644
---- a/libio/oldstdfiles.c
-+++ b/libio/oldstdfiles.c
-@@ -83,6 +83,11 @@ _IO_check_libio (void)
- = stderr->_vtable_offset =
- ((int) sizeof (struct _IO_FILE)
- - (int) sizeof (struct _IO_FILE_complete));
-+
-+ if (_IO_stdin_.vtable != &_IO_old_file_jumps
-+ || _IO_stdout_.vtable != &_IO_old_file_jumps
-+ || _IO_stderr_.vtable != &_IO_old_file_jumps)
-+ IO_set_accept_foreign_vtables (&_IO_vtable_check);
- }
- }
-
-diff --git a/localedata/locales/bo_CN b/localedata/locales/bo_CN
-index 90cbc7807b..9df91a1721 100644
---- a/localedata/locales/bo_CN
-+++ b/localedata/locales/bo_CN
-@@ -128,6 +128,7 @@ t_fmt_ampm "<U0F46><U0F74><U0F0B><U0F5A><U0F7C><U0F51>/
- <U0025><U0070>"
-
- week 7;19971130;1
-+first_weekday 2
- END LC_TIME
-
- LC_MESSAGES
-diff --git a/localedata/locales/ug_CN b/localedata/locales/ug_CN
-index 1ba583c588..83d15c90e4 100644
---- a/localedata/locales/ug_CN
-+++ b/localedata/locales/ug_CN
-@@ -165,6 +165,7 @@ am_pm "";""
- date_fmt "%a<U060C> %d-%m-%Y<U060C> %T"
-
- week 7;19971130;1
-+first_weekday 2
- END LC_TIME
-
- LC_MESSAGES
-diff --git a/localedata/locales/zh_CN b/localedata/locales/zh_CN
-index 62a46415c1..cd4b33602a 100644
---- a/localedata/locales/zh_CN
-+++ b/localedata/locales/zh_CN
-@@ -139,6 +139,7 @@ t_fmt_ampm "%p %I<U65F6>%M<U5206>%S<U79D2>"
-
- date_fmt "%Y<U5E74> %m<U6708> %d<U65E5> %A %H:%M:%S %Z"
- week 7;19971130;1
-+first_weekday 2
- END LC_TIME
-
- LC_MESSAGES
-diff --git a/login/Makefile b/login/Makefile
-index 92535f0aec..4fd8195e73 100644
---- a/login/Makefile
-+++ b/login/Makefile
-@@ -43,7 +43,8 @@ endif
- subdir-dirs = programs
- vpath %.c programs
-
--tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
-+tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
-+ tst-pututxline-lockfail tst-pututxline-cache
-
- # Build the -lutil library with these extra functions.
- extra-libs := libutil
-@@ -71,3 +72,6 @@ endif
- $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force)
- $(make-target-directory)
- -$(INSTALL_PROGRAM) -m 4755 -o root $< $@
-+
-+$(objpfx)tst-pututxline-lockfail: $(shared-thread-library)
-+$(objpfx)tst-pututxline-cache: $(shared-thread-library)
-diff --git a/login/getutent_r.c b/login/getutent_r.c
-index 98ffc5d1c6..fd13be8a1e 100644
---- a/login/getutent_r.c
-+++ b/login/getutent_r.c
-@@ -23,115 +23,16 @@
-
- #include "utmp-private.h"
-
--
--/* Functions defined here. */
--static int setutent_unknown (void);
--static int getutent_r_unknown (struct utmp *buffer, struct utmp **result);
--static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer,
-- struct utmp **result);
--static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer,
-- struct utmp **result);
--static struct utmp *pututline_unknown (const struct utmp *data);
--static void endutent_unknown (void);
--
--/* Initial Jump table. */
--const struct utfuncs __libc_utmp_unknown_functions =
--{
-- setutent_unknown,
-- getutent_r_unknown,
-- getutid_r_unknown,
-- getutline_r_unknown,
-- pututline_unknown,
-- endutent_unknown,
-- NULL
--};
--
--/* Currently selected backend. */
--const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions;
--
- /* We need to protect the opening of the file. */
- __libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden)
-
-
--static int
--setutent_unknown (void)
--{
-- int result;
--
-- result = (*__libc_utmp_file_functions.setutent) ();
-- if (result)
-- __libc_utmp_jump_table = &__libc_utmp_file_functions;
--
-- return result;
--}
--
--
--static int
--getutent_r_unknown (struct utmp *buffer, struct utmp **result)
--{
-- /* The backend was not yet initialized. */
-- if (setutent_unknown ())
-- return (*__libc_utmp_jump_table->getutent_r) (buffer, result);
--
-- /* Not available. */
-- *result = NULL;
-- return -1;
--}
--
--
--static int
--getutid_r_unknown (const struct utmp *id, struct utmp *buffer,
-- struct utmp **result)
--{
-- /* The backend was not yet initialized. */
-- if (setutent_unknown ())
-- return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
--
-- /* Not available. */
-- *result = NULL;
-- return -1;
--}
--
--
--static int
--getutline_r_unknown (const struct utmp *line, struct utmp *buffer,
-- struct utmp **result)
--{
-- /* The backend was not yet initialized. */
-- if (setutent_unknown ())
-- return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
--
-- /* Not available. */
-- *result = NULL;
-- return -1;
--}
--
--
--static struct utmp *
--pututline_unknown (const struct utmp *data)
--{
-- /* The backend was not yet initialized. */
-- if (setutent_unknown ())
-- return (*__libc_utmp_jump_table->pututline) (data);
--
-- /* Not available. */
-- return NULL;
--}
--
--
--static void
--endutent_unknown (void)
--{
-- /* Nothing to do. */
--}
--
--
- void
- __setutent (void)
- {
- __libc_lock_lock (__libc_utmp_lock);
-
-- (*__libc_utmp_jump_table->setutent) ();
-+ __libc_setutent ();
-
- __libc_lock_unlock (__libc_utmp_lock);
- }
-@@ -145,7 +46,7 @@ __getutent_r (struct utmp *buffer, struct utmp **result)
-
- __libc_lock_lock (__libc_utmp_lock);
-
-- retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result);
-+ retval = __libc_getutent_r (buffer, result);
-
- __libc_lock_unlock (__libc_utmp_lock);
-
-@@ -162,7 +63,7 @@ __pututline (const struct utmp *data)
-
- __libc_lock_lock (__libc_utmp_lock);
-
-- buffer = (*__libc_utmp_jump_table->pututline) (data);
-+ buffer = __libc_pututline (data);
-
- __libc_lock_unlock (__libc_utmp_lock);
-
-@@ -177,8 +78,7 @@ __endutent (void)
- {
- __libc_lock_lock (__libc_utmp_lock);
-
-- (*__libc_utmp_jump_table->endutent) ();
-- __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
-+ __libc_endutent ();
-
- __libc_lock_unlock (__libc_utmp_lock);
- }
-diff --git a/login/getutid_r.c b/login/getutid_r.c
-index 34ea61d8f4..460d94be0c 100644
---- a/login/getutid_r.c
-+++ b/login/getutid_r.c
-@@ -32,7 +32,6 @@ __libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
- int
- __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
- {
--#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0)
- int retval;
-
- /* Test whether ID has any of the legal types. */
-@@ -49,15 +48,11 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
-
- __libc_lock_lock (__libc_utmp_lock);
-
-- retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
-+ retval = __libc_getutid_r (id, buffer, result);
-
- __libc_lock_unlock (__libc_utmp_lock);
-
- return retval;
--#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */
-- __set_errno (ENOSYS);
-- return -1;
--#endif
- }
- libc_hidden_def (__getutid_r)
- weak_alias (__getutid_r, getutid_r)
-diff --git a/login/getutline_r.c b/login/getutline_r.c
-index 110b89e438..f03255dbbd 100644
---- a/login/getutline_r.c
-+++ b/login/getutline_r.c
-@@ -36,7 +36,7 @@ __getutline_r (const struct utmp *line, struct utmp *buffer,
-
- __libc_lock_lock (__libc_utmp_lock);
-
-- retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
-+ retval = __libc_getutline_r (line, buffer, result);
-
- __libc_lock_unlock (__libc_utmp_lock);
-
-diff --git a/login/getutmp.c b/login/getutmp.c
-index 73bc15d781..4e3be11216 100644
---- a/login/getutmp.c
-+++ b/login/getutmp.c
-@@ -23,23 +23,11 @@
- void
- getutmp (const struct utmpx *utmpx, struct utmp *utmp)
- {
--#if _HAVE_UT_TYPE - 0
- utmp->ut_type = utmpx->ut_type;
--#endif
--#if _HAVE_UT_PID - 0
- utmp->ut_pid = utmpx->ut_pid;
--#endif
- memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line));
- memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user));
--#if _HAVE_UT_ID - 0
- memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id));
--#endif
--#if _HAVE_UT_HOST - 0
- memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host));
--#endif
--#if _HAVE_UT_TV - 0
- utmp->ut_tv = utmpx->ut_tv;
--#else
-- utmp->ut_time = utmpx->ut_time;
--#endif
- }
-diff --git a/login/getutmpx.c b/login/getutmpx.c
-index b181d9bc30..da28d339ab 100644
---- a/login/getutmpx.c
-+++ b/login/getutmpx.c
-@@ -24,24 +24,11 @@ void
- getutmpx (const struct utmp *utmp, struct utmpx *utmpx)
- {
- memset (utmpx, 0, sizeof (struct utmpx));
--
--#if _HAVE_UT_TYPE - 0
- utmpx->ut_type = utmp->ut_type;
--#endif
--#if _HAVE_UT_PID - 0
- utmpx->ut_pid = utmp->ut_pid;
--#endif
- memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line));
- memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user));
--#if _HAVE_UT_ID - 0
- memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id));
--#endif
--#if _HAVE_UT_HOST - 0
- memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host));
--#endif
--#if _HAVE_UT_TV - 0
- utmpx->ut_tv = utmp->ut_tv;
--#else
-- utmpx->ut_time = utmp->ut_time;
--#endif
- }
-diff --git a/login/login.c b/login/login.c
-index 09ef3f75a5..b7d638c692 100644
---- a/login/login.c
-+++ b/login/login.c
-@@ -91,12 +91,8 @@ login (const struct utmp *ut)
- struct utmp copy = *ut;
-
- /* Fill in those fields we supply. */
--#if _HAVE_UT_TYPE - 0
- copy.ut_type = USER_PROCESS;
--#endif
--#if _HAVE_UT_PID - 0
- copy.ut_pid = getpid ();
--#endif
-
- /* Seek tty. */
- found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty));
-diff --git a/login/logout.c b/login/logout.c
-index 85254d0324..5015c1af0b 100644
---- a/login/logout.c
-+++ b/login/logout.c
-@@ -36,9 +36,7 @@ logout (const char *line)
- setutent ();
-
- /* Fill in search information. */
--#if _HAVE_UT_TYPE - 0
- tmp.ut_type = USER_PROCESS;
--#endif
- strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
-
- /* Read the record. */
-@@ -46,20 +44,12 @@ logout (const char *line)
- {
- /* Clear information about who & from where. */
- memset (ut->ut_name, '\0', sizeof ut->ut_name);
--#if _HAVE_UT_HOST - 0
- memset (ut->ut_host, '\0', sizeof ut->ut_host);
--#endif
--#if _HAVE_UT_TV - 0
- struct timeval tv;
- __gettimeofday (&tv, NULL);
- ut->ut_tv.tv_sec = tv.tv_sec;
- ut->ut_tv.tv_usec = tv.tv_usec;
--#else
-- ut->ut_time = time (NULL);
--#endif
--#if _HAVE_UT_TYPE - 0
- ut->ut_type = DEAD_PROCESS;
--#endif
-
- if (pututline (ut) != NULL)
- result = 1;
-diff --git a/login/logwtmp.c b/login/logwtmp.c
-index f53187121c..50d14976c7 100644
---- a/login/logwtmp.c
-+++ b/login/logwtmp.c
-@@ -30,26 +30,16 @@ logwtmp (const char *line, const char *name, const char *host)
-
- /* Set information in new entry. */
- memset (&ut, 0, sizeof (ut));
--#if _HAVE_UT_PID - 0
- ut.ut_pid = getpid ();
--#endif
--#if _HAVE_UT_TYPE - 0
- ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS;
--#endif
- strncpy (ut.ut_line, line, sizeof ut.ut_line);
- strncpy (ut.ut_name, name, sizeof ut.ut_name);
--#if _HAVE_UT_HOST - 0
- strncpy (ut.ut_host, host, sizeof ut.ut_host);
--#endif
-
--#if _HAVE_UT_TV - 0
- struct timeval tv;
- __gettimeofday (&tv, NULL);
- ut.ut_tv.tv_sec = tv.tv_sec;
- ut.ut_tv.tv_usec = tv.tv_usec;
--#else
-- ut.ut_time = time (NULL);
--#endif
-
- updwtmp (_PATH_WTMP, &ut);
- }
-diff --git a/login/programs/utmpdump.c b/login/programs/utmpdump.c
-index 4c312f0939..85d8e31b43 100644
---- a/login/programs/utmpdump.c
-+++ b/login/programs/utmpdump.c
-@@ -37,47 +37,11 @@ print_entry (struct utmp *up)
- temp_tv.tv_sec = up->ut_tv.tv_sec;
- temp_tv.tv_usec = up->ut_tv.tv_usec;
-
-- (printf) (
-- /* The format string. */
--#if _HAVE_UT_TYPE
-- "[%d] "
--#endif
--#if _HAVE_UT_PID
-- "[%05d] "
--#endif
--#if _HAVE_UT_ID
-- "[%-4.4s] "
--#endif
-- "[%-8.8s] [%-12.12s]"
--#if _HAVE_UT_HOST
-- " [%-16.16s]"
--#endif
-- " [%-15.15s]"
--#if _HAVE_UT_TV
-- " [%ld]"
--#endif
-- "\n"
-- /* The arguments. */
--#if _HAVE_UT_TYPE
-- , up->ut_type
--#endif
--#if _HAVE_UT_PID
-- , up->ut_pid
--#endif
--#if _HAVE_UT_ID
-- , up->ut_id
--#endif
-- , up->ut_user, up->ut_line
--#if _HAVE_UT_HOST
-- , up->ut_host
--#endif
--#if _HAVE_UT_TV
-- , 4 + ctime (&temp_tv.tv_sec)
-- , (long int) temp_tv.tv_usec
--#else
-- , 4 + ctime (&up->ut_time)
--#endif
-- );
-+ printf ("[%d] [%05d] [%-4.4s] [%-8.8s] [%-12.12s] [%-16.16s] [%-15.15s]"
-+ " [%ld]\n",
-+ up->ut_type, up->ut_pid, up->ut_id, up->ut_user, up->ut_line,
-+ up->ut_host, 4 + ctime (&temp_tv.tv_sec),
-+ (long int) temp_tv.tv_usec);
- }
-
- int
-diff --git a/login/tst-pututxline-cache.c b/login/tst-pututxline-cache.c
-new file mode 100644
-index 0000000000..3f30dd1776
---- /dev/null
-+++ b/login/tst-pututxline-cache.c
-@@ -0,0 +1,193 @@
-+/* Test case for cache invalidation after concurrent write (bug 24882).
-+ Copyright (C) 2019 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; see the file COPYING.LIB. If
-+ not, see <http://www.gnu.org/licenses/>. */
-+
-+/* This test writes an entry to the utmpx file, reads it (so that it
-+ is cached) in process1, and overwrites the same entry in process2
-+ with something that does not match the search criteria. At this
-+ point, the cache of the first process is stale, and when process1
-+ attempts to write a new record which would have gone to the same
-+ place (as indicated by the cache), it needs to realize that it has
-+ to pick a different slot because the old slot is now used for
-+ something else. */
-+
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/namespace.h>
-+#include <support/support.h>
-+#include <support/temp_file.h>
-+#include <support/xthread.h>
-+#include <support/xunistd.h>
-+#include <utmp.h>
-+#include <utmpx.h>
-+
-+/* Set to the path of the utmp file. */
-+static char *utmp_file;
-+
-+/* Used to synchronize the subprocesses. The barrier itself is
-+ allocated in shared memory. */
-+static pthread_barrier_t *barrier;
-+
-+/* setutxent with error checking. */
-+static void
-+xsetutxent (void)
-+{
-+ errno = 0;
-+ setutxent ();
-+ TEST_COMPARE (errno, 0);
-+}
-+
-+/* getutxent with error checking. */
-+static struct utmpx *
-+xgetutxent (void)
-+{
-+ errno = 0;
-+ struct utmpx *result = getutxent ();
-+ if (result == NULL)
-+ FAIL_EXIT1 ("getutxent: %m");
-+ return result;
-+}
-+
-+static void
-+put_entry (const char *id, pid_t pid, const char *user, const char *line)
-+{
-+ struct utmpx ut =
-+ {
-+ .ut_type = LOGIN_PROCESS,
-+ .ut_pid = pid,
-+ .ut_host = "localhost",
-+ };
-+ strcpy (ut.ut_id, id);
-+ strncpy (ut.ut_user, user, sizeof (ut.ut_user));
-+ strncpy (ut.ut_line, line, sizeof (ut.ut_line));
-+ TEST_VERIFY (pututxline (&ut) != NULL);
-+}
-+
-+/* Use two cooperating subprocesses to avoid issues related to
-+ unlock-on-close semantics of POSIX advisory locks. */
-+
-+static __attribute__ ((noreturn)) void
-+process1 (void)
-+{
-+ TEST_COMPARE (utmpname (utmp_file), 0);
-+
-+ /* Create an entry. */
-+ xsetutxent ();
-+ put_entry ("1", 101, "root", "process1");
-+
-+ /* Retrieve the entry. This will fill the internal cache. */
-+ {
-+ errno = 0;
-+ setutxent ();
-+ TEST_COMPARE (errno, 0);
-+ struct utmpx ut =
-+ {
-+ .ut_type = LOGIN_PROCESS,
-+ .ut_line = "process1",
-+ };
-+ struct utmpx *result = getutxline (&ut);
-+ if (result == NULL)
-+ FAIL_EXIT1 ("getutxline (\"process1\"): %m");
-+ TEST_COMPARE (result->ut_pid, 101);
-+ }
-+
-+ /* Signal the other process to overwrite the entry. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Wait for the other process to complete the write operation. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Add another entry. Note: This time, there is no setutxent call. */
-+ put_entry ("1", 103, "root", "process1");
-+
-+ _exit (0);
-+}
-+
-+static void
-+process2 (void *closure)
-+{
-+ /* Wait for the first process to write its entry. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Truncate the file. The glibc interface does not support
-+ re-purposing records, but an external expiration mechanism may
-+ trigger this. */
-+ TEST_COMPARE (truncate64 (utmp_file, 0), 0);
-+
-+ /* Write the replacement entry. */
-+ TEST_COMPARE (utmpname (utmp_file), 0);
-+ xsetutxent ();
-+ put_entry ("2", 102, "user", "process2");
-+
-+ /* Signal the other process that the entry has been replaced. */
-+ xpthread_barrier_wait (barrier);
-+}
-+
-+static int
-+do_test (void)
-+{
-+ xclose (create_temp_file ("tst-tumpx-cache-write-", &utmp_file));
-+ {
-+ pthread_barrierattr_t attr;
-+ xpthread_barrierattr_init (&attr);
-+ xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS);
-+ barrier = support_shared_allocate (sizeof (*barrier));
-+ xpthread_barrier_init (barrier, &attr, 2);
-+ }
-+
-+ /* Run both subprocesses in parallel. */
-+ {
-+ pid_t pid1 = xfork ();
-+ if (pid1 == 0)
-+ process1 ();
-+ support_isolate_in_subprocess (process2, NULL);
-+ int status;
-+ xwaitpid (pid1, &status, 0);
-+ TEST_COMPARE (status, 0);
-+ }
-+
-+ /* Check that the utmpx database contains the expected records. */
-+ {
-+ TEST_COMPARE (utmpname (utmp_file), 0);
-+ xsetutxent ();
-+
-+ struct utmpx *ut = xgetutxent ();
-+ TEST_COMPARE_STRING (ut->ut_id, "2");
-+ TEST_COMPARE (ut->ut_pid, 102);
-+ TEST_COMPARE_STRING (ut->ut_user, "user");
-+ TEST_COMPARE_STRING (ut->ut_line, "process2");
-+
-+ ut = xgetutxent ();
-+ TEST_COMPARE_STRING (ut->ut_id, "1");
-+ TEST_COMPARE (ut->ut_pid, 103);
-+ TEST_COMPARE_STRING (ut->ut_user, "root");
-+ TEST_COMPARE_STRING (ut->ut_line, "process1");
-+
-+ if (getutxent () != NULL)
-+ FAIL_EXIT1 ("additional utmpx entry");
-+ }
-+
-+ xpthread_barrier_destroy (barrier);
-+ support_shared_free (barrier);
-+ free (utmp_file);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/login/tst-pututxline-lockfail.c b/login/tst-pututxline-lockfail.c
-new file mode 100644
-index 0000000000..47c25dc065
---- /dev/null
-+++ b/login/tst-pututxline-lockfail.c
-@@ -0,0 +1,176 @@
-+/* Test the lock upgrade path in tst-pututxline.
-+ Copyright (C) 2019 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; see the file COPYING.LIB. If
-+ not, see <http://www.gnu.org/licenses/>. */
-+
-+/* pututxline upgrades the read lock on the file to a write lock.
-+ This test verifies that if the lock upgrade fails, the utmp
-+ subsystem remains in a consistent state, so that pututxline can be
-+ called again. */
-+
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <support/check.h>
-+#include <support/namespace.h>
-+#include <support/support.h>
-+#include <support/temp_file.h>
-+#include <support/xthread.h>
-+#include <support/xunistd.h>
-+#include <unistd.h>
-+#include <utmp.h>
-+#include <utmpx.h>
-+
-+/* Path to the temporary utmp file. */
-+static char *path;
-+
-+/* Used to synchronize the subprocesses. The barrier itself is
-+ allocated in shared memory. */
-+static pthread_barrier_t *barrier;
-+
-+/* Use pututxline to write an entry for PID. */
-+static struct utmpx *
-+write_entry (pid_t pid)
-+{
-+ struct utmpx ut =
-+ {
-+ .ut_type = LOGIN_PROCESS,
-+ .ut_id = "1",
-+ .ut_user = "root",
-+ .ut_pid = pid,
-+ .ut_line = "entry",
-+ .ut_host = "localhost",
-+ };
-+ return pututxline (&ut);
-+}
-+
-+/* Create the initial entry in a subprocess, so that the utmp
-+ subsystem in the original process is not disturbed. */
-+static void
-+subprocess_create_entry (void *closure)
-+{
-+ TEST_COMPARE (utmpname (path), 0);
-+ TEST_VERIFY (write_entry (101) != NULL);
-+}
-+
-+/* Acquire an advisory read lock on PATH. */
-+__attribute__ ((noreturn)) static void
-+subprocess_lock_file (void)
-+{
-+ int fd = xopen (path, O_RDONLY, 0);
-+
-+ struct flock64 fl =
-+ {
-+ .l_type = F_RDLCK,
-+ fl.l_whence = SEEK_SET,
-+ };
-+ TEST_COMPARE (fcntl64 (fd, F_SETLKW, &fl), 0);
-+
-+ /* Signal to the main process that the lock has been acquired. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Wait for the unlock request from the main process. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Implicitly unlock the file. */
-+ xclose (fd);
-+
-+ /* Overwrite the existing entry. */
-+ TEST_COMPARE (utmpname (path), 0);
-+ errno = 0;
-+ setutxent ();
-+ TEST_COMPARE (errno, 0);
-+ TEST_VERIFY (write_entry (102) != NULL);
-+ errno = 0;
-+ endutxent ();
-+ TEST_COMPARE (errno, 0);
-+
-+ _exit (0);
-+}
-+
-+static int
-+do_test (void)
-+{
-+ xclose (create_temp_file ("tst-pututxline-lockfail-", &path));
-+
-+ {
-+ pthread_barrierattr_t attr;
-+ xpthread_barrierattr_init (&attr);
-+ xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS);
-+ barrier = support_shared_allocate (sizeof (*barrier));
-+ xpthread_barrier_init (barrier, &attr, 2);
-+ xpthread_barrierattr_destroy (&attr);
-+ }
-+
-+ /* Write the initial entry. */
-+ support_isolate_in_subprocess (subprocess_create_entry, NULL);
-+
-+ pid_t locker_pid = xfork ();
-+ if (locker_pid == 0)
-+ subprocess_lock_file ();
-+
-+ /* Wait for the file locking to complete. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Try to add another entry. This attempt will fail, with EINTR or
-+ EAGAIN. */
-+ TEST_COMPARE (utmpname (path), 0);
-+ TEST_VERIFY (write_entry (102) == NULL);
-+ if (errno != EINTR)
-+ TEST_COMPARE (errno, EAGAIN);
-+
-+ /* Signal the subprocess to overwrite the entry. */
-+ xpthread_barrier_wait (barrier);
-+
-+ /* Wait for write and unlock to complete. */
-+ {
-+ int status;
-+ xwaitpid (locker_pid, &status, 0);
-+ TEST_COMPARE (status, 0);
-+ }
-+
-+ /* The file is no longer locked, so this operation will succeed. */
-+ TEST_VERIFY (write_entry (103) != NULL);
-+ errno = 0;
-+ endutxent ();
-+ TEST_COMPARE (errno, 0);
-+
-+ /* Check that there is just one entry with the expected contents.
-+ If pututxline becomes desynchronized internally, the entry is not
-+ overwritten (bug 24902). */
-+ errno = 0;
-+ setutxent ();
-+ TEST_COMPARE (errno, 0);
-+ struct utmpx *ut = getutxent ();
-+ TEST_VERIFY_EXIT (ut != NULL);
-+ TEST_COMPARE (ut->ut_type, LOGIN_PROCESS);
-+ TEST_COMPARE_STRING (ut->ut_id, "1");
-+ TEST_COMPARE_STRING (ut->ut_user, "root");
-+ TEST_COMPARE (ut->ut_pid, 103);
-+ TEST_COMPARE_STRING (ut->ut_line, "entry");
-+ TEST_COMPARE_STRING (ut->ut_host, "localhost");
-+ TEST_VERIFY (getutxent () == NULL);
-+ errno = 0;
-+ endutxent ();
-+ TEST_COMPARE (errno, 0);
-+
-+ xpthread_barrier_destroy (barrier);
-+ support_shared_free (barrier);
-+ free (path);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/login/tst-updwtmpx.c b/login/tst-updwtmpx.c
-new file mode 100644
-index 0000000000..0a4a27daeb
---- /dev/null
-+++ b/login/tst-updwtmpx.c
-@@ -0,0 +1,112 @@
-+/* Basic test coverage for updwtmpx.
-+ Copyright (C) 2019 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; see the file COPYING.LIB. If
-+ not, see <http://www.gnu.org/licenses/>. */
-+
-+/* This program runs a series of tests. Each one calls updwtmpx
-+ twice, to write two records, optionally with misalignment in the
-+ file, and reads back the results. */
-+
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <support/check.h>
-+#include <support/descriptors.h>
-+#include <support/support.h>
-+#include <support/temp_file.h>
-+#include <support/test-driver.h>
-+#include <support/xunistd.h>
-+#include <unistd.h>
-+#include <utmpx.h>
-+
-+static int
-+do_test (void)
-+{
-+ /* Two entries filled with an arbitrary bit pattern. */
-+ struct utmpx entries[2];
-+ unsigned char pad;
-+ {
-+ unsigned char *p = (unsigned char *) &entries[0];
-+ for (size_t i = 0; i < sizeof (entries); ++i)
-+ {
-+ p[i] = i;
-+ }
-+ /* Make sure that the first and second entry and the padding are
-+ different. */
-+ p[sizeof (struct utmpx)] = p[0] + 1;
-+ pad = p[0] + 2;
-+ }
-+
-+ char *path;
-+ int fd = create_temp_file ("tst-updwtmpx-", &path);
-+
-+ /* Used to check that updwtmpx does not leave an open file
-+ descriptor around. */
-+ struct support_descriptors *descriptors = support_descriptors_list ();
-+
-+ /* updwtmpx is expected to remove misalignment. Optionally insert
-+ one byte of misalignment at the start and in the middle (after
-+ the first entry). */
-+ for (int misaligned_start = 0; misaligned_start < 2; ++misaligned_start)
-+ for (int misaligned_middle = 0; misaligned_middle < 2; ++misaligned_middle)
-+ {
-+ if (test_verbose > 0)
-+ printf ("info: misaligned_start=%d misaligned_middle=%d\n",
-+ misaligned_start, misaligned_middle);
-+
-+ xftruncate (fd, 0);
-+ TEST_COMPARE (pwrite64 (fd, &pad, misaligned_start, 0),
-+ misaligned_start);
-+
-+ /* Write first entry and check it. */
-+ errno = 0;
-+ updwtmpx (path, &entries[0]);
-+ TEST_COMPARE (errno, 0);
-+ support_descriptors_check (descriptors);
-+ TEST_COMPARE (xlseek (fd, 0, SEEK_END), sizeof (struct utmpx));
-+ struct utmpx buffer;
-+ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0),
-+ sizeof (buffer));
-+ TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]),
-+ &buffer, sizeof (buffer));
-+
-+ /* Middle mis-alignmet. */
-+ TEST_COMPARE (pwrite64 (fd, &pad, misaligned_middle,
-+ sizeof (struct utmpx)), misaligned_middle);
-+
-+ /* Write second entry and check both entries. */
-+ errno = 0;
-+ updwtmpx (path, &entries[1]);
-+ TEST_COMPARE (errno, 0);
-+ support_descriptors_check (descriptors);
-+ TEST_COMPARE (xlseek (fd, 0, SEEK_END), 2 * sizeof (struct utmpx));
-+ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0),
-+ sizeof (buffer));
-+ TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]),
-+ &buffer, sizeof (buffer));
-+ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), sizeof (buffer)),
-+ sizeof (buffer));
-+ TEST_COMPARE_BLOB (&entries[1], sizeof (entries[1]),
-+ &buffer, sizeof (buffer));
-+ }
-+
-+ support_descriptors_free (descriptors);
-+ free (path);
-+ xclose (fd);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/login/tst-utmp.c b/login/tst-utmp.c
-index ce48e8326e..02d0c1fe8c 100644
---- a/login/tst-utmp.c
-+++ b/login/tst-utmp.c
-@@ -39,8 +39,6 @@
- #endif
-
-
--#if defined UTMPX || _HAVE_UT_TYPE
--
- /* Prototype for our test function. */
- static int do_test (int argc, char *argv[]);
-
-@@ -75,11 +73,7 @@ do_prepare (int argc, char *argv[])
-
- struct utmp entry[] =
- {
--#if defined UTMPX || _HAVE_UT_TV
- #define UT(a) .ut_tv = { .tv_sec = (a)}
--#else
--#define UT(a) .ut_time = (a)
--#endif
-
- { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) },
- { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) },
-@@ -167,11 +161,7 @@ simulate_login (const char *line, const char *user)
- entry[n].ut_pid = (entry_pid += 27);
- entry[n].ut_type = USER_PROCESS;
- strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user));
--#if defined UTMPX || _HAVE_UT_TV - 0
- entry[n].ut_tv.tv_sec = (entry_time += 1000);
--#else
-- entry[n].ut_time = (entry_time += 1000);
--#endif
- setutent ();
-
- if (pututline (&entry[n]) == NULL)
-@@ -201,11 +191,7 @@ simulate_logout (const char *line)
- {
- entry[n].ut_type = DEAD_PROCESS;
- strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user));
--#if defined UTMPX || _HAVE_UT_TV - 0
- entry[n].ut_tv.tv_sec = (entry_time += 1000);
--#else
-- entry[n].ut_time = (entry_time += 1000);
--#endif
- setutent ();
-
- if (pututline (&entry[n]) == NULL)
-@@ -390,14 +376,3 @@ do_test (int argc, char *argv[])
-
- return result;
- }
--
--#else
--
--/* No field 'ut_type' in struct utmp. */
--int
--main (void)
--{
-- return 0;
--}
--
--#endif
-diff --git a/login/updwtmp.c b/login/updwtmp.c
-index b9bccd9b67..387e580828 100644
---- a/login/updwtmp.c
-+++ b/login/updwtmp.c
-@@ -29,7 +29,7 @@ __updwtmp (const char *wtmp_file, const struct utmp *utmp)
- {
- const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file);
-
-- (*__libc_utmp_file_functions.updwtmp) (file_name, utmp);
-+ __libc_updwtmp (file_name, utmp);
- }
- libc_hidden_def (__updwtmp)
- weak_alias (__updwtmp, updwtmp)
-diff --git a/login/utmp-private.h b/login/utmp-private.h
-index a82a923657..d60461d644 100644
---- a/login/utmp-private.h
-+++ b/login/utmp-private.h
-@@ -24,24 +24,17 @@
- #include <utmp.h>
- #include <libc-lock.h>
-
--/* The structure describing the functions in a backend. */
--struct utfuncs
--{
-- int (*setutent) (void);
-- int (*getutent_r) (struct utmp *, struct utmp **);
-- int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **);
-- int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **);
-- struct utmp *(*pututline) (const struct utmp *);
-- void (*endutent) (void);
-- int (*updwtmp) (const char *, const struct utmp *);
--};
--
--/* The tables from the services. */
--extern const struct utfuncs __libc_utmp_file_functions attribute_hidden;
--extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden;
--
--/* Currently selected backend. */
--extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden;
-+/* These functions check for initialization, but not perform any
-+ locking. */
-+int __libc_setutent (void) attribute_hidden;
-+int __libc_getutent_r (struct utmp *, struct utmp **) attribute_hidden;
-+int __libc_getutid_r (const struct utmp *, struct utmp *, struct utmp **)
-+ attribute_hidden;
-+int __libc_getutline_r (const struct utmp *, struct utmp *, struct utmp **)
-+ attribute_hidden;
-+struct utmp *__libc_pututline (const struct utmp *) attribute_hidden;
-+void __libc_endutent (void) attribute_hidden;
-+int __libc_updwtmp (const char *, const struct utmp *) attribute_hidden;
-
- /* Current file name. */
- extern const char *__libc_utmp_file_name attribute_hidden;
-diff --git a/login/utmp_file.c b/login/utmp_file.c
-index b19d3caf0d..e98bc31899 100644
---- a/login/utmp_file.c
-+++ b/login/utmp_file.c
-@@ -43,6 +43,25 @@ static off64_t file_offset;
- /* Cache for the last read entry. */
- static struct utmp last_entry;
-
-+/* Returns true if *ENTRY matches last_entry, based on
-+ data->ut_type. */
-+static bool
-+matches_last_entry (const struct utmp *data)
-+{
-+ if (file_offset <= 0)
-+ /* Nothing has been read. last_entry is stale and cannot match. */
-+ return false;
-+
-+ if (data->ut_type == RUN_LVL
-+ || data->ut_type == BOOT_TIME
-+ || data->ut_type == OLD_TIME
-+ || data->ut_type == NEW_TIME)
-+ /* For some entry types, only a type match is required. */
-+ return data->ut_type == last_entry.ut_type;
-+ else
-+ /* For the process-related entries, a full match is needed. */
-+ return __utmp_equal (&last_entry, data);
-+}
-
- /* Locking timeout. */
- #ifndef TIMEOUT
-@@ -52,90 +71,70 @@ static struct utmp last_entry;
- /* Do-nothing handler for locking timeout. */
- static void timeout_handler (int signum) {};
-
--/* LOCK_FILE(fd, type) failure_statement
-- attempts to get a lock on the utmp file referenced by FD. If it fails,
-- the failure_statement is executed, otherwise it is skipped.
-- LOCKING_FAILED()
-- jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE.
-- UNLOCK_FILE(fd)
-- unlocks the utmp file referenced by FD and performs the cleanup of
-- LOCK_FILE.
-- */
--#define LOCK_FILE(fd, type) \
--{ \
-- struct flock fl; \
-- struct sigaction action, old_action; \
-- unsigned int old_timeout; \
-- \
-- /* Cancel any existing alarm. */ \
-- old_timeout = alarm (0); \
-- \
-- /* Establish signal handler. */ \
-- action.sa_handler = timeout_handler; \
-- __sigemptyset (&action.sa_mask); \
-- action.sa_flags = 0; \
-- __sigaction (SIGALRM, &action, &old_action); \
-- \
-- alarm (TIMEOUT); \
-- \
-- /* Try to get the lock. */ \
-- memset (&fl, '\0', sizeof (struct flock)); \
-- fl.l_type = (type); \
-- fl.l_whence = SEEK_SET; \
-- if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0)
--
--#define LOCKING_FAILED() \
-- goto unalarm_return
--
--#define UNLOCK_FILE(fd) \
-- /* Unlock the file. */ \
-- fl.l_type = F_UNLCK; \
-- __fcntl64_nocancel ((fd), F_SETLKW, &fl); \
-- \
-- unalarm_return: \
-- /* Reset the signal handler and alarm. We must reset the alarm \
-- before resetting the handler so our alarm does not generate a \
-- spurious SIGALRM seen by the user. However, we cannot just set \
-- the user's old alarm before restoring the handler, because then \
-- it's possible our handler could catch the user alarm's SIGARLM \
-- and then the user would never see the signal he expected. */ \
-- alarm (0); \
-- __sigaction (SIGALRM, &old_action, NULL); \
-- if (old_timeout != 0) \
-- alarm (old_timeout); \
--} while (0)
--
--
--/* Functions defined here. */
--static int setutent_file (void);
--static int getutent_r_file (struct utmp *buffer, struct utmp **result);
--static int getutid_r_file (const struct utmp *key, struct utmp *buffer,
-- struct utmp **result);
--static int getutline_r_file (const struct utmp *key, struct utmp *buffer,
-- struct utmp **result);
--static struct utmp *pututline_file (const struct utmp *data);
--static void endutent_file (void);
--static int updwtmp_file (const char *file, const struct utmp *utmp);
--
--/* Jump table for file functions. */
--const struct utfuncs __libc_utmp_file_functions =
-+
-+/* try_file_lock (LOCKING, FD, TYPE) returns true if the locking
-+ operation failed and recovery needs to be performed.
-+
-+ file_unlock (FD) removes the lock (which must have been
-+ successfully acquired). */
-+
-+static bool
-+try_file_lock (int fd, int type)
- {
-- setutent_file,
-- getutent_r_file,
-- getutid_r_file,
-- getutline_r_file,
-- pututline_file,
-- endutent_file,
-- updwtmp_file
--};
-+ /* Cancel any existing alarm. */
-+ int old_timeout = alarm (0);
-+
-+ /* Establish signal handler. */
-+ struct sigaction old_action;
-+ struct sigaction action;
-+ action.sa_handler = timeout_handler;
-+ __sigemptyset (&action.sa_mask);
-+ action.sa_flags = 0;
-+ __sigaction (SIGALRM, &action, &old_action);
-+
-+ alarm (TIMEOUT);
-+
-+ /* Try to get the lock. */
-+ struct flock64 fl =
-+ {
-+ .l_type = type,
-+ .l_whence = SEEK_SET,
-+ };
-+
-+ bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0;
-+ int saved_errno = errno;
-+
-+ /* Reset the signal handler and alarm. We must reset the alarm
-+ before resetting the handler so our alarm does not generate a
-+ spurious SIGALRM seen by the user. However, we cannot just set
-+ the user's old alarm before restoring the handler, because then
-+ it's possible our handler could catch the user alarm's SIGARLM and
-+ then the user would never see the signal he expected. */
-+ alarm (0);
-+ __sigaction (SIGALRM, &old_action, NULL);
-+ if (old_timeout != 0)
-+ alarm (old_timeout);
-+
-+ __set_errno (saved_errno);
-+ return status;
-+}
-
-+static void
-+file_unlock (int fd)
-+{
-+ struct flock64 fl =
-+ {
-+ .l_type = F_UNLCK,
-+ };
-+ __fcntl64_nocancel (fd, F_SETLKW, &fl);
-+}
-
- #ifndef TRANSFORM_UTMP_FILE_NAME
- # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
- #endif
-
--static int
--setutent_file (void)
-+int
-+__libc_setutent (void)
- {
- if (file_fd < 0)
- {
-@@ -153,56 +152,68 @@ setutent_file (void)
- __lseek64 (file_fd, 0, SEEK_SET);
- file_offset = 0;
-
-- /* Make sure the entry won't match. */
--#if _HAVE_UT_TYPE - 0
-- last_entry.ut_type = -1;
--#else
-- last_entry.ut_line[0] = '\177';
--# if _HAVE_UT_ID - 0
-- last_entry.ut_id[0] = '\0';
--# endif
--#endif
--
- return 1;
- }
-
-+/* Preform initialization if necessary. */
-+static bool
-+maybe_setutent (void)
-+{
-+ return file_fd >= 0 || __libc_setutent ();
-+}
-
--static int
--getutent_r_file (struct utmp *buffer, struct utmp **result)
-+/* Reads the entry at file_offset, storing it in last_entry and
-+ updating file_offset on success. Returns -1 for a read error, 0
-+ for EOF, and 1 for a successful read. last_entry and file_offset
-+ are only updated on a successful and complete read. */
-+static ssize_t
-+read_last_entry (void)
- {
-- ssize_t nbytes;
-+ struct utmp buffer;
-+ ssize_t nbytes = __pread64_nocancel (file_fd, &buffer, sizeof (buffer),
-+ file_offset);
-+ if (nbytes < 0)
-+ return -1;
-+ else if (nbytes != sizeof (buffer))
-+ /* Assume EOF. */
-+ return 0;
-+ else
-+ {
-+ last_entry = buffer;
-+ file_offset += sizeof (buffer);
-+ return 1;
-+ }
-+}
-
-- assert (file_fd >= 0);
-+int
-+__libc_getutent_r (struct utmp *buffer, struct utmp **result)
-+{
-+ int saved_errno = errno;
-
-- if (file_offset == -1l)
-+ if (!maybe_setutent ())
- {
- /* Not available. */
- *result = NULL;
- return -1;
- }
-
-- LOCK_FILE (file_fd, F_RDLCK)
-- {
-- nbytes = 0;
-- LOCKING_FAILED ();
-- }
--
-- /* Read the next entry. */
-- nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp));
-+ if (try_file_lock (file_fd, F_RDLCK))
-+ return -1;
-
-- UNLOCK_FILE (file_fd);
-+ ssize_t nbytes = read_last_entry ();
-+ file_unlock (file_fd);
-
-- if (nbytes != sizeof (struct utmp))
-+ if (nbytes <= 0) /* Read error or EOF. */
- {
-- if (nbytes != 0)
-- file_offset = -1l;
-+ if (nbytes == 0)
-+ /* errno should be unchanged to indicate success. A premature
-+ EOF is treated like an EOF (missing complete record at the
-+ end). */
-+ __set_errno (saved_errno);
- *result = NULL;
- return -1;
- }
-
-- /* Update position pointer. */
-- file_offset += sizeof (struct utmp);
--
- memcpy (buffer, &last_entry, sizeof (struct utmp));
- *result = buffer;
-
-@@ -210,82 +221,55 @@ getutent_r_file (struct utmp *buffer, struct utmp **result)
- }
-
-
-+/* Search for *ID, updating last_entry and file_offset. Return 0 on
-+ success and -1 on failure. Does not perform locking; for that see
-+ internal_getut_r below. */
- static int
--internal_getut_r (const struct utmp *id, struct utmp *buffer,
-- bool *lock_failed)
-+internal_getut_nolock (const struct utmp *id)
- {
-- int result = -1;
--
-- LOCK_FILE (file_fd, F_RDLCK)
-- {
-- *lock_failed = true;
-- LOCKING_FAILED ();
-- }
--
--#if _HAVE_UT_TYPE - 0
-- if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
-- || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
-+ while (1)
- {
-- /* Search for next entry with type RUN_LVL, BOOT_TIME,
-- OLD_TIME, or NEW_TIME. */
--
-- while (1)
-+ ssize_t nbytes = read_last_entry ();
-+ if (nbytes < 0)
-+ return -1;
-+ if (nbytes == 0)
- {
-- /* Read the next entry. */
-- if (__read_nocancel (file_fd, buffer, sizeof (struct utmp))
-- != sizeof (struct utmp))
-- {
-- __set_errno (ESRCH);
-- file_offset = -1l;
-- goto unlock_return;
-- }
-- file_offset += sizeof (struct utmp);
--
-- if (id->ut_type == buffer->ut_type)
-- break;
-+ /* End of file reached. */
-+ __set_errno (ESRCH);
-+ return -1;
- }
-- }
-- else
--#endif /* _HAVE_UT_TYPE */
-- {
-- /* Search for the next entry with the specified ID and with type
-- INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */
-
-- while (1)
-- {
-- /* Read the next entry. */
-- if (__read_nocancel (file_fd, buffer, sizeof (struct utmp))
-- != sizeof (struct utmp))
-- {
-- __set_errno (ESRCH);
-- file_offset = -1l;
-- goto unlock_return;
-- }
-- file_offset += sizeof (struct utmp);
--
-- if (__utmp_equal (buffer, id))
-- break;
-- }
-+ if (matches_last_entry (id))
-+ break;
- }
-
-- result = 0;
-+ return 0;
-+}
-
--unlock_return:
-- UNLOCK_FILE (file_fd);
-+/* Search for *ID, updating last_entry and file_offset. Return 0 on
-+ success and -1 on failure. If the locking operation failed, write
-+ true to *LOCK_FAILED. */
-+static int
-+internal_getut_r (const struct utmp *id, bool *lock_failed)
-+{
-+ if (try_file_lock (file_fd, F_RDLCK))
-+ {
-+ *lock_failed = true;
-+ return -1;
-+ }
-
-+ int result = internal_getut_nolock (id);
-+ file_unlock (file_fd);
- return result;
- }
-
--
- /* For implementing this function we don't use the getutent_r function
- because we can avoid the reposition on every new entry this way. */
--static int
--getutid_r_file (const struct utmp *id, struct utmp *buffer,
-- struct utmp **result)
-+int
-+__libc_getutid_r (const struct utmp *id, struct utmp *buffer,
-+ struct utmp **result)
- {
-- assert (file_fd >= 0);
--
-- if (file_offset == -1l)
-+ if (!maybe_setutent ())
- {
- *result = NULL;
- return -1;
-@@ -294,7 +278,7 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer,
- /* We don't have to distinguish whether we can lock the file or
- whether there is no entry. */
- bool lock_failed = false;
-- if (internal_getut_r (id, &last_entry, &lock_failed) < 0)
-+ if (internal_getut_r (id, &lock_failed) < 0)
- {
- *result = NULL;
- return -1;
-@@ -306,69 +290,65 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer,
- return 0;
- }
-
--
- /* For implementing this function we don't use the getutent_r function
- because we can avoid the reposition on every new entry this way. */
--static int
--getutline_r_file (const struct utmp *line, struct utmp *buffer,
-- struct utmp **result)
-+int
-+__libc_getutline_r (const struct utmp *line, struct utmp *buffer,
-+ struct utmp **result)
- {
-- assert (file_fd >= 0);
--
-- if (file_offset == -1l)
-+ if (!maybe_setutent ())
- {
- *result = NULL;
- return -1;
- }
-
-- LOCK_FILE (file_fd, F_RDLCK)
-+ if (try_file_lock (file_fd, F_RDLCK))
- {
- *result = NULL;
-- LOCKING_FAILED ();
-+ return -1;
- }
-
- while (1)
- {
-- /* Read the next entry. */
-- if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp))
-- != sizeof (struct utmp))
-+ ssize_t nbytes = read_last_entry ();
-+ if (nbytes < 0)
-+ {
-+ file_unlock (file_fd);
-+ *result = NULL;
-+ return -1;
-+ }
-+ if (nbytes == 0)
- {
-+ /* End of file reached. */
-+ file_unlock (file_fd);
- __set_errno (ESRCH);
-- file_offset = -1l;
- *result = NULL;
-- goto unlock_return;
-+ return -1;
- }
-- file_offset += sizeof (struct utmp);
-
- /* Stop if we found a user or login entry. */
-- if (
--#if _HAVE_UT_TYPE - 0
-- (last_entry.ut_type == USER_PROCESS
-+ if ((last_entry.ut_type == USER_PROCESS
- || last_entry.ut_type == LOGIN_PROCESS)
-- &&
--#endif
-- !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line))
-+ && (strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line)
-+ == 0))
- break;
- }
-
-+ file_unlock (file_fd);
- memcpy (buffer, &last_entry, sizeof (struct utmp));
- *result = buffer;
-
--unlock_return:
-- UNLOCK_FILE (file_fd);
--
-- return ((*result == NULL) ? -1 : 0);
-+ return 0;
- }
-
-
--static struct utmp *
--pututline_file (const struct utmp *data)
-+struct utmp *
-+__libc_pututline (const struct utmp *data)
- {
-- struct utmp buffer;
-- struct utmp *pbuf;
-- int found;
-+ if (!maybe_setutent ())
-+ return NULL;
-
-- assert (file_fd >= 0);
-+ struct utmp *pbuf;
-
- if (! file_writable)
- {
-@@ -380,8 +360,7 @@ pututline_file (const struct utmp *data)
- if (new_fd == -1)
- return NULL;
-
-- if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1
-- || __dup2 (new_fd, file_fd) < 0)
-+ if (__dup2 (new_fd, file_fd) < 0)
- {
- __close_nocancel_nostatus (new_fd);
- return NULL;
-@@ -390,95 +369,96 @@ pututline_file (const struct utmp *data)
- file_writable = true;
- }
-
-+ /* Exclude other writers before validating the cache. */
-+ if (try_file_lock (file_fd, F_WRLCK))
-+ return NULL;
-+
- /* Find the correct place to insert the data. */
-- if (file_offset > 0
-- && (
--#if _HAVE_UT_TYPE - 0
-- (last_entry.ut_type == data->ut_type
-- && (last_entry.ut_type == RUN_LVL
-- || last_entry.ut_type == BOOT_TIME
-- || last_entry.ut_type == OLD_TIME
-- || last_entry.ut_type == NEW_TIME))
-- ||
--#endif
-- __utmp_equal (&last_entry, data)))
-- found = 1;
-- else
-+ bool found = false;
-+ if (matches_last_entry (data))
- {
-- bool lock_failed = false;
-- found = internal_getut_r (data, &buffer, &lock_failed);
--
-- if (__builtin_expect (lock_failed, false))
-+ /* Read back the entry under the write lock. */
-+ file_offset -= sizeof (last_entry);
-+ ssize_t nbytes = read_last_entry ();
-+ if (nbytes < 0)
- {
-- __set_errno (EAGAIN);
-+ file_unlock (file_fd);
- return NULL;
- }
-- }
-
-- LOCK_FILE (file_fd, F_WRLCK)
-- {
-- pbuf = NULL;
-- LOCKING_FAILED ();
-+ if (nbytes == 0)
-+ /* End of file reached. */
-+ found = false;
-+ else
-+ found = matches_last_entry (data);
- }
-
-- if (found < 0)
-+ if (!found)
-+ /* Search forward for the entry. */
-+ found = internal_getut_nolock (data) >= 0;
-+
-+ off64_t write_offset;
-+ if (!found)
- {
- /* We append the next entry. */
-- file_offset = __lseek64 (file_fd, 0, SEEK_END);
-- if (file_offset % sizeof (struct utmp) != 0)
-- {
-- file_offset -= file_offset % sizeof (struct utmp);
-- __ftruncate64 (file_fd, file_offset);
--
-- if (__lseek64 (file_fd, 0, SEEK_END) < 0)
-- {
-- pbuf = NULL;
-- goto unlock_return;
-- }
-- }
-+ write_offset = __lseek64 (file_fd, 0, SEEK_END);
-+
-+ /* Round down to the next multiple of the entry size. This
-+ ensures any partially-written record is overwritten by the
-+ new record. */
-+ write_offset = (write_offset / sizeof (struct utmp)
-+ * sizeof (struct utmp));
- }
- else
-+ /* Overwrite last_entry. */
-+ write_offset = file_offset - sizeof (struct utmp);
-+
-+ /* Write the new data. */
-+ ssize_t nbytes;
-+ if (__lseek64 (file_fd, write_offset, SEEK_SET) < 0
-+ || (nbytes = __write_nocancel (file_fd, data, sizeof (struct utmp))) < 0)
- {
-- /* We replace the just read entry. */
-- file_offset -= sizeof (struct utmp);
-- __lseek64 (file_fd, file_offset, SEEK_SET);
-+ /* There is no need to recover the file position because all
-+ reads use pread64, and any future write is preceded by
-+ another seek. */
-+ file_unlock (file_fd);
-+ return NULL;
- }
-
-- /* Write the new data. */
-- if (__write_nocancel (file_fd, data, sizeof (struct utmp))
-- != sizeof (struct utmp))
-+ if (nbytes != sizeof (struct utmp))
- {
- /* If we appended a new record this is only partially written.
- Remove it. */
-- if (found < 0)
-- (void) __ftruncate64 (file_fd, file_offset);
-- pbuf = NULL;
-- }
-- else
-- {
-- file_offset += sizeof (struct utmp);
-- pbuf = (struct utmp *) data;
-+ if (!found)
-+ (void) __ftruncate64 (file_fd, write_offset);
-+ file_unlock (file_fd);
-+ /* Assume that the write failure was due to missing disk
-+ space. */
-+ __set_errno (ENOSPC);
-+ return NULL;
- }
-
-- unlock_return:
-- UNLOCK_FILE (file_fd);
-+ file_unlock (file_fd);
-+ file_offset = write_offset + sizeof (struct utmp);
-+ pbuf = (struct utmp *) data;
-
- return pbuf;
- }
-
-
--static void
--endutent_file (void)
-+void
-+__libc_endutent (void)
- {
-- assert (file_fd >= 0);
--
-- __close_nocancel_nostatus (file_fd);
-- file_fd = -1;
-+ if (file_fd >= 0)
-+ {
-+ __close_nocancel_nostatus (file_fd);
-+ file_fd = -1;
-+ }
- }
-
-
--static int
--updwtmp_file (const char *file, const struct utmp *utmp)
-+int
-+__libc_updwtmp (const char *file, const struct utmp *utmp)
- {
- int result = -1;
- off64_t offset;
-@@ -489,8 +469,11 @@ updwtmp_file (const char *file, const struct utmp *utmp)
- if (fd < 0)
- return -1;
-
-- LOCK_FILE (fd, F_WRLCK)
-- LOCKING_FAILED ();
-+ if (try_file_lock (fd, F_WRLCK))
-+ {
-+ __close_nocancel_nostatus (fd);
-+ return -1;
-+ }
-
- /* Remember original size of log file. */
- offset = __lseek64 (fd, 0, SEEK_END);
-@@ -516,7 +499,7 @@ updwtmp_file (const char *file, const struct utmp *utmp)
- result = 0;
-
- unlock_return:
-- UNLOCK_FILE (fd);
-+ file_unlock (fd);
-
- /* Close WTMP file. */
- __close_nocancel_nostatus (fd);
-diff --git a/login/utmpname.c b/login/utmpname.c
-index c3da183d5b..8f94b19caf 100644
---- a/login/utmpname.c
-+++ b/login/utmpname.c
-@@ -42,8 +42,7 @@ __utmpname (const char *file)
- __libc_lock_lock (__libc_utmp_lock);
-
- /* Close the old file. */
-- (*__libc_utmp_jump_table->endutent) ();
-- __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
-+ __libc_endutent ();
-
- if (strcmp (file, __libc_utmp_file_name) != 0)
- {
-diff --git a/malloc/Makefile b/malloc/Makefile
-index d2fba29953..9698574bba 100644
---- a/malloc/Makefile
-+++ b/malloc/Makefile
-@@ -27,7 +27,7 @@ headers := $(dist-headers) obstack.h mcheck.h
- tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
- tst-mcheck tst-mallocfork tst-trim1 \
- tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \
-- tst-pvalloc tst-memalign tst-mallopt \
-+ tst-pvalloc tst-pvalloc-fortify tst-memalign tst-mallopt \
- tst-malloc-backtrace tst-malloc-thread-exit \
- tst-malloc-thread-fail tst-malloc-fork-deadlock \
- tst-mallocfork2 \
-@@ -54,7 +54,7 @@ tests-internal += \
- tst-dynarray-at-fail \
-
- ifneq (no,$(have-tunables))
--tests += tst-malloc-usable-tunables
-+tests += tst-malloc-usable-tunables tst-mxfast
- tests-static += tst-malloc-usable-static-tunables
- endif
-
-@@ -196,6 +196,8 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV)
- tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3
- tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV)
-
-+tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
-+
- ifeq ($(experimental-malloc),yes)
- CPPFLAGS-malloc.c += -DUSE_TCACHE=1
- else
-diff --git a/malloc/arena.c b/malloc/arena.c
-index 8309c1334c..a32eb403ec 100644
---- a/malloc/arena.c
-+++ b/malloc/arena.c
-@@ -236,6 +236,7 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t)
- TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t)
- TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t)
- #endif
-+TUNABLE_CALLBACK_FNDECL (set_mxfast, size_t)
- #else
- /* Initialization routine. */
- #include <string.h>
-@@ -323,6 +324,7 @@ ptmalloc_init (void)
- TUNABLE_GET (tcache_unsorted_limit, size_t,
- TUNABLE_CALLBACK (set_tcache_unsorted_limit));
- # endif
-+ TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast));
- #else
- const char *s = NULL;
- if (__glibc_likely (_environ != NULL))
-diff --git a/malloc/malloc.c b/malloc/malloc.c
-index 00ce48cf58..8c68b21b2b 100644
---- a/malloc/malloc.c
-+++ b/malloc/malloc.c
-@@ -1621,7 +1621,7 @@ static INTERNAL_SIZE_T global_max_fast;
-
- #define set_max_fast(s) \
- global_max_fast = (((s) == 0) \
-- ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
-+ ? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
-
- static inline INTERNAL_SIZE_T
- get_max_fast (void)
-@@ -5115,6 +5115,19 @@ do_set_tcache_unsorted_limit (size_t value)
- }
- #endif
-
-+static inline int
-+__always_inline
-+do_set_mxfast (size_t value)
-+{
-+ if (value >= 0 && value <= MAX_FAST_SIZE)
-+ {
-+ LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
-+ set_max_fast (value);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
- int
- __libc_mallopt (int param_number, int value)
- {
-@@ -5134,13 +5147,7 @@ __libc_mallopt (int param_number, int value)
- switch (param_number)
- {
- case M_MXFAST:
-- if (value >= 0 && value <= MAX_FAST_SIZE)
-- {
-- LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
-- set_max_fast (value);
-- }
-- else
-- res = 0;
-+ do_set_mxfast (value);
- break;
-
- case M_TRIM_THRESHOLD:
-@@ -5406,6 +5413,12 @@ __malloc_info (int options, FILE *fp)
-
- __libc_lock_lock (ar_ptr->mutex);
-
-+ /* Account for top chunk. The top-most available chunk is
-+ treated specially and is never in any bin. See "initial_top"
-+ comments. */
-+ avail = chunksize (ar_ptr->top);
-+ nblocks = 1; /* Top always exists. */
-+
- for (size_t i = 0; i < NFASTBINS; ++i)
- {
- mchunkptr p = fastbin (ar_ptr, i);
-@@ -5491,7 +5504,7 @@ __malloc_info (int options, FILE *fp)
-
- for (size_t i = 0; i < nsizes; ++i)
- if (sizes[i].count != 0 && i != NFASTBINS)
-- fprintf (fp, " \
-+ fprintf (fp, "\
- <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
- sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
-
-diff --git a/malloc/malloc.h b/malloc/malloc.h
-index 70d8282bdc..f62c6c594c 100644
---- a/malloc/malloc.h
-+++ b/malloc/malloc.h
-@@ -71,8 +71,7 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__
-
- /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
- __size to nearest pagesize. */
--extern void *pvalloc (size_t __size) __THROW __attribute_malloc__
-- __attribute_alloc_size__ ((1)) __wur;
-+extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ __wur;
-
- /* Underlying allocation function; successive calls should return
- contiguous pieces of memory. */
-diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c
-new file mode 100644
-index 0000000000..7a7750bc71
---- /dev/null
-+++ b/malloc/tst-mxfast.c
-@@ -0,0 +1,50 @@
-+/* Test that glibc.malloc.mxfast tunable works.
-+ Copyright (C) 2019 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* This test verifies that setting the glibc.malloc.mxfast tunable to
-+ zero results in free'd blocks being returned to the small bins, not
-+ the fast bins. */
-+
-+#include <malloc.h>
-+#include <support/check.h>
-+
-+int
-+do_test (void)
-+{
-+ struct mallinfo m;
-+ char *volatile p1;
-+ char *volatile p2;
-+
-+ /* Arbitrary value; must be in default fastbin range. */
-+ p1 = malloc (3);
-+ /* Something large so that p1 isn't a "top block" */
-+ p2 = malloc (512);
-+ free (p1);
-+
-+ m = mallinfo ();
-+
-+ /* This will fail if there are any blocks in the fastbins. */
-+ TEST_COMPARE (m.smblks, 0);
-+
-+ /* To keep gcc happy. */
-+ free (p2);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/malloc/tst-pvalloc-fortify.c b/malloc/tst-pvalloc-fortify.c
-new file mode 100644
-index 0000000000..391b7fa2f5
---- /dev/null
-+++ b/malloc/tst-pvalloc-fortify.c
-@@ -0,0 +1,48 @@
-+/* Test fortify-source allocation size handling in pvalloc (bug 25401).
-+ 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; see the file COPYING.LIB. If
-+ not, see <https://www.gnu.org/licenses/>. */
-+
-+#undef _FORTIFY_SOURCE
-+#define _FORTIFY_SOURCE 2
-+#include <malloc.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/xunistd.h>
-+#include <unistd.h>
-+
-+static int
-+do_test (void)
-+{
-+ /* The test below assumes that pvalloc rounds up the allocation size
-+ to at least 8. */
-+ TEST_VERIFY (xsysconf (_SC_PAGESIZE) >= 8);
-+
-+ void *p = pvalloc (5);
-+ TEST_VERIFY_EXIT (p != NULL);
-+
-+ /* This is valid assuming the page size is at least 8 because
-+ pvalloc rounds up the allocation size to a multiple of the page
-+ size. Due to bug 25041, this used to trigger a compiler
-+ warning. */
-+ strcpy (p, "abcdefg");
-+
-+ asm ("" : : "g" (p) : "memory"); /* Optimization barrier. */
-+ TEST_VERIFY (malloc_usable_size (p) >= xsysconf (_SC_PAGESIZE));
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
-index f1bd994a10..b1695376dc 100644
---- a/misc/sys/cdefs.h
-+++ b/misc/sys/cdefs.h
-@@ -412,14 +412,6 @@
- # define __glibc_has_attribute(attr) 0
- #endif
-
--#ifdef __has_include
--/* Do not use a function-like macro, so that __has_include can inhibit
-- macro expansion. */
--# define __glibc_has_include __has_include
--#else
--# define __glibc_has_include(header) 0
--#endif
--
- #if (!defined _Noreturn \
- && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
- && !__GNUC_PREREQ (4,7))
-diff --git a/string/string.h b/string/string.h
-index c38eea971f..608ed496b9 100644
---- a/string/string.h
-+++ b/string/string.h
-@@ -33,7 +33,8 @@ __BEGIN_DECLS
- #include <stddef.h>
-
- /* Tell the caller that we provide correct C++ prototypes. */
--#if defined __cplusplus && __GNUC_PREREQ (4, 4)
-+#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \
-+ || __glibc_clang_prereq (3, 5))
- # define __CORRECT_ISO_CPP_STRING_H_PROTO
- #endif
-
-diff --git a/string/test-strstr.c b/string/test-strstr.c
-index df6dbc251e..daed9a2705 100644
---- a/string/test-strstr.c
-+++ b/string/test-strstr.c
-@@ -139,16 +139,45 @@ check1 (void)
- static void
- check2 (void)
- {
-- const char s1[] = ", enable_static, \0, enable_shared, ";
-+ const char s1_stack[] = ", enable_static, \0, enable_shared, ";
-+ const size_t s1_byte_count = 18;
-+ const char *s2_stack = &(s1_stack[s1_byte_count]);
-+ const size_t s2_byte_count = 18;
- char *exp_result;
-- char *s2 = (void *) buf1 + page_size - 18;
-+ const size_t page_size_real = getpagesize ();
-
-- strcpy (s2, s1);
-- exp_result = stupid_strstr (s1, s1 + 18);
-+ /* Haystack at end of page. The following page is protected. */
-+ char *s1_page_end = (void *) buf1 + page_size - s1_byte_count;
-+ strcpy (s1_page_end, s1_stack);
-+
-+ /* Haystack which crosses a page boundary.
-+ Note: page_size is at least 2 * getpagesize. See test_init. */
-+ char *s1_page_cross = (void *) buf1 + page_size_real - 8;
-+ strcpy (s1_page_cross, s1_stack);
-+
-+ /* Needle at end of page. The following page is protected. */
-+ char *s2_page_end = (void *) buf2 + page_size - s2_byte_count;
-+ strcpy (s2_page_end, s2_stack);
-+
-+ /* Needle which crosses a page boundary.
-+ Note: page_size is at least 2 * getpagesize. See test_init. */
-+ char *s2_page_cross = (void *) buf2 + page_size_real - 8;
-+ strcpy (s2_page_cross, s2_stack);
-+
-+ exp_result = stupid_strstr (s1_stack, s2_stack);
- FOR_EACH_IMPL (impl, 0)
- {
-- check_result (impl, s1, s1 + 18, exp_result);
-- check_result (impl, s2, s1 + 18, exp_result);
-+ check_result (impl, s1_stack, s2_stack, exp_result);
-+ check_result (impl, s1_stack, s2_page_end, exp_result);
-+ check_result (impl, s1_stack, s2_page_cross, exp_result);
-+
-+ check_result (impl, s1_page_end, s2_stack, exp_result);
-+ check_result (impl, s1_page_end, s2_page_end, exp_result);
-+ check_result (impl, s1_page_end, s2_page_cross, exp_result);
-+
-+ check_result (impl, s1_page_cross, s2_stack, exp_result);
-+ check_result (impl, s1_page_cross, s2_page_end, exp_result);
-+ check_result (impl, s1_page_cross, s2_page_cross, exp_result);
- }
- }
-
-diff --git a/sysdeps/alpha/fpu/libm-test-ulps b/sysdeps/alpha/fpu/libm-test-ulps
-index 0f77dd2ed0..89c4527a81 100644
---- a/sysdeps/alpha/fpu/libm-test-ulps
-+++ b/sysdeps/alpha/fpu/libm-test-ulps
-@@ -1084,10 +1084,10 @@ ildouble: 1
- ldouble: 1
-
- Function: Real part of "cpow_downward":
--double: 2
--float: 4
--idouble: 2
--ifloat: 4
-+double: 5
-+float: 8
-+idouble: 5
-+ifloat: 8
- ildouble: 6
- ldouble: 6
-
-@@ -1100,10 +1100,10 @@ ildouble: 2
- ldouble: 2
-
- Function: Real part of "cpow_towardzero":
--double: 2
--float: 4
--idouble: 2
--ifloat: 4
-+double: 5
-+float: 8
-+idouble: 5
-+ifloat: 8
- ildouble: 6
- ldouble: 6
-
-diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h
-index f3d862651e..724c3e5e71 100644
---- a/sysdeps/generic/not-cancel.h
-+++ b/sysdeps/generic/not-cancel.h
-@@ -41,6 +41,8 @@
- (void) __close (fd)
- #define __read_nocancel(fd, buf, n) \
- __read (fd, buf, n)
-+#define __pread64_nocancel(fd, buf, count, offset) \
-+ __pread64 (fd, buf, count, offset)
- #define __write_nocancel(fd, buf, n) \
- __write (fd, buf, n)
- #define __writev_nocancel_nostatus(fd, iov, n) \
-diff --git a/sysdeps/generic/utmp-equal.h b/sysdeps/generic/utmp-equal.h
-index d077147a7a..d61cbb3300 100644
---- a/sysdeps/generic/utmp-equal.h
-+++ b/sysdeps/generic/utmp-equal.h
-@@ -27,26 +27,16 @@
- static int
- __utmp_equal (const struct utmp *entry, const struct utmp *match)
- {
-- return
-- (
--#if _HAVE_UT_TYPE - 0
-- (entry->ut_type == INIT_PROCESS
-- || entry->ut_type == LOGIN_PROCESS
-- || entry->ut_type == USER_PROCESS
-- || entry->ut_type == DEAD_PROCESS)
-- &&
-- (match->ut_type == INIT_PROCESS
-- || match->ut_type == LOGIN_PROCESS
-- || match->ut_type == USER_PROCESS
-- || match->ut_type == DEAD_PROCESS)
-- &&
--#endif
--#if _HAVE_UT_ID - 0
-- (entry->ut_id[0] && match->ut_id[0]
-- ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
-- : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
--#else
-- strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
--#endif
-- );
-+ return (entry->ut_type == INIT_PROCESS
-+ || entry->ut_type == LOGIN_PROCESS
-+ || entry->ut_type == USER_PROCESS
-+ || entry->ut_type == DEAD_PROCESS)
-+ && (match->ut_type == INIT_PROCESS
-+ || match->ut_type == LOGIN_PROCESS
-+ || match->ut_type == USER_PROCESS
-+ || match->ut_type == DEAD_PROCESS)
-+ && (entry->ut_id[0] && match->ut_id[0]
-+ ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
-+ : (strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line)
-+ == 0));
- }
-diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h
-deleted file mode 100644
-index 7357034cb6..0000000000
---- a/sysdeps/gnu/bits/utmp.h
-+++ /dev/null
-@@ -1,126 +0,0 @@
--/* The `struct utmp' type, describing entries in the utmp file. GNU version.
-- Copyright (C) 1993-2019 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with the GNU C Library; if not, see
-- <http://www.gnu.org/licenses/>. */
--
--#ifndef _UTMP_H
--# error "Never include <bits/utmp.h> directly; use <utmp.h> instead."
--#endif
--
--#include <paths.h>
--#include <sys/time.h>
--#include <sys/types.h>
--#include <bits/wordsize.h>
--
--
--#define UT_LINESIZE 32
--#define UT_NAMESIZE 32
--#define UT_HOSTSIZE 256
--
--
--/* The structure describing an entry in the database of
-- previous logins. */
--struct lastlog
-- {
--#if __WORDSIZE_TIME64_COMPAT32
-- int32_t ll_time;
--#else
-- __time_t ll_time;
--#endif
-- char ll_line[UT_LINESIZE];
-- char ll_host[UT_HOSTSIZE];
-- };
--
--
--/* The structure describing the status of a terminated process. This
-- type is used in `struct utmp' below. */
--struct exit_status
-- {
-- short int e_termination; /* Process termination status. */
-- short int e_exit; /* Process exit status. */
-- };
--
--
--/* The structure describing an entry in the user accounting database. */
--struct utmp
--{
-- short int ut_type; /* Type of login. */
-- pid_t ut_pid; /* Process ID of login process. */
-- char ut_line[UT_LINESIZE]
-- __attribute_nonstring__; /* Devicename. */
-- char ut_id[4]; /* Inittab ID. */
-- char ut_user[UT_NAMESIZE]
-- __attribute_nonstring__; /* Username. */
-- char ut_host[UT_HOSTSIZE]
-- __attribute_nonstring__; /* Hostname for remote login. */
-- struct exit_status ut_exit; /* Exit status of a process marked
-- as DEAD_PROCESS. */
--/* The ut_session and ut_tv fields must be the same size when compiled
-- 32- and 64-bit. This allows data files and shared memory to be
-- shared between 32- and 64-bit applications. */
--#if __WORDSIZE_TIME64_COMPAT32
-- int32_t ut_session; /* Session ID, used for windowing. */
-- struct
-- {
-- int32_t tv_sec; /* Seconds. */
-- int32_t tv_usec; /* Microseconds. */
-- } ut_tv; /* Time entry was made. */
--#else
-- long int ut_session; /* Session ID, used for windowing. */
-- struct timeval ut_tv; /* Time entry was made. */
--#endif
--
-- int32_t ut_addr_v6[4]; /* Internet address of remote host. */
-- char __glibc_reserved[20]; /* Reserved for future use. */
--};
--
--/* Backwards compatibility hacks. */
--#define ut_name ut_user
--#ifndef _NO_UT_TIME
--/* We have a problem here: `ut_time' is also used otherwise. Define
-- _NO_UT_TIME if the compiler complains. */
--# define ut_time ut_tv.tv_sec
--#endif
--#define ut_xtime ut_tv.tv_sec
--#define ut_addr ut_addr_v6[0]
--
--
--/* Values for the `ut_type' field of a `struct utmp'. */
--#define EMPTY 0 /* No valid user accounting information. */
--
--#define RUN_LVL 1 /* The system's runlevel. */
--#define BOOT_TIME 2 /* Time of system boot. */
--#define NEW_TIME 3 /* Time after system clock changed. */
--#define OLD_TIME 4 /* Time when system clock changed. */
--
--#define INIT_PROCESS 5 /* Process spawned by the init process. */
--#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
--#define USER_PROCESS 7 /* Normal process. */
--#define DEAD_PROCESS 8 /* Terminated process. */
--
--#define ACCOUNTING 9
--
--/* Old Linux name for the EMPTY type. */
--#define UT_UNKNOWN EMPTY
--
--
--/* Tell the user that we have a modern system with UT_HOST, UT_PID,
-- UT_TYPE, UT_ID and UT_TV fields. */
--#define _HAVE_UT_TYPE 1
--#define _HAVE_UT_PID 1
--#define _HAVE_UT_ID 1
--#define _HAVE_UT_TV 1
--#define _HAVE_UT_HOST 1
-diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h
-index 472a7d57d3..2beadbf587 100644
---- a/sysdeps/gnu/bits/utmpx.h
-+++ b/sysdeps/gnu/bits/utmpx.h
-@@ -56,10 +56,14 @@ struct utmpx
- {
- short int ut_type; /* Type of login. */
- __pid_t ut_pid; /* Process ID of login process. */
-- char ut_line[__UT_LINESIZE]; /* Devicename. */
-- char ut_id[4]; /* Inittab ID. */
-- char ut_user[__UT_NAMESIZE]; /* Username. */
-- char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */
-+ char ut_line[__UT_LINESIZE]
-+ __attribute_nonstring__; /* Devicename. */
-+ char ut_id[4]
-+ __attribute_nonstring__; /* Inittab ID. */
-+ char ut_user[__UT_NAMESIZE]
-+ __attribute_nonstring__; /* Username. */
-+ char ut_host[__UT_HOSTSIZE]
-+ __attribute_nonstring__; /* Hostname for remote login. */
- struct __exit_status ut_exit; /* Exit status of a process marked
- as DEAD_PROCESS. */
-
-diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps
-index d0c4dea001..2c61a7ae91 100644
---- a/sysdeps/hppa/fpu/libm-test-ulps
-+++ b/sysdeps/hppa/fpu/libm-test-ulps
-@@ -544,9 +544,9 @@ idouble: 1
- ifloat: 1
-
- Function: Imaginary part of "ccos_downward":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "ccos_towardzero":
-@@ -556,9 +556,9 @@ idouble: 1
- ifloat: 2
-
- Function: Imaginary part of "ccos_towardzero":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "ccos_upward":
-@@ -588,27 +588,27 @@ idouble: 1
- ifloat: 1
-
- Function: Real part of "ccosh_downward":
--double: 1
-+double: 2
- float: 3
--idouble: 1
-+idouble: 2
- ifloat: 3
-
- Function: Imaginary part of "ccosh_downward":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "ccosh_towardzero":
--double: 1
-+double: 2
- float: 3
--idouble: 1
-+idouble: 2
- ifloat: 3
-
- Function: Imaginary part of "ccosh_towardzero":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "ccosh_upward":
-@@ -636,27 +636,27 @@ idouble: 1
- ifloat: 2
-
- Function: Real part of "cexp_downward":
--double: 1
-+double: 2
- float: 2
--idouble: 1
-+idouble: 2
- ifloat: 2
-
- Function: Imaginary part of "cexp_downward":
--double: 1
-+double: 3
- float: 3
--idouble: 1
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "cexp_towardzero":
--double: 1
-+double: 2
- float: 2
--idouble: 1
-+idouble: 2
- ifloat: 2
-
- Function: Imaginary part of "cexp_towardzero":
--double: 1
-+double: 3
- float: 3
--idouble: 1
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "cexp_upward":
-@@ -666,9 +666,9 @@ idouble: 1
- ifloat: 2
-
- Function: Imaginary part of "cexp_upward":
--double: 1
-+double: 3
- float: 2
--idouble: 1
-+idouble: 3
- ifloat: 2
-
- Function: Real part of "clog":
-@@ -800,21 +800,21 @@ idouble: 1
- ifloat: 1
-
- Function: "cosh_downward":
--double: 1
-+double: 2
- float: 1
--idouble: 1
-+idouble: 2
- ifloat: 1
-
- Function: "cosh_towardzero":
--double: 1
-+double: 2
- float: 1
--idouble: 1
-+idouble: 2
- ifloat: 1
-
- Function: "cosh_upward":
--double: 1
-+double: 2
- float: 2
--idouble: 1
-+idouble: 2
- ifloat: 2
-
- Function: Real part of "cpow":
-@@ -834,9 +834,9 @@ ildouble: 2
- ldouble: 2
-
- Function: Real part of "cpow_downward":
--double: 4
-+double: 5
- float: 8
--idouble: 4
-+idouble: 5
- ifloat: 8
-
- Function: Imaginary part of "cpow_downward":
-@@ -846,9 +846,9 @@ idouble: 2
- ifloat: 2
-
- Function: Real part of "cpow_towardzero":
--double: 4
-+double: 5
- float: 8
--idouble: 4
-+idouble: 5
- ifloat: 8
-
- Function: Imaginary part of "cpow_towardzero":
-@@ -876,9 +876,9 @@ idouble: 1
- ifloat: 1
-
- Function: Real part of "csin_downward":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Imaginary part of "csin_downward":
-@@ -888,9 +888,9 @@ idouble: 1
- ifloat: 2
-
- Function: Real part of "csin_towardzero":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Imaginary part of "csin_towardzero":
-@@ -930,9 +930,9 @@ idouble: 2
- ifloat: 2
-
- Function: Imaginary part of "csinh_downward":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "csinh_towardzero":
-@@ -942,9 +942,9 @@ idouble: 2
- ifloat: 2
-
- Function: Imaginary part of "csinh_towardzero":
--double: 2
-+double: 3
- float: 3
--idouble: 2
-+idouble: 3
- ifloat: 3
-
- Function: Real part of "csinh_upward":
-@@ -1172,15 +1172,15 @@ ildouble: 6
- ldouble: 6
-
- Function: "exp10_downward":
--double: 2
-+double: 3
- float: 1
--idouble: 2
-+idouble: 3
- ifloat: 1
-
- Function: "exp10_towardzero":
--double: 2
-+double: 3
- float: 1
--idouble: 2
-+idouble: 3
- ifloat: 1
-
- Function: "exp10_upward":
-diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
-index 44c9901800..1307ec41de 100644
---- a/sysdeps/s390/dl-procinfo.c
-+++ b/sysdeps/s390/dl-procinfo.c
-@@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
- #if !defined PROCINFO_DECL && defined SHARED
- ._dl_s390_platforms
- #else
--PROCINFO_CLASS const char _dl_s390_platforms[9][7]
-+PROCINFO_CLASS const char _dl_s390_platforms[10][7]
- #endif
- #ifndef PROCINFO_DECL
- = {
-- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14"
-+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
- }
- #endif
- #if !defined SHARED || defined PROCINFO_DECL
-diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
-index 3b1f6a642b..689e961ced 100644
---- a/sysdeps/s390/dl-procinfo.h
-+++ b/sysdeps/s390/dl-procinfo.h
-@@ -23,7 +23,7 @@
-
- #define _DL_HWCAP_COUNT 19
-
--#define _DL_PLATFORMS_COUNT 9
-+#define _DL_PLATFORMS_COUNT 10
-
- /* The kernel provides up to 32 capability bits with elf_hwcap. */
- #define _DL_FIRST_PLATFORM 32
-diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S
-index 929b026adf..faa969849e 100644
---- a/sysdeps/s390/strstr-arch13.S
-+++ b/sysdeps/s390/strstr-arch13.S
-@@ -164,7 +164,7 @@ ENTRY(STRSTR_ARCH13)
- vfenezb %v19,%v18,%v18 /* Search zero in loaded needle bytes. */
- veclb %v19,%v21 /* Zero index <= max loaded byte index? */
- jle .Lneedle_loaded /* -> v18 contains full needle. */
-- vl %v16,0(%r3) /* Load needle beyond page boundary. */
-+ vl %v18,0(%r3) /* Load needle beyond page boundary. */
- vfenezb %v19,%v18,%v18
- j .Lneedle_loaded
- END(STRSTR_ARCH13)
-diff --git a/sysdeps/unix/alpha/getegid.S b/sysdeps/unix/alpha/getegid.S
-deleted file mode 100644
-index 167009d17a..0000000000
---- a/sysdeps/unix/alpha/getegid.S
-+++ /dev/null
-@@ -1,26 +0,0 @@
--/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with the GNU C Library. If not, see
-- <http://www.gnu.org/licenses/>. */
--
--#include <sysdep.h>
--
--
--PSEUDO (__getegid, getxgid, 0)
-- MOVE (r1, r0)
-- ret
--PSEUDO_END (__getegid)
--
--weak_alias (__getegid, getegid)
-diff --git a/sysdeps/unix/alpha/geteuid.S b/sysdeps/unix/alpha/geteuid.S
-deleted file mode 100644
-index 39413779f7..0000000000
---- a/sysdeps/unix/alpha/geteuid.S
-+++ /dev/null
-@@ -1,26 +0,0 @@
--/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with the GNU C Library. If not, see
-- <http://www.gnu.org/licenses/>. */
--
--#include <sysdep.h>
--
--
--PSEUDO (__geteuid, getxuid, 0)
-- MOVE (r1, r0)
-- ret
--PSEUDO_END (__geteuid)
--
--weak_alias (__geteuid, geteuid)
-diff --git a/sysdeps/unix/alpha/getppid.S b/sysdeps/unix/alpha/getppid.S
-deleted file mode 100644
-index 4d291181bd..0000000000
---- a/sysdeps/unix/alpha/getppid.S
-+++ /dev/null
-@@ -1,26 +0,0 @@
--/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with the GNU C Library. If not, see
-- <http://www.gnu.org/licenses/>. */
--
--#include <sysdep.h>
--
--
--PSEUDO (__getppid, getxpid, 0)
-- MOVE (r1, r0)
-- ret
--PSEUDO_END (__getppid)
--
--weak_alias (__getppid, getppid)
-diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c
-index 6c564d3b59..88971a9931 100644
---- a/sysdeps/unix/getlogin_r.c
-+++ b/sysdeps/unix/getlogin_r.c
-@@ -64,8 +64,8 @@ __getlogin_r (char *name, size_t name_len)
- held so that our search is thread-safe. */
-
- __libc_lock_lock (__libc_utmp_lock);
-- (*__libc_utmp_jump_table->setutent) ();
-- result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut);
-+ __libc_setutent ();
-+ result = __libc_getutline_r (&line, &buffer, &ut);
- if (result < 0)
- {
- if (errno == ESRCH)
-@@ -74,8 +74,7 @@ __getlogin_r (char *name, size_t name_len)
- else
- result = errno;
- }
-- (*__libc_utmp_jump_table->endutent) ();
-- __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
-+ __libc_endutent ();
- __libc_lock_unlock (__libc_utmp_lock);
-
- if (result == 0)
-diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
-index 1ab6bcbfc8..a7980a60f6 100644
---- a/sysdeps/unix/sysv/linux/Makefile
-+++ b/sysdeps/unix/sysv/linux/Makefile
-@@ -212,8 +212,8 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
- close_nocancel fcntl_nocancel nanosleep_nocancel \
- open_nocancel open64_nocancel \
- openat_nocancel openat64_nocancel \
-- pause_nocancel read_nocancel waitpid_nocancel \
-- write_nocancel statx_cp
-+ pause_nocancel read_nocancel pread64_nocancel \
-+ waitpid_nocancel write_nocancel statx_cp
-
- sysdep_headers += bits/fcntl-linux.h
-
-diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
-index 1ca102a9e2..d385085c61 100644
---- a/sysdeps/unix/sysv/linux/Versions
-+++ b/sysdeps/unix/sysv/linux/Versions
-@@ -182,6 +182,7 @@ libc {
- __syscall_rt_sigqueueinfo;
- __open_nocancel;
- __read_nocancel;
-+ __pread64_nocancel;
- __close_nocancel;
- __sigtimedwait;
- # functions used by nscd
-diff --git a/sysdeps/unix/sysv/linux/alpha/getegid.S b/sysdeps/unix/sysv/linux/alpha/getegid.S
-new file mode 100644
-index 0000000000..167009d17a
---- /dev/null
-+++ b/sysdeps/unix/sysv/linux/alpha/getegid.S
-@@ -0,0 +1,26 @@
-+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library. If not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <sysdep.h>
-+
-+
-+PSEUDO (__getegid, getxgid, 0)
-+ MOVE (r1, r0)
-+ ret
-+PSEUDO_END (__getegid)
-+
-+weak_alias (__getegid, getegid)
-diff --git a/sysdeps/unix/sysv/linux/alpha/geteuid.S b/sysdeps/unix/sysv/linux/alpha/geteuid.S
-new file mode 100644
-index 0000000000..39413779f7
---- /dev/null
-+++ b/sysdeps/unix/sysv/linux/alpha/geteuid.S
-@@ -0,0 +1,26 @@
-+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library. If not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <sysdep.h>
-+
-+
-+PSEUDO (__geteuid, getxuid, 0)
-+ MOVE (r1, r0)
-+ ret
-+PSEUDO_END (__geteuid)
-+
-+weak_alias (__geteuid, geteuid)
-diff --git a/sysdeps/unix/sysv/linux/alpha/getppid.S b/sysdeps/unix/sysv/linux/alpha/getppid.S
-new file mode 100644
-index 0000000000..4d291181bd
---- /dev/null
-+++ b/sysdeps/unix/sysv/linux/alpha/getppid.S
-@@ -0,0 +1,26 @@
-+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library. If not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <sysdep.h>
-+
-+
-+PSEUDO (__getppid, getxpid, 0)
-+ MOVE (r1, r0)
-+ ret
-+PSEUDO_END (__getppid)
-+
-+weak_alias (__getppid, getppid)
-diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h
-index 206878723f..aaccfdc2dc 100644
---- a/sysdeps/unix/sysv/linux/bits/statx.h
-+++ b/sysdeps/unix/sysv/linux/bits/statx.h
-@@ -26,11 +26,13 @@
-
- /* Use "" to work around incorrect macro expansion of the
- __has_include argument (GCC PR 80005). */
--#if __glibc_has_include ("linux/stat.h")
--# include "linux/stat.h"
--# ifdef STATX_TYPE
--# define __statx_timestamp_defined 1
--# define __statx_defined 1
-+#ifdef __has_include
-+# if __has_include ("linux/stat.h")
-+# include "linux/stat.h"
-+# ifdef STATX_TYPE
-+# define __statx_timestamp_defined 1
-+# define __statx_defined 1
-+# endif
- # endif
- #endif
-
-diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S
-index 79fa4f6147..1c0325e199 100644
---- a/sysdeps/unix/sysv/linux/hppa/clone.S
-+++ b/sysdeps/unix/sysv/linux/hppa/clone.S
-@@ -73,13 +73,18 @@ ENTRY(__clone)
- #endif
-
- /* Sanity check arguments. */
-- comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */
-- comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */
-+ comib,=,n 0,%arg0,.LerrorSanity /* no NULL function pointers */
-+ comib,=,n 0,%arg1,.LerrorSanity /* no NULL stack pointers */
-+
-+ /* Ensure stack argument is 8-byte aligned. */
-+ ldo 7(%r25),%r25
-+ depi 0,31,3,%r25
-
- /* Save the function pointer, arg, and flags on the new stack. */
- stwm %r26, 64(%r25)
- stw %r23, -60(%r25)
- stw %r24, -56(%r25)
-+
- /* Clone arguments are (int flags, void * child_stack) */
- copy %r24, %r26 /* flags are first */
- /* User stack pointer is in the correct register already */
-diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile
-index 8217f42e75..03044e7365 100644
---- a/sysdeps/unix/sysv/linux/mips/Makefile
-+++ b/sysdeps/unix/sysv/linux/mips/Makefile
-@@ -63,14 +63,25 @@ sysdep-dl-routines += dl-static
-
- sysdep_routines += dl-vdso
- endif
--
--# Supporting non-executable stacks on MIPS requires changes to both
--# the Linux kernel and glibc. See
--# <https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html> and
--# <https://sourceware.org/ml/libc-alpha/2016-01/msg00719.html>.
-+# If the compiler doesn't use GNU.stack note,
-+# this test is expected to fail.
-+ifneq ($(mips-has-gnustack),yes)
- test-xfail-check-execstack = yes
- endif
-+endif
-
- ifeq ($(subdir),stdlib)
- gen-as-const-headers += ucontext_i.sym
- endif
-+
-+ifeq ($(mips-force-execstack),yes)
-+CFLAGS-.o += -Wa,-execstack
-+CFLAGS-.os += -Wa,-execstack
-+CFLAGS-.op += -Wa,-execstack
-+CFLAGS-.oS += -Wa,-execstack
-+
-+ASFLAGS-.o += -Wa,-execstack
-+ASFLAGS-.os += -Wa,-execstack
-+ASFLAGS-.op += -Wa,-execstack
-+ASFLAGS-.oS += -Wa,-execstack
-+endif
-diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure
-index 1ee7f41a36..25f98e0c7b 100644
---- a/sysdeps/unix/sysv/linux/mips/configure
-+++ b/sysdeps/unix/sysv/linux/mips/configure
-@@ -475,3 +475,44 @@ if test -z "$arch_minimum_kernel"; then
- arch_minimum_kernel=4.5.0
- fi
- fi
-+
-+# Check if we are supposed to run on kernels older than 4.8.0. If so,
-+# force executable stack to avoid potential runtime problems with fpu
-+# emulation.
-+# NOTE: The check below assumes that in absence of user-provided minumum_kernel
-+# we will default to arch_minimum_kernel which is currently less than 4.8.0 for
-+# all known configurations. If this changes, the check must be updated.
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler must use executable stack" >&5
-+$as_echo_n "checking whether the compiler must use executable stack... " >&6; }
-+if ${libc_cv_mips_force_execstack+:} false; then :
-+ $as_echo_n "(cached) " >&6
-+else
-+ libc_cv_mips_force_execstack=no
-+ if test $libc_mips_float = hard; then
-+ if test -n "$minimum_kernel"; then
-+
-+ min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
-+
-+ if test $min_version -lt 264192; then
-+ libc_cv_mips_force_execstack=yes
-+ fi
-+ else
-+ libc_cv_mips_force_execstack=yes
-+ fi
-+ fi
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_force_execstack" >&5
-+$as_echo "$libc_cv_mips_force_execstack" >&6; }
-+
-+libc_mips_has_gnustack=$libc_cv_as_noexecstack
-+
-+if test $libc_cv_mips_force_execstack = yes; then
-+ libc_mips_has_gnustack=no
-+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&5
-+$as_echo "$as_me: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&2;}
-+fi
-+
-+config_vars="$config_vars
-+mips-force-execstack = ${libc_cv_mips_force_execstack}"
-+config_vars="$config_vars
-+mips-has-gnustack = ${libc_mips_has_gnustack}"
-diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac
-index 9147aa4582..3db1b32b08 100644
---- a/sysdeps/unix/sysv/linux/mips/configure.ac
-+++ b/sysdeps/unix/sysv/linux/mips/configure.ac
-@@ -134,3 +134,35 @@ if test -z "$arch_minimum_kernel"; then
- arch_minimum_kernel=4.5.0
- fi
- fi
-+
-+# Check if we are supposed to run on kernels older than 4.8.0. If so,
-+# force executable stack to avoid potential runtime problems with fpu
-+# emulation.
-+# NOTE: The check below assumes that in absence of user-provided minumum_kernel
-+# we will default to arch_minimum_kernel which is currently less than 4.8.0 for
-+# all known configurations. If this changes, the check must be updated.
-+AC_CACHE_CHECK([whether the compiler must use executable stack],
-+ libc_cv_mips_force_execstack, [dnl
-+libc_cv_mips_force_execstack=no
-+ if test $libc_mips_float = hard; then
-+ if test -n "$minimum_kernel"; then
-+ changequote(,)
-+ min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
-+ changequote([,])
-+ if test $min_version -lt 264192; then
-+ libc_cv_mips_force_execstack=yes
-+ fi
-+ else
-+ libc_cv_mips_force_execstack=yes
-+ fi
-+ fi])
-+
-+libc_mips_has_gnustack=$libc_cv_as_noexecstack
-+
-+if test $libc_cv_mips_force_execstack = yes; then
-+ libc_mips_has_gnustack=no
-+ AC_MSG_WARN([forcing executable stack for pre-4.8.0 Linux kernels])
-+fi
-+
-+LIBC_CONFIG_VAR([mips-force-execstack],[${libc_cv_mips_force_execstack}])
-+LIBC_CONFIG_VAR([mips-has-gnustack],[${libc_mips_has_gnustack}])
-diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
-index 16cc31cba5..bf7d80125a 100644
---- a/sysdeps/unix/sysv/linux/not-cancel.h
-+++ b/sysdeps/unix/sysv/linux/not-cancel.h
-@@ -43,6 +43,9 @@ __typeof (openat64) __openat64_nocancel;
- /* Non cancellable read syscall. */
- __typeof (__read) __read_nocancel;
-
-+/* Non cancellable pread syscall (LFS version). */
-+__typeof (__pread64) __pread64_nocancel;
-+
- /* Uncancelable write. */
- __typeof (__write) __write_nocancel;
-
-@@ -84,6 +87,7 @@ hidden_proto (__open64_nocancel)
- hidden_proto (__openat_nocancel)
- hidden_proto (__openat64_nocancel)
- hidden_proto (__read_nocancel)
-+hidden_proto (__pread64_nocancel)
- hidden_proto (__write_nocancel)
- hidden_proto (__close_nocancel)
- hidden_proto (__waitpid_nocancel)
-diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c
-new file mode 100644
-index 0000000000..dab61260e5
---- /dev/null
-+++ b/sysdeps/unix/sysv/linux/pread64_nocancel.c
-@@ -0,0 +1,32 @@
-+/* Linux pread64() syscall implementation -- non-cancellable.
-+ Copyright (C) 2019 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <unistd.h>
-+#include <sysdep-cancel.h>
-+#include <not-cancel.h>
-+
-+#ifndef __NR_pread64
-+# define __NR_pread64 __NR_pread
-+#endif
-+
-+ssize_t
-+__pread64_nocancel (int fd, void *buf, size_t count, off64_t offset)
-+{
-+ return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset));
-+}
-+hidden_def (__pread64_nocancel)
-diff --git a/sysdeps/unix/sysv/linux/riscv/vfork.S b/sysdeps/unix/sysv/linux/riscv/vfork.S
-index 67373f181b..dc173d6b47 100644
---- a/sysdeps/unix/sysv/linux/riscv/vfork.S
-+++ b/sysdeps/unix/sysv/linux/riscv/vfork.S
-@@ -21,9 +21,12 @@
- #include <sys/asm.h>
- #include <sysdep.h>
- #define __ASSEMBLY__
--#include <linux/sched.h>
- #include <asm/signal.h>
-
-+#define CLONE_VM 0x00000100 /* Set if VM shared between processes. */
-+#define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to
-+ wake it up on mm_release. */
-+
- .text
- LEAF (__libc_vfork)
-
-diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmp.h b/sysdeps/unix/sysv/linux/s390/bits/utmp.h
-index 862115c6f8..0569c3b784 100644
---- a/sysdeps/unix/sysv/linux/s390/bits/utmp.h
-+++ b/sysdeps/unix/sysv/linux/s390/bits/utmp.h
-@@ -61,7 +61,8 @@ struct utmp
- pid_t ut_pid; /* Process ID of login process. */
- char ut_line[UT_LINESIZE]
- __attribute_nonstring__; /* Devicename. */
-- char ut_id[4]; /* Inittab ID. */
-+ char ut_id[4]
-+ __attribute_nonstring__; /* Inittab ID. */
- char ut_user[UT_NAMESIZE]
- __attribute_nonstring__; /* Username. */
- char ut_host[UT_HOSTSIZE]
-diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h
-index ea3e860a2d..737d9dca05 100644
---- a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h
-+++ b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h
-@@ -56,10 +56,14 @@ struct utmpx
- {
- short int ut_type; /* Type of login. */
- __pid_t ut_pid; /* Process ID of login process. */
-- char ut_line[__UT_LINESIZE]; /* Devicename. */
-- char ut_id[4]; /* Inittab ID. */
-- char ut_user[__UT_NAMESIZE]; /* Username. */
-- char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */
-+ char ut_line[__UT_LINESIZE]
-+ __attribute_nonstring__; /* Devicename. */
-+ char ut_id[4]
-+ __attribute_nonstring__; /* Inittab ID. */
-+ char ut_user[__UT_NAMESIZE]
-+ __attribute_nonstring__; /* Username. */
-+ char ut_host[__UT_HOSTSIZE]
-+ __attribute_nonstring__; /* Hostname for remote login. */
- struct __exit_status ut_exit; /* Exit status of a process marked
- as DEAD_PROCESS. */
-
-diff --git a/sysdeps/unix/sysv/linux/test-errno-linux.c b/sysdeps/unix/sysv/linux/test-errno-linux.c
-index cb979d44bd..aaa9eadc0a 100644
---- a/sysdeps/unix/sysv/linux/test-errno-linux.c
-+++ b/sysdeps/unix/sysv/linux/test-errno-linux.c
-@@ -160,8 +160,9 @@ do_test (void)
- fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0);
- /* quotactl returns ENOSYS for kernels not configured with
- CONFIG_QUOTA, and may return EPERM if called within certain types
-- of containers. */
-- fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM),
-+ of containers. Linux 5.4 added additional argument validation
-+ and can return EINVAL. */
-+ fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM, EINVAL),
- quotactl, Q_GETINFO, NULL, -1, (caddr_t) &dqblk);
- fails |= test_wrp (EINVAL, sched_getparam, -1, &sch_param);
- fails |= test_wrp (EINVAL, sched_getscheduler, -1);
-diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
-index 975cbe2950..df2cdfdb6b 100644
---- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
-+++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
-@@ -31,7 +31,8 @@
- environment variable, LD_PREFER_MAP_32BIT_EXEC. */
- #define EXTRA_LD_ENVVARS \
- case 21: \
-- if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \
-+ if (!__libc_enable_secure \
-+ && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \
- GLRO(dl_x86_cpu_features).feature[index_arch_Prefer_MAP_32BIT_EXEC] \
- |= bit_arch_Prefer_MAP_32BIT_EXEC; \
- break;
-diff --git a/time/Makefile b/time/Makefile
-index a428f55245..63b8d735ea 100644
---- a/time/Makefile
-+++ b/time/Makefile
-@@ -57,6 +57,8 @@ include ../gen-locales.mk
-
- $(objpfx)tst-ftime_l.out: $(gen-locales)
- $(objpfx)tst-strptime.out: $(gen-locales)
-+$(objpfx)tst-strftime2.out: $(gen-locales)
-+$(objpfx)tst-strftime3.out: $(gen-locales)
- endif
-
- tz-cflags = -DTZDIR='"$(zonedir)"' \