import CS glibc-2.34-168.el9
This commit is contained in:
parent
8972ef0417
commit
72b1f60f08
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
||||
SOURCES/glibc-2.34.tar.xz
|
||||
SOURCES/glibc-upstream-2.34-373.patch
|
||||
|
@ -1,2 +1 @@
|
||||
7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz
|
||||
6022f103e5596ad229f22bc966327d71208f7016 SOURCES/glibc-upstream-2.34-373.patch
|
||||
|
337
SOURCES/glibc-RHEL-1915-1.patch
Normal file
337
SOURCES/glibc-RHEL-1915-1.patch
Normal file
@ -0,0 +1,337 @@
|
||||
commit f58a8c1c15d8b5d8a08e8553f82867202b88a5cc
|
||||
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
Date: Sat May 27 06:48:33 2023 +0000
|
||||
|
||||
Fix misspellings in iconv/ and iconvdata/ -- BZ 25337
|
||||
|
||||
All the changes are in comments or '#error' messages.
|
||||
Applying this commit results in bit-identical rebuild of iconvdata/*.so
|
||||
|
||||
Reviewed-by: Florian Weimer <fw@deneb.enyo.de>
|
||||
|
||||
diff --git a/iconv/gconv_charset.c b/iconv/gconv_charset.c
|
||||
index 5696058298..0cf3226be6 100644
|
||||
--- a/iconv/gconv_charset.c
|
||||
+++ b/iconv/gconv_charset.c
|
||||
@@ -181,10 +181,10 @@ __gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
|
||||
implementation has always handled them. Only suffixes in the tocode are
|
||||
processed and handled. The reality is that invalid input in the input
|
||||
character set should only be ignored if the fromcode specifies IGNORE.
|
||||
- The current implementation ignores invalid intput in the input character
|
||||
+ The current implementation ignores invalid input in the input character
|
||||
set if the tocode contains IGNORE. We preserve this behavior for
|
||||
backwards compatibility. In the future we may split the handling of
|
||||
- IGNORE to allow a finer grained specification of ignorning invalid input
|
||||
+ IGNORE to allow a finer grained specification of ignoring invalid input
|
||||
and/or ignoring invalid output. */
|
||||
conv_spec->translit = ptc.translit;
|
||||
conv_spec->ignore = ptc.ignore;
|
||||
diff --git a/iconv/gconv_charset.h b/iconv/gconv_charset.h
|
||||
index 00744aad56..07815b0eee 100644
|
||||
--- a/iconv/gconv_charset.h
|
||||
+++ b/iconv/gconv_charset.h
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/* This function copies in-order, characters from the source 's' that are
|
||||
- either alpha-numeric or one in one of these: "_-.,:/" - into the destination
|
||||
+ either alphanumeric or one in one of these: "_-.,:/" - into the destination
|
||||
'wp' while dropping all other characters. In the process, it converts all
|
||||
alphabetical characters to upper case. It then appends up to two '/'
|
||||
characters so that the total number of '/'es in the destination is 2. */
|
||||
diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
|
||||
index c76011d6bc..ee9e97e1bd 100644
|
||||
--- a/iconv/gconv_conf.c
|
||||
+++ b/iconv/gconv_conf.c
|
||||
@@ -153,7 +153,7 @@ static void
|
||||
add_alias (char *rp)
|
||||
{
|
||||
/* We now expect two more string. The strings are normalized
|
||||
- (converted to UPPER case) and strored in the alias database. */
|
||||
+ (converted to UPPER case) and stored in the alias database. */
|
||||
char *from, *to, *wp;
|
||||
|
||||
while (__isspace_l (*rp, _nl_C_locobj_ptr))
|
||||
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
|
||||
index 4b247a815f..19d042faff 100644
|
||||
--- a/iconv/gconv_int.h
|
||||
+++ b/iconv/gconv_int.h
|
||||
@@ -172,7 +172,7 @@ __libc_lock_define (extern, __gconv_lock attribute_hidden)
|
||||
})
|
||||
|
||||
|
||||
-/* Return in *HANDLE, a decriptor for the transformation. The function expects
|
||||
+/* Return in *HANDLE, a descriptor for the transformation. The function expects
|
||||
the specification of the transformation in the structure pointed to by
|
||||
CONV_SPEC. It only reads *CONV_SPEC and does not take ownership of it. */
|
||||
extern int __gconv_open (struct gconv_spec *conv_spec,
|
||||
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
|
||||
index c60cffad4c..e936e171d7 100644
|
||||
--- a/iconv/gconv_simple.c
|
||||
+++ b/iconv/gconv_simple.c
|
||||
@@ -56,7 +56,7 @@ __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
|
||||
|
||||
/* Transform from the internal, UCS4-like format, to UCS4. The
|
||||
difference between the internal ucs4 format and the real UCS4
|
||||
- format is, if any, the endianess. The Unicode/ISO 10646 says that
|
||||
+ format is, if any, the endianness. The Unicode/ISO 10646 says that
|
||||
unless some higher protocol specifies it differently, the byte
|
||||
order is big endian.*/
|
||||
#define DEFINE_INIT 0
|
||||
@@ -100,7 +100,7 @@ internal_ucs4_loop (struct __gconv_step *step,
|
||||
*inptrp = inptr + n_convert * 4;
|
||||
*outptrp = __mempcpy (outptr, inptr, n_convert * 4);
|
||||
#else
|
||||
-# error "This endianess is not supported."
|
||||
+# error "This endianness is not supported."
|
||||
#endif
|
||||
|
||||
/* Determine the status. */
|
||||
@@ -153,7 +153,7 @@ internal_ucs4_loop_single (struct __gconv_step *step,
|
||||
(*outptrp)[2] = state->__value.__wchb[2];
|
||||
(*outptrp)[3] = state->__value.__wchb[3];
|
||||
#else
|
||||
-# error "This endianess is not supported."
|
||||
+# error "This endianness is not supported."
|
||||
#endif
|
||||
*outptrp += 4;
|
||||
|
||||
@@ -347,7 +347,7 @@ internal_ucs4le_loop (struct __gconv_step *step,
|
||||
*inptrp = inptr + n_convert * 4;
|
||||
*outptrp = __mempcpy (outptr, inptr, n_convert * 4);
|
||||
#else
|
||||
-# error "This endianess is not supported."
|
||||
+# error "This endianness is not supported."
|
||||
#endif
|
||||
|
||||
/* Determine the status. */
|
||||
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
|
||||
index 1d90938d71..bee898c63c 100644
|
||||
--- a/iconv/iconv_prog.c
|
||||
+++ b/iconv/iconv_prog.c
|
||||
@@ -537,7 +537,7 @@ incomplete character or shift sequence at end of buffer"));
|
||||
static int
|
||||
process_fd (iconv_t cd, int fd, FILE **output, const char *output_file)
|
||||
{
|
||||
- /* we have a problem with reading from a desriptor since we must not
|
||||
+ /* we have a problem with reading from a descriptor since we must not
|
||||
provide the iconv() function an incomplete character or shift
|
||||
sequence at the end of the buffer. Since we have to deal with
|
||||
arbitrary encodings we must read the whole text in a buffer and
|
||||
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
|
||||
index a319e2f762..f3f4baa4e7 100644
|
||||
--- a/iconv/iconvconfig.c
|
||||
+++ b/iconv/iconvconfig.c
|
||||
@@ -445,7 +445,7 @@ static void
|
||||
add_alias (char *rp)
|
||||
{
|
||||
/* We now expect two more string. The strings are normalized
|
||||
- (converted to UPPER case) and strored in the alias database. */
|
||||
+ (converted to UPPER case) and stored in the alias database. */
|
||||
char *from;
|
||||
char *to;
|
||||
char *wp;
|
||||
diff --git a/iconvdata/bug-iconv8.c b/iconvdata/bug-iconv8.c
|
||||
index e32d891b5c..1ebb674c91 100644
|
||||
--- a/iconvdata/bug-iconv8.c
|
||||
+++ b/iconvdata/bug-iconv8.c
|
||||
@@ -29,7 +29,7 @@ do_test (void)
|
||||
/*
|
||||
* result: -1 84 0 0 (84=EILSEQ)
|
||||
*
|
||||
- * Error is returnd but inbuf is consumed.
|
||||
+ * Error is returned but inbuf is consumed.
|
||||
*
|
||||
* \x83\xd9 is valid shift-jis sequence but no character is assigned
|
||||
* to it.
|
||||
diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
|
||||
index 4d6ec71139..5203f30e79 100644
|
||||
--- a/iconvdata/ibm1364.c
|
||||
+++ b/iconvdata/ibm1364.c
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/ibm930.c b/iconvdata/ibm930.c
|
||||
index 2939d4d29e..fe2fe1f15b 100644
|
||||
--- a/iconvdata/ibm930.c
|
||||
+++ b/iconvdata/ibm930.c
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
|
||||
index 95935b8b36..4db0699a68 100644
|
||||
--- a/iconvdata/ibm933.c
|
||||
+++ b/iconvdata/ibm933.c
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
|
||||
index 1d8240a758..3c3d697a24 100644
|
||||
--- a/iconvdata/ibm935.c
|
||||
+++ b/iconvdata/ibm935.c
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
|
||||
index 9e02aba122..1586036c1e 100644
|
||||
--- a/iconvdata/ibm937.c
|
||||
+++ b/iconvdata/ibm937.c
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
|
||||
index ce719cb29f..9b053c696e 100644
|
||||
--- a/iconvdata/ibm939.c
|
||||
+++ b/iconvdata/ibm939.c
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_curcs = *curcsp; \
|
||||
diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
|
||||
index d0c3ca4f03..36727f0865 100644
|
||||
--- a/iconvdata/iso-2022-cn-ext.c
|
||||
+++ b/iconvdata/iso-2022-cn-ext.c
|
||||
@@ -154,7 +154,7 @@ enum
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_set = *setp; \
|
||||
diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c
|
||||
index 73eb5e77c6..5660ead668 100644
|
||||
--- a/iconvdata/iso-2022-cn.c
|
||||
+++ b/iconvdata/iso-2022-cn.c
|
||||
@@ -102,7 +102,7 @@ enum
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_set = *setp; \
|
||||
diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c
|
||||
index d341a14f51..c722bdbfc3 100644
|
||||
--- a/iconvdata/iso-2022-jp-3.c
|
||||
+++ b/iconvdata/iso-2022-jp-3.c
|
||||
@@ -156,7 +156,7 @@ enum
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
saved_state = *statep; \
|
||||
diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c
|
||||
index f31dfb92e6..b023d3cf8e 100644
|
||||
--- a/iconvdata/iso-2022-jp.c
|
||||
+++ b/iconvdata/iso-2022-jp.c
|
||||
@@ -249,7 +249,7 @@ gconv_end (struct __gconv_step *data)
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_set = *setp; \
|
||||
@@ -679,7 +679,7 @@ static const cvlist_t conversion_lists[4] =
|
||||
the character is unknown. \
|
||||
The CJK character sets partially overlap when seen as subsets \
|
||||
of ISO 10646; therefore there is no single correct result. \
|
||||
- We use a preferrence order which depends on the language tag. */ \
|
||||
+ We use a preference order which depends on the language tag. */ \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
{ \
|
||||
diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c
|
||||
index e71198aee9..fd785fd8f9 100644
|
||||
--- a/iconvdata/iso-2022-kr.c
|
||||
+++ b/iconvdata/iso-2022-kr.c
|
||||
@@ -100,7 +100,7 @@ enum
|
||||
|
||||
|
||||
/* Since we might have to reset input pointer we must be able to save
|
||||
- and retore the state. */
|
||||
+ and restore the state. */
|
||||
#define SAVE_RESET_STATE(Save) \
|
||||
if (Save) \
|
||||
save_set = *setp; \
|
||||
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
|
||||
index f7111a3759..1800dc8fdb 100644
|
||||
--- a/iconvdata/iso646.c
|
||||
+++ b/iconvdata/iso646.c
|
||||
@@ -21,7 +21,7 @@
|
||||
zillions of ISO 646 derivates and supporting them all in a separate
|
||||
module is overkill since these coded character sets are hardly ever
|
||||
used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
|
||||
- with ISO 8859-1). The European variants are superceded by the
|
||||
+ with ISO 8859-1). The European variants are superseded by the
|
||||
various ISO 8859-? standards and the Asian variants are embedded in
|
||||
larger character sets. Therefore this implementation is simply
|
||||
here to make it possible to do the conversion if it is necessary.
|
||||
diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c
|
||||
index 93c28db13e..5ab821bbff 100644
|
||||
--- a/iconvdata/sjis.c
|
||||
+++ b/iconvdata/sjis.c
|
||||
@@ -2001,7 +2001,7 @@ static const char from_ucs4_greek[193][2] =
|
||||
|
||||
|
||||
/* The mapping of the Kanji is horrible. The glyphs covered by Shift JIS
|
||||
- are spreaded all around the Unicode CJK area. We use one big table
|
||||
+ are spread all around the Unicode CJK area. We use one big table
|
||||
since using the gaps will not buy us much.
|
||||
|
||||
The following table can be generated using
|
||||
diff --git a/iconvdata/tst-table.sh b/iconvdata/tst-table.sh
|
||||
index d5b1f3c87d..bc6f542b24 100755
|
||||
--- a/iconvdata/tst-table.sh
|
||||
+++ b/iconvdata/tst-table.sh
|
||||
@@ -44,7 +44,7 @@ if test ${charset} = GB18030; then
|
||||
mv ${objpfx}tst-${charset}.truncated.table ${objpfx}tst-${charset}.charmap.table
|
||||
fi
|
||||
|
||||
-# Precomputed expexted differences between the charmap and iconv forward.
|
||||
+# Precomputed expected differences between the charmap and iconv forward.
|
||||
precomposed=${charset}.precomposed
|
||||
|
||||
# Precompute expected differences between the charmap and iconv backward.
|
218
SOURCES/glibc-RHEL-1915-2.patch
Normal file
218
SOURCES/glibc-RHEL-1915-2.patch
Normal file
@ -0,0 +1,218 @@
|
||||
commit 422ed8ede312f786369e4850e47b8d32beaae4e4
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
iconv: Base tests for buffer management
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
Conflicts:
|
||||
iconv/Makefile - tests-special list differences
|
||||
|
||||
diff --git a/iconv/Makefile b/iconv/Makefile
|
||||
index 65b4a44ab8..b0fa550141 100644
|
||||
--- a/iconv/Makefile 2024-11-18 12:41:42.539981355 -0500
|
||||
+++ b/iconv/Makefile 2024-11-18 12:40:54.861651890 -0500
|
||||
@@ -72,7 +72,10 @@ include $(patsubst %,$(..)libof-iterator
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
xtests-special += $(objpfx)test-iconvconfig.out
|
||||
-tests-special += $(objpfx)tst-iconv_prog.out
|
||||
+tests-special += \
|
||||
+ $(objpfx)tst-iconv_prog-buffer.out \
|
||||
+ $(objpfx)tst-iconv_prog.out \
|
||||
+ # tests-special
|
||||
endif
|
||||
|
||||
# Make a copy of the file because gconv module names are constructed
|
||||
@@ -125,3 +128,8 @@ $(objpfx)tst-iconv_prog.out: tst-iconv_p
|
||||
$(BASH) $< $(common-objdir) '$(test-wrapper-env)' \
|
||||
'$(run-program-env)' > $@; \
|
||||
$(evaluate-test)
|
||||
+
|
||||
+$(objpfx)tst-iconv_prog-buffer.out: \
|
||||
+ tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
+ $(BASH) $< $(common-objdir) '$(test-program-prefix)' > $@; \
|
||||
+ $(evaluate-test)
|
||||
diff --git a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh
|
||||
new file mode 100644
|
||||
index 0000000000..a27107f02b
|
||||
--- /dev/null
|
||||
+++ b/iconv/tst-iconv_prog-buffer.sh
|
||||
@@ -0,0 +1,177 @@
|
||||
+#!/bin/bash
|
||||
+# Test for iconv (the program) buffer management.
|
||||
+# Copyright (C) 2024 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
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+exec 2>&1
|
||||
+set -e
|
||||
+
|
||||
+exec {logfd}>&1
|
||||
+
|
||||
+codir=$1
|
||||
+test_program_prefix="$2"
|
||||
+
|
||||
+# Use internal converters to avoid issues with module loading.
|
||||
+iconv_args="-f ASCII -t UTF-8"
|
||||
+
|
||||
+failure=false
|
||||
+
|
||||
+tmp=`mktemp -d`
|
||||
+trap 'rm -rf "$tmp"' 0
|
||||
+echo ABC > "$tmp/abc"
|
||||
+echo DEF > "$tmp/def"
|
||||
+echo GGG > "$tmp/ggg"
|
||||
+echo HH > "$tmp/hh"
|
||||
+echo XY > "$tmp/xy"
|
||||
+echo ZT > "$tmp/zt"
|
||||
+echo OUT > "$tmp/out-template"
|
||||
+printf '\xff' > "$tmp/0xff"
|
||||
+cat "$tmp/xy" "$tmp/0xff" "$tmp/zt" > "$tmp/0xff-wrapped"
|
||||
+
|
||||
+run_iconv () {
|
||||
+ local c=0
|
||||
+ if test "${FUNCNAME[2]}" = main; then
|
||||
+ c=1
|
||||
+ fi
|
||||
+ echo "${BASH_SOURCE[$c]}:${BASH_LINENO[$c]}: iconv $iconv_args $@" >&$logfd
|
||||
+ $test_program_prefix $codir/iconv/iconv_prog $iconv_args "$@"
|
||||
+}
|
||||
+
|
||||
+check_out_expected () {
|
||||
+ if ! cmp -s "$tmp/out" "$tmp/expected" ; then
|
||||
+ echo "error: iconv output difference" >&$logfd
|
||||
+ echo "*** expected ***" >&$logfd
|
||||
+ cat "$tmp/expected" >&$logfd
|
||||
+ echo "*** actual ***" >&$logfd
|
||||
+ cat "$tmp/out" >&$logfd
|
||||
+ failure=true
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+expect_files () {
|
||||
+ local f
|
||||
+ ! test -z "$1"
|
||||
+ cp "$tmp/$1" "$tmp/expected"
|
||||
+ shift
|
||||
+ for f in "$@" ; do
|
||||
+ cat "$tmp/$f" >> "$tmp/expected"
|
||||
+ done
|
||||
+ check_out_expected
|
||||
+}
|
||||
+
|
||||
+check_out () {
|
||||
+ cat > "$tmp/expected"
|
||||
+ check_out_expected
|
||||
+}
|
||||
+
|
||||
+expect_exit () {
|
||||
+ local expected=$1
|
||||
+ shift
|
||||
+ # Prevent failure for stopping the script.
|
||||
+ if "$@" ; then
|
||||
+ actual=$?
|
||||
+ else
|
||||
+ actual=$?
|
||||
+ fi
|
||||
+ if test "$actual" -ne "$expected"; then
|
||||
+ echo "error: expected exit status $expected, not $actual" >&$logfd
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+ignore_failure () {
|
||||
+ set +e
|
||||
+ "$@"
|
||||
+ status=$?
|
||||
+ set -e
|
||||
+}
|
||||
+
|
||||
+# Concatentation test.
|
||||
+run_iconv -o "$tmp/out" "$tmp/abc" "$tmp/def"
|
||||
+expect_files abc def
|
||||
+
|
||||
+# Single-file in-place conversion.
|
||||
+run_iconv -o "$tmp/out" "$tmp/out"
|
||||
+expect_files abc def
|
||||
+
|
||||
+# Multiple input files with in-place conversion.
|
||||
+
|
||||
+run_iconv -o "$tmp/out" "$tmp/out" "$tmp/abc"
|
||||
+expect_files abc def abc
|
||||
+
|
||||
+# But not if we are writing to standard output.
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv </dev/null >>"$tmp/out"
|
||||
+expect_files out-template
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv - </dev/null >>"$tmp/out"
|
||||
+expect_files out-template
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv /dev/null >>"$tmp/out"
|
||||
+expect_files out-template
|
||||
+
|
||||
+# Conversion errors should avoid clobbering an existing file if
|
||||
+# it is also an input file.
|
||||
+
|
||||
+cp "$tmp/0xff" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/out"
|
||||
+expect_files 0xff
|
||||
+
|
||||
+cp "$tmp/0xff" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" < "$tmp/out"
|
||||
+expect_files 0xff
|
||||
+
|
||||
+cp "$tmp/0xff" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" - < "$tmp/out"
|
||||
+expect_files 0xff
|
||||
+
|
||||
+# If errors are ignored, the file should be overwritten.
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+expect_exit 1 \
|
||||
+ run_iconv -c -o "$tmp/out" "$tmp/abc" "$tmp/0xff" "$tmp/def" 2>"$tmp/err"
|
||||
+! test -s "$tmp/err"
|
||||
+expect_files abc def
|
||||
+
|
||||
+# FIXME: This is not correct, -c should not change the exit status.
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -c -o "$tmp/out" \
|
||||
+ "$tmp/abc" "$tmp/0xff-wrapped" "$tmp/def" 2>"$tmp/err"
|
||||
+! test -s "$tmp/err"
|
||||
+expect_files abc xy zt def
|
||||
+
|
||||
+# If the file does not exist yet, it should not be created on error.
|
||||
+
|
||||
+rm "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/0xff"
|
||||
+! test -e "$tmp/out"
|
||||
+
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" < "$tmp/0xff"
|
||||
+! test -e "$tmp/out"
|
||||
+
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" "$tmp/0xff" "$tmp/def"
|
||||
+! test -e "$tmp/out"
|
||||
+
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" - < "$tmp/0xff" "$tmp/def"
|
||||
+! test -e "$tmp/out"
|
||||
+
|
||||
+if $failure ; then
|
||||
+ exit 1
|
||||
+fi
|
91
SOURCES/glibc-RHEL-1915-3.patch
Normal file
91
SOURCES/glibc-RHEL-1915-3.patch
Normal file
@ -0,0 +1,91 @@
|
||||
commit 0cb64617a6f691b611406427c8e24b7f04c4983f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
iconv: Do not use mmap in iconv (the program) (bug 17703)
|
||||
|
||||
On current systems, very large files are needed before
|
||||
mmap becomes beneficial. Simplify the implementation.
|
||||
|
||||
This exposed that inptr was not initialized correctly in
|
||||
process_fd. Handling multiple input files resulted in
|
||||
EFAULT in read because a null pointer was passed. This
|
||||
could be observed previously if an input file was not
|
||||
mappable and was reported as bug 17703.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
|
||||
index a765b1af21..88a928557e 100644
|
||||
--- a/iconv/iconv_prog.c
|
||||
+++ b/iconv/iconv_prog.c
|
||||
@@ -31,9 +31,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libintl.h>
|
||||
-#ifdef _POSIX_MAPPED_FILES
|
||||
-# include <sys/mman.h>
|
||||
-#endif
|
||||
#include <charmap.h>
|
||||
#include <gconv_int.h>
|
||||
#include "iconv_prog.h"
|
||||
@@ -253,10 +250,6 @@ conversions from `%s' and to `%s' are not supported"),
|
||||
else
|
||||
do
|
||||
{
|
||||
-#ifdef _POSIX_MAPPED_FILES
|
||||
- struct stat64 st;
|
||||
- char *addr;
|
||||
-#endif
|
||||
int fd, ret;
|
||||
|
||||
if (verbose)
|
||||
@@ -276,39 +269,6 @@ conversions from `%s' and to `%s' are not supported"),
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef _POSIX_MAPPED_FILES
|
||||
- /* We have possibilities for reading the input file. First try
|
||||
- to mmap() it since this will provide the fastest solution. */
|
||||
- if (fstat64 (fd, &st) == 0
|
||||
- && ((addr = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE,
|
||||
- fd, 0)) != MAP_FAILED))
|
||||
- {
|
||||
- /* Yes, we can use mmap(). The descriptor is not needed
|
||||
- anymore. */
|
||||
- if (close (fd) != 0)
|
||||
- error (EXIT_FAILURE, errno,
|
||||
- _("error while closing input `%s'"),
|
||||
- argv[remaining]);
|
||||
-
|
||||
- ret = process_block (cd, addr, st.st_size, &output,
|
||||
- output_file);
|
||||
-
|
||||
- /* We don't need the input data anymore. */
|
||||
- munmap ((void *) addr, st.st_size);
|
||||
-
|
||||
- if (ret != 0)
|
||||
- {
|
||||
- status = EXIT_FAILURE;
|
||||
-
|
||||
- if (ret < 0)
|
||||
- /* We cannot go on with producing output since it might
|
||||
- lead to problem because the last output might leave
|
||||
- the output stream in an undefined state. */
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif /* _POSIX_MAPPED_FILES */
|
||||
{
|
||||
/* Read the file in pieces. */
|
||||
ret = process_fd (cd, fd, &output, output_file);
|
||||
@@ -544,7 +504,7 @@ process_fd (iconv_t cd, int fd, FILE **output, const char *output_file)
|
||||
process it in one step. */
|
||||
static char *inbuf = NULL;
|
||||
static size_t maxlen = 0;
|
||||
- char *inptr = NULL;
|
||||
+ char *inptr = inbuf;
|
||||
size_t actlen = 0;
|
||||
|
||||
while (actlen < maxlen)
|
62
SOURCES/glibc-RHEL-1915-4.patch
Normal file
62
SOURCES/glibc-RHEL-1915-4.patch
Normal file
@ -0,0 +1,62 @@
|
||||
commit 00ba299787c2ea9e5c4986301e2f4965dffbfded
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
manual: __is_last is no longer part of iconv internals
|
||||
|
||||
The __is_last field was replaced with a bitmask in
|
||||
commit 85830c4c4688b30d3d76111aa9a26745c7b141d6 in 2000,
|
||||
and multiple bits are in use today.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/manual/charset.texi b/manual/charset.texi
|
||||
index 427db3bc80..3aaa62d088 100644
|
||||
--- a/manual/charset.texi
|
||||
+++ b/manual/charset.texi
|
||||
@@ -2422,11 +2422,11 @@ written into the buffer to signal how much output is available. If this
|
||||
conversion step is not the last one, the element must not be modified.
|
||||
The @code{__outbufend} element must not be modified.
|
||||
|
||||
-@item int __is_last
|
||||
-This element is nonzero if this conversion step is the last one. This
|
||||
-information is necessary for the recursion. See the description of the
|
||||
-conversion function internals below. This element must never be
|
||||
-modified.
|
||||
+@item int __flags
|
||||
+This field is a set of flags. The @code{__GCONV_IS_LAST} bit is set if
|
||||
+this conversion step is the last one. This information is necessary for
|
||||
+the recursion. See the description of the conversion function internals
|
||||
+below. This element must never be modified.
|
||||
|
||||
@item int __invocation_counter
|
||||
The conversion function can use this element to see how many calls of
|
||||
@@ -2731,8 +2731,8 @@ Otherwise the function has to emit a byte sequence to bring the state
|
||||
object into the initial state. Once this all happened the other
|
||||
conversion modules in the chain of conversions have to get the same
|
||||
chance. Whether another step follows can be determined from the
|
||||
-@code{__is_last} element of the step data structure to which the first
|
||||
-parameter points.
|
||||
+@code{__GCONV_IS_LAST} flag in the @code{__flags} field of the step
|
||||
+data structure to which the first parameter points.
|
||||
|
||||
The more interesting mode is when actual text has to be converted. The
|
||||
first step in this case is to convert as much text as possible from the
|
||||
@@ -2866,7 +2866,7 @@ gconv (struct __gconv_step *step, struct __gconv_step_data *data,
|
||||
|
||||
/* @r{Call the steps down the chain if there are any but only}
|
||||
@r{if we successfully emitted the escape sequence.} */
|
||||
- if (status == __GCONV_OK && ! data->__is_last)
|
||||
+ if (status == __GCONV_OK && ! (data->__flags & __GCONV_IS_LAST))
|
||||
status = fct (next_step, next_data, NULL, NULL,
|
||||
written, 1);
|
||||
@}
|
||||
@@ -2892,7 +2892,7 @@ gconv (struct __gconv_step *step, struct __gconv_step_data *data,
|
||||
|
||||
/* @r{If this is the last step, leave the loop. There is}
|
||||
@r{nothing we can do.} */
|
||||
- if (data->__is_last)
|
||||
+ if (data->__flags & __GCONV_IS_LAST)
|
||||
@{
|
||||
/* @r{Store information about how many bytes are}
|
||||
@r{available.} */
|
1064
SOURCES/glibc-RHEL-1915-5.patch
Normal file
1064
SOURCES/glibc-RHEL-1915-5.patch
Normal file
File diff suppressed because it is too large
Load Diff
715
SOURCES/glibc-RHEL-1915-6.patch
Normal file
715
SOURCES/glibc-RHEL-1915-6.patch
Normal file
@ -0,0 +1,715 @@
|
||||
commit 8ef3cff9d1ceafe369f982d980678d749fb93bd2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
iconv: Support in-place conversions (bug 10460, bug 32033)
|
||||
|
||||
Check if any of the input files overlaps with the output file, and use
|
||||
a temporary file in this case, so that the input is no clobbered
|
||||
before it is read. This fixes bug 10460. It allows to use iconv
|
||||
more easily as a functional replacement for GNU recode.
|
||||
|
||||
The updated output buffer management truncates the output file
|
||||
if there is no input, fixing bug 32033.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
NEWS - Dropped
|
||||
iconv/Makefile - tests-special list diffs
|
||||
iconv/iconv_prog.c - Manual merge
|
||||
|
||||
diff -Nrup a/iconv/Makefile b/iconv/Makefile
|
||||
--- a/iconv/Makefile 2024-11-21 11:08:26.166051531 -0500
|
||||
+++ b/iconv/Makefile 2024-11-21 11:08:51.325219751 -0500
|
||||
@@ -77,6 +77,8 @@ include $(patsubst %,$(..)libof-iterator
|
||||
ifeq ($(run-built-tests),yes)
|
||||
xtests-special += $(objpfx)test-iconvconfig.out
|
||||
tests-special += \
|
||||
+ $(objpfx)tst-iconv_prog-buffer-large.out \
|
||||
+ $(objpfx)tst-iconv_prog-buffer-tiny.out \
|
||||
$(objpfx)tst-iconv_prog-buffer.out \
|
||||
$(objpfx)tst-iconv_prog.out \
|
||||
# tests-special
|
||||
@@ -137,3 +139,12 @@ $(objpfx)tst-iconv_prog-buffer.out: \
|
||||
tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
$(BASH) $< $(common-objdir) '$(test-program-prefix)' > $@; \
|
||||
$(evaluate-test)
|
||||
+$(objpfx)tst-iconv_prog-buffer-tiny.out: \
|
||||
+ tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
+ $(BASH) $< $(common-objdir) '$(test-program-prefix)' \
|
||||
+ '--buffer-size=1' > $@; \
|
||||
+ $(evaluate-test)
|
||||
+$(objpfx)tst-iconv_prog-buffer-large.out: \
|
||||
+ tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
+ $(BASH) $< $(common-objdir) '$(test-program-prefix)' '' '22' > $@; \
|
||||
+ $(evaluate-test)
|
||||
diff -Nrup a/iconv/iconv_prog.c b/iconv/iconv_prog.c
|
||||
--- a/iconv/iconv_prog.c 2024-11-21 11:08:26.167051537 -0500
|
||||
+++ b/iconv/iconv_prog.c 2024-11-21 11:10:10.028745981 -0500
|
||||
@@ -48,7 +48,11 @@
|
||||
static void print_version (FILE *stream, struct argp_state *state);
|
||||
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
|
||||
|
||||
-#define OPT_VERBOSE 1000
|
||||
+enum
|
||||
+ {
|
||||
+ OPT_VERBOSE = 1000,
|
||||
+ OPT_BUFFER_SIZE,
|
||||
+ };
|
||||
#define OPT_LIST 'l'
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
@@ -64,6 +68,10 @@ static const struct argp_option options[
|
||||
{ "output", 'o', N_("FILE"), 0, N_("output file") },
|
||||
{ "silent", 's', NULL, 0, N_("suppress warnings") },
|
||||
{ "verbose", OPT_VERBOSE, NULL, 0, N_("print progress information") },
|
||||
+ /* This is an internal option intended for testing only. Very small
|
||||
+ buffers do not work with all character sets. */
|
||||
+ { "buffer-size", OPT_BUFFER_SIZE, N_("BYTE-COUNT"), OPTION_HIDDEN,
|
||||
+ N_("size of in-memory scratch buffer") },
|
||||
{ NULL, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
@@ -101,13 +109,20 @@ static int list;
|
||||
/* If nonzero omit invalid character from output. */
|
||||
int omit_invalid;
|
||||
|
||||
+/* Current index in argv (after command line processing) with the
|
||||
+ input file name. */
|
||||
+static int current_input_file_index;
|
||||
+
|
||||
+/* Size of the temporary, in-memory buffer. Exceeding it needs
|
||||
+ spooling to disk in a temporary file. Controlled by --buffer_size. */
|
||||
+static size_t output_buffer_size = 1024 * 1024;
|
||||
+
|
||||
/* Prototypes for the functions doing the actual work. */
|
||||
-static int process_block (iconv_t cd, char *addr, size_t len, FILE **output,
|
||||
- const char *output_file);
|
||||
-static int process_fd (iconv_t cd, int fd, FILE **output,
|
||||
- const char *output_file);
|
||||
-static int process_file (iconv_t cd, FILE *input, FILE **output,
|
||||
- const char *output_file);
|
||||
+static void prepare_output_file (char **argv);
|
||||
+static void close_output_file (int status);
|
||||
+static int process_block (iconv_t cd, char *addr, size_t len);
|
||||
+static int process_fd (iconv_t cd, int fd);
|
||||
+static int process_file (iconv_t cd, FILE *input);
|
||||
static void print_known_names (void);
|
||||
|
||||
|
||||
@@ -115,7 +130,6 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int status = EXIT_SUCCESS;
|
||||
- int remaining;
|
||||
__gconv_t cd;
|
||||
struct charmap_t *from_charmap = NULL;
|
||||
struct charmap_t *to_charmap = NULL;
|
||||
@@ -127,7 +141,7 @@ main (int argc, char *argv[])
|
||||
textdomain (_libc_intl_domainname);
|
||||
|
||||
/* Parse and process arguments. */
|
||||
- argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
+ argp_parse (&argp, argc, argv, 0, ¤t_input_file_index, NULL);
|
||||
|
||||
/* List all coded character sets if wanted. */
|
||||
if (list)
|
||||
@@ -162,7 +176,8 @@ main (int argc, char *argv[])
|
||||
if (from_charmap != NULL || to_charmap != NULL)
|
||||
/* Construct the conversion table and do the conversion. */
|
||||
status = charmap_conversion (from_code, from_charmap, to_code, to_charmap,
|
||||
- argc, remaining, argv, output_file);
|
||||
+ argc, current_input_file_index, argv,
|
||||
+ output_file);
|
||||
else
|
||||
{
|
||||
struct gconv_spec conv_spec;
|
||||
@@ -236,16 +251,14 @@ conversions from `%s' and to `%s' are no
|
||||
_("failed to start conversion processing"));
|
||||
}
|
||||
|
||||
- /* The output file. Will be opened when we are ready to produce
|
||||
- output. */
|
||||
- FILE *output = NULL;
|
||||
+ prepare_output_file (argv);
|
||||
|
||||
/* Now process the remaining files. Write them to stdout or the file
|
||||
specified with the `-o' parameter. If we have no file given as
|
||||
the parameter process all from stdin. */
|
||||
- if (remaining == argc)
|
||||
+ if (current_input_file_index == argc)
|
||||
{
|
||||
- if (process_file (cd, stdin, &output, output_file) != 0)
|
||||
+ if (process_file (cd, stdin) != 0)
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
@@ -254,17 +267,17 @@ conversions from `%s' and to `%s' are no
|
||||
int fd, ret;
|
||||
|
||||
if (verbose)
|
||||
- fprintf (stderr, "%s:\n", argv[remaining]);
|
||||
- if (strcmp (argv[remaining], "-") == 0)
|
||||
- fd = 0;
|
||||
+ fprintf (stderr, "%s:\n", argv[current_input_file_index]);
|
||||
+ if (strcmp (argv[current_input_file_index], "-") == 0)
|
||||
+ fd = STDIN_FILENO;
|
||||
else
|
||||
{
|
||||
- fd = open (argv[remaining], O_RDONLY);
|
||||
+ fd = open (argv[current_input_file_index], O_RDONLY);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
error (0, errno, _("cannot open input file `%s'"),
|
||||
- argv[remaining]);
|
||||
+ argv[current_input_file_index]);
|
||||
status = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
@@ -272,7 +285,7 @@ conversions from `%s' and to `%s' are no
|
||||
|
||||
{
|
||||
/* Read the file in pieces. */
|
||||
- ret = process_fd (cd, fd, &output, output_file);
|
||||
+ ret = process_fd (cd, fd);
|
||||
|
||||
/* Now close the file. */
|
||||
close (fd);
|
||||
@@ -290,7 +303,7 @@ conversions from `%s' and to `%s' are no
|
||||
}
|
||||
}
|
||||
}
|
||||
- while (++remaining < argc);
|
||||
+ while (++current_input_file_index < argc);
|
||||
|
||||
/* Ensure that iconv -c still exits with failure if iconv (the
|
||||
function) has failed with E2BIG instead of EILSEQ. */
|
||||
@@ -298,8 +311,7 @@ conversions from `%s' and to `%s' are no
|
||||
status = EXIT_FAILURE;
|
||||
|
||||
/* Close the output file now. */
|
||||
- if (output != NULL && fclose (output))
|
||||
- error (EXIT_FAILURE, errno, _("error while closing output file"));
|
||||
+ close_output_file (status);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -329,6 +341,14 @@ parse_opt (int key, char *arg, struct ar
|
||||
/* Omit invalid characters from output. */
|
||||
omit_invalid = 1;
|
||||
break;
|
||||
+ case OPT_BUFFER_SIZE:
|
||||
+ {
|
||||
+ int i = atoi (arg);
|
||||
+ if (i <= 0)
|
||||
+ error (EXIT_FAILURE, 0, _("invalid buffer size: %s"), arg);
|
||||
+ output_buffer_size = i;
|
||||
+ }
|
||||
+ break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
@@ -375,59 +395,247 @@ warranty; not even for MERCHANTABILITY o
|
||||
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
|
||||
}
|
||||
|
||||
+/* Command line index of the last input file that overlaps with the
|
||||
+ output file. Zero means no temporary file is ever required. */
|
||||
+static int last_overlapping_file_index;
|
||||
|
||||
-static int
|
||||
-write_output (const char *outbuf, const char *outptr, FILE **output,
|
||||
- const char *output_file)
|
||||
+/* This is set to true if the output is written to a temporary file. */
|
||||
+static bool output_using_temporary_file;
|
||||
+
|
||||
+/* This is the file descriptor that will be used by write_output. */
|
||||
+static int output_fd = -1;
|
||||
+
|
||||
+/* Pointers at the start and end of the fixed-size output buffer. */
|
||||
+static char *output_buffer_start;
|
||||
+
|
||||
+/* Current write position in the output buffer. */
|
||||
+static char *output_buffer_current;
|
||||
+
|
||||
+/* Remaining bytes after output_buffer_current in the output buffer. */
|
||||
+static size_t output_buffer_remaining;
|
||||
+
|
||||
+
|
||||
+/* Reduce the buffer size when writing directly to the output file, to
|
||||
+ reduce cache utilization. */
|
||||
+static size_t copy_buffer_size = BUFSIZ;
|
||||
+
|
||||
+static void
|
||||
+output_error (void)
|
||||
+{
|
||||
+ error (EXIT_FAILURE, errno, _("cannot open output file"));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+input_error (const char *path)
|
||||
{
|
||||
- /* We have something to write out. */
|
||||
- int errno_save = errno;
|
||||
+ error (0, errno, _("cannot open input file `%s'"), path);
|
||||
+}
|
||||
|
||||
- if (*output == NULL)
|
||||
+/* Opens output_file for writing, truncating it. */
|
||||
+static void
|
||||
+open_output_direct (void)
|
||||
+{
|
||||
+ output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
||||
+ if (output_fd < 0)
|
||||
+ output_error ();
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+prepare_output_file (char **argv)
|
||||
+{
|
||||
+ if (copy_buffer_size > output_buffer_size)
|
||||
+ copy_buffer_size = output_buffer_size;
|
||||
+
|
||||
+ if (output_file == NULL || strcmp (output_file, "-") == 0)
|
||||
+ {
|
||||
+ /* No buffering is required when writing to standard output
|
||||
+ because input overlap is expected to be solved externally. */
|
||||
+ output_fd = STDOUT_FILENO;
|
||||
+ output_buffer_size = copy_buffer_size;
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
- /* Determine output file. */
|
||||
- if (output_file != NULL && strcmp (output_file, "-") != 0)
|
||||
+ /* If iconv creates the output file, no overlap is possible. */
|
||||
+ output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
+ if (output_fd >= 0)
|
||||
+ output_buffer_size = copy_buffer_size;
|
||||
+ else
|
||||
{
|
||||
- *output = fopen (output_file, "w");
|
||||
- if (*output == NULL)
|
||||
- error (EXIT_FAILURE, errno, _("cannot open output file"));
|
||||
+ /* Otherwise, check if any of the input files overlap with the
|
||||
+ output file. */
|
||||
+ struct statx st;
|
||||
+ if (statx (AT_FDCWD, output_file, 0, STATX_INO | STATX_MODE, &st)
|
||||
+ != 0)
|
||||
+ output_error ();
|
||||
+ uint32_t out_dev_minor = st.stx_dev_minor;
|
||||
+ uint32_t out_dev_major = st.stx_dev_major;
|
||||
+ uint64_t out_ino = st.stx_ino;
|
||||
+
|
||||
+ int idx = current_input_file_index;
|
||||
+ while (true)
|
||||
+ {
|
||||
+ /* Special case: no input files means standard input. */
|
||||
+ if (argv[idx] == NULL && idx != current_input_file_index)
|
||||
+ break;
|
||||
+
|
||||
+ int ret;
|
||||
+ if (argv[idx] == NULL || strcmp (argv[idx], "-") == 0)
|
||||
+ ret = statx (STDIN_FILENO, "", AT_EMPTY_PATH, STATX_INO, &st);
|
||||
+ else
|
||||
+ ret = statx (AT_FDCWD, argv[idx], 0, STATX_INO, &st);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ input_error (argv[idx]);
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (out_dev_minor == st.stx_dev_minor
|
||||
+ && out_dev_major == st.stx_dev_major
|
||||
+ && out_ino == st.stx_ino)
|
||||
+ {
|
||||
+ if (argv[idx] == NULL)
|
||||
+ /* Corner case: index of NULL would be larger than
|
||||
+ idx while converting, triggering a switch away
|
||||
+ from the temporary file. */
|
||||
+ last_overlapping_file_index = INT_MAX;
|
||||
+ else
|
||||
+ last_overlapping_file_index = idx;
|
||||
+ }
|
||||
+
|
||||
+ if (argv[idx] == NULL)
|
||||
+ break;
|
||||
+ ++idx;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is no overlap, avoid using a temporary file. */
|
||||
+ if (last_overlapping_file_index == 0)
|
||||
+ {
|
||||
+ open_output_direct ();
|
||||
+ output_buffer_size = copy_buffer_size;
|
||||
+ }
|
||||
}
|
||||
- else
|
||||
- *output = stdout;
|
||||
}
|
||||
|
||||
- if (fwrite (outbuf, 1, outptr - outbuf, *output) < (size_t) (outptr - outbuf)
|
||||
- || ferror (*output))
|
||||
+ output_buffer_start = malloc (output_buffer_size);
|
||||
+ if (output_buffer_start == NULL)
|
||||
+ output_error ();
|
||||
+ output_buffer_current = output_buffer_start;
|
||||
+ output_buffer_remaining = output_buffer_size;
|
||||
+}
|
||||
+
|
||||
+/* Write out the range [first, last), terminating the process on write
|
||||
+ error. */
|
||||
+static void
|
||||
+write_fully (int fd, const char *first, const char *last)
|
||||
+{
|
||||
+ while (first < last)
|
||||
{
|
||||
- /* Error occurred while printing the result. */
|
||||
- error (0, 0, _("\
|
||||
+ ssize_t ret = write (fd, first, last - first);
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ errno = ENOSPC;
|
||||
+ output_error ();
|
||||
+ }
|
||||
+ if (ret < 0)
|
||||
+ error (EXIT_FAILURE, errno, _("\
|
||||
conversion stopped due to problem in writing the output"));
|
||||
- return -1;
|
||||
+ first += ret;
|
||||
}
|
||||
+}
|
||||
|
||||
- errno = errno_save;
|
||||
+static void
|
||||
+flush_output (void)
|
||||
+{
|
||||
+ bool temporary_file_not_needed
|
||||
+ = current_input_file_index > last_overlapping_file_index;
|
||||
+ if (output_fd < 0)
|
||||
+ {
|
||||
+ if (temporary_file_not_needed)
|
||||
+ open_output_direct ();
|
||||
+ else
|
||||
+ {
|
||||
+ /* Create an anonymous temporary file. */
|
||||
+ FILE *fp = tmpfile ();
|
||||
+ if (fp == NULL)
|
||||
+ output_error ();
|
||||
+ output_fd = dup (fileno (fp));
|
||||
+ if (output_fd < 0)
|
||||
+ output_error ();
|
||||
+ fclose (fp);
|
||||
+ output_using_temporary_file = true;
|
||||
+ }
|
||||
+ /* Either way, no longer use a memory-only staging buffer. */
|
||||
+ output_buffer_size = copy_buffer_size;
|
||||
+ }
|
||||
+ else if (output_using_temporary_file && temporary_file_not_needed)
|
||||
+ {
|
||||
+ /* The temporary file is no longer needed. Switch to direct
|
||||
+ output, replacing output_fd. */
|
||||
+ int temp_fd = output_fd;
|
||||
+ open_output_direct ();
|
||||
+
|
||||
+ /* Copy over the data spooled to the temporary file. */
|
||||
+ if (lseek (temp_fd, 0, SEEK_SET) < 0)
|
||||
+ output_error ();
|
||||
+ while (true)
|
||||
+ {
|
||||
+ char buf[BUFSIZ];
|
||||
+ ssize_t ret = read (temp_fd, buf, sizeof (buf));
|
||||
+ if (ret < 0)
|
||||
+ output_error ();
|
||||
+ if (ret == 0)
|
||||
+ break;
|
||||
+ write_fully (output_fd, buf, buf + ret);
|
||||
+ }
|
||||
+ close (temp_fd);
|
||||
|
||||
- return 0;
|
||||
+ /* No longer using a temporary file from now on. */
|
||||
+ output_using_temporary_file = false;
|
||||
+ output_buffer_size = copy_buffer_size;
|
||||
+ }
|
||||
+
|
||||
+ write_fully (output_fd, output_buffer_start, output_buffer_current);
|
||||
+ output_buffer_current = output_buffer_start;
|
||||
+ output_buffer_remaining = output_buffer_size;
|
||||
}
|
||||
|
||||
+static void
|
||||
+close_output_file (int status)
|
||||
+{
|
||||
+ /* Do not perform a flush if a temporary file or the in-memory
|
||||
+ buffer is in use and there was an error. It would clobber the
|
||||
+ overlapping input file. */
|
||||
+ if (status != EXIT_SUCCESS && !omit_invalid &&
|
||||
+ (output_using_temporary_file || output_fd < 0))
|
||||
+ return;
|
||||
+
|
||||
+ /* The current_input_file_index variable is now larger than
|
||||
+ last_overlapping_file_index, so the flush_output call switches
|
||||
+ away from the temporary file. */
|
||||
+ flush_output ();
|
||||
+
|
||||
+ if (output_fd == STDOUT_FILENO)
|
||||
+ {
|
||||
+ /* Close standard output in safe manner, to report certain
|
||||
+ ENOSPC errors. */
|
||||
+ output_fd = dup (output_fd);
|
||||
+ if (output_fd < 0)
|
||||
+ output_error ();
|
||||
+ }
|
||||
+ if (close (output_fd) < 0)
|
||||
+ output_error ();
|
||||
+}
|
||||
|
||||
static int
|
||||
-process_block (iconv_t cd, char *addr, size_t len, FILE **output,
|
||||
- const char *output_file)
|
||||
+process_block (iconv_t cd, char *addr, size_t len)
|
||||
{
|
||||
-#define OUTBUF_SIZE 32768
|
||||
const char *start = addr;
|
||||
- char outbuf[OUTBUF_SIZE];
|
||||
- char *outptr;
|
||||
- size_t outlen;
|
||||
size_t n;
|
||||
int ret = 0;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
- outptr = outbuf;
|
||||
- outlen = OUTBUF_SIZE;
|
||||
- n = iconv (cd, &addr, &len, &outptr, &outlen);
|
||||
+ n = iconv (cd, &addr, &len,
|
||||
+ &output_buffer_current, &output_buffer_remaining);
|
||||
|
||||
if (n == (size_t) -1 && omit_invalid && errno == EILSEQ)
|
||||
{
|
||||
@@ -438,39 +646,34 @@ process_block (iconv_t cd, char *addr, s
|
||||
errno = E2BIG;
|
||||
}
|
||||
|
||||
- if (outptr != outbuf)
|
||||
- {
|
||||
- ret = write_output (outbuf, outptr, output, output_file);
|
||||
- if (ret != 0)
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
if (n != (size_t) -1)
|
||||
{
|
||||
/* All the input test is processed. For state-dependent
|
||||
character sets we have to flush the state now. */
|
||||
- outptr = outbuf;
|
||||
- outlen = OUTBUF_SIZE;
|
||||
- n = iconv (cd, NULL, NULL, &outptr, &outlen);
|
||||
-
|
||||
- if (outptr != outbuf)
|
||||
+ n = iconv (cd, NULL, NULL,
|
||||
+ &output_buffer_current, &output_buffer_remaining);
|
||||
+ if (n == (size_t) -1 && errno == E2BIG)
|
||||
{
|
||||
- ret = write_output (outbuf, outptr, output, output_file);
|
||||
- if (ret != 0)
|
||||
- break;
|
||||
+ /* Try again if the state flush exceeded the buffer space. */
|
||||
+ flush_output ();
|
||||
+ n = iconv (cd, NULL, NULL,
|
||||
+ &output_buffer_current, &output_buffer_remaining);
|
||||
}
|
||||
+ bool errno_is_EILSEQ = errno == EILSEQ;
|
||||
|
||||
if (n != (size_t) -1)
|
||||
break;
|
||||
|
||||
- if (omit_invalid && errno == EILSEQ)
|
||||
+ if (omit_invalid && errno_is_EILSEQ)
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- if (errno != E2BIG)
|
||||
+ if (errno == E2BIG)
|
||||
+ flush_output ();
|
||||
+ else
|
||||
{
|
||||
/* iconv() ran into a problem. */
|
||||
switch (errno)
|
||||
@@ -501,7 +704,7 @@ incomplete character or shift sequence a
|
||||
|
||||
|
||||
static int
|
||||
-process_fd (iconv_t cd, int fd, FILE **output, const char *output_file)
|
||||
+process_fd (iconv_t cd, int fd)
|
||||
{
|
||||
/* we have a problem with reading from a descriptor since we must not
|
||||
provide the iconv() function an incomplete character or shift
|
||||
@@ -575,16 +778,16 @@ process_fd (iconv_t cd, int fd, FILE **o
|
||||
}
|
||||
|
||||
/* Now we have all the input in the buffer. Process it in one run. */
|
||||
- return process_block (cd, inbuf, actlen, output, output_file);
|
||||
+ return process_block (cd, inbuf, actlen);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
-process_file (iconv_t cd, FILE *input, FILE **output, const char *output_file)
|
||||
+process_file (iconv_t cd, FILE *input)
|
||||
{
|
||||
/* This should be safe since we use this function only for `stdin' and
|
||||
we haven't read anything so far. */
|
||||
- return process_fd (cd, fileno (input), output, output_file);
|
||||
+ return process_fd (cd, fileno (input));
|
||||
}
|
||||
|
||||
|
||||
diff -Nrup a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh
|
||||
--- a/iconv/tst-iconv_prog-buffer.sh 2024-11-21 11:08:26.168051544 -0500
|
||||
+++ b/iconv/tst-iconv_prog-buffer.sh 2024-11-21 11:08:51.326219757 -0500
|
||||
@@ -17,6 +17,12 @@
|
||||
# License along with the GNU C Library; if not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
|
||||
+# Arguments:
|
||||
+# root of the build tree ($(objpfx-common))
|
||||
+# test command wrapper (for running on the board/with new ld.so)
|
||||
+# extra flags to pass to iconv
|
||||
+# number of times to double the input files in size (default: 0)
|
||||
+
|
||||
exec 2>&1
|
||||
set -e
|
||||
|
||||
@@ -26,7 +32,9 @@ codir=$1
|
||||
test_program_prefix="$2"
|
||||
|
||||
# Use internal converters to avoid issues with module loading.
|
||||
-iconv_args="-f ASCII -t UTF-8"
|
||||
+iconv_args="-f ASCII -t UTF-8 $3"
|
||||
+
|
||||
+file_size_doublings=${4-0}
|
||||
|
||||
failure=false
|
||||
|
||||
@@ -39,7 +47,19 @@ echo HH > "$tmp/hh"
|
||||
echo XY > "$tmp/xy"
|
||||
echo ZT > "$tmp/zt"
|
||||
echo OUT > "$tmp/out-template"
|
||||
+: > "$tmp/empty"
|
||||
printf '\xff' > "$tmp/0xff"
|
||||
+
|
||||
+# Double all files to produce larger buffers.
|
||||
+for p in "$tmp"/* ; do
|
||||
+ i=0
|
||||
+ while test $i -lt $file_size_doublings; do
|
||||
+ cat "$p" "$p" > "$tmp/scratch"
|
||||
+ mv "$tmp/scratch" "$p"
|
||||
+ i=$(($i + 1))
|
||||
+ done
|
||||
+done
|
||||
+
|
||||
cat "$tmp/xy" "$tmp/0xff" "$tmp/zt" > "$tmp/0xff-wrapped"
|
||||
|
||||
run_iconv () {
|
||||
@@ -113,6 +133,38 @@ expect_files abc def
|
||||
run_iconv -o "$tmp/out" "$tmp/out" "$tmp/abc"
|
||||
expect_files abc def abc
|
||||
|
||||
+run_iconv -o "$tmp/out" "$tmp/ggg" "$tmp/out"
|
||||
+expect_files ggg abc def abc
|
||||
+
|
||||
+run_iconv -o "$tmp/out" "$tmp/hh" "$tmp/out" "$tmp/hh"
|
||||
+expect_files hh ggg abc def abc hh
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -o "$tmp/out" "$tmp/ggg" "$tmp/out" "$tmp/out" "$tmp/ggg"
|
||||
+expect_files ggg out-template out-template ggg
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -o "$tmp/out" "$tmp/ggg" "$tmp/out" "$tmp/hh" "$tmp/out" "$tmp/ggg"
|
||||
+expect_files ggg out-template hh out-template ggg
|
||||
+
|
||||
+# Empty output should truncate the output file if exists.
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -o "$tmp/out" </dev/null
|
||||
+expect_files empty
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -o "$tmp/out" - </dev/null
|
||||
+expect_files empty
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+run_iconv -o "$tmp/out" /dev/null
|
||||
+expect_files empty
|
||||
+
|
||||
+cp "$tmp/out-template" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -c -o "$tmp/out" "$tmp/0xff"
|
||||
+expect_files empty
|
||||
+
|
||||
# But not if we are writing to standard output.
|
||||
|
||||
cp "$tmp/out-template" "$tmp/out"
|
||||
@@ -142,8 +194,36 @@ cp "$tmp/0xff" "$tmp/out"
|
||||
expect_exit 1 run_iconv -o "$tmp/out" - < "$tmp/out"
|
||||
expect_files 0xff
|
||||
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/out"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" < "$tmp/out"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" - < "$tmp/out"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" "$tmp/out"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" - < "$tmp/out"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
# If errors are ignored, the file should be overwritten.
|
||||
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -c -o "$tmp/out" "$tmp/out"
|
||||
+expect_files xy zt
|
||||
+
|
||||
+cp "$tmp/0xff" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -c -o "$tmp/out" "$tmp/abc" "$tmp/out" "$tmp/def"
|
||||
+expect_files abc def
|
||||
+
|
||||
cp "$tmp/out-template" "$tmp/out"
|
||||
expect_exit 1 \
|
||||
run_iconv -c -o "$tmp/out" "$tmp/abc" "$tmp/0xff" "$tmp/def" 2>"$tmp/err"
|
||||
@@ -156,6 +236,20 @@ expect_exit 1 run_iconv -c -o "$tmp/out"
|
||||
! test -s "$tmp/err"
|
||||
expect_files abc xy zt def
|
||||
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -c -o "$tmp/out" "$tmp/out" "$tmp/abc" "$tmp/out" "$tmp/def"
|
||||
+expect_files xy zt abc xy zt def
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" \
|
||||
+ "$tmp/out" "$tmp/abc" "$tmp/out" "$tmp/def"
|
||||
+expect_files 0xff-wrapped
|
||||
+
|
||||
+cp "$tmp/0xff-wrapped" "$tmp/out"
|
||||
+expect_exit 1 run_iconv -c -o "$tmp/out" \
|
||||
+ "$tmp/abc" "$tmp/out" "$tmp/def" "$tmp/out"
|
||||
+expect_files abc xy zt def xy zt
|
||||
+
|
||||
# If the file does not exist yet, it should not be created on error.
|
||||
|
||||
rm "$tmp/out"
|
41
SOURCES/glibc-RHEL-1915-7.patch
Normal file
41
SOURCES/glibc-RHEL-1915-7.patch
Normal file
@ -0,0 +1,41 @@
|
||||
commit 75819cdd29a193cc2db980878bec305905b22bbc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
iconv: Multiple - on command line should not fail (bug 32050)
|
||||
|
||||
Usually, the second and subsequent - return EOF immediately
|
||||
and do not contribute to the output, but this is not an error.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
|
||||
index 3e02db7319..dd4bc3a59a 100644
|
||||
--- a/iconv/iconv_prog.c
|
||||
+++ b/iconv/iconv_prog.c
|
||||
@@ -287,7 +287,8 @@ conversions from `%s' and to `%s' are not supported"),
|
||||
ret = process_fd (cd, fd);
|
||||
|
||||
/* Now close the file. */
|
||||
- close (fd);
|
||||
+ if (fd != STDIN_FILENO)
|
||||
+ close (fd);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
diff --git a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh
|
||||
index 54ff871d32..a9c3729d94 100644
|
||||
--- a/iconv/tst-iconv_prog-buffer.sh
|
||||
+++ b/iconv/tst-iconv_prog-buffer.sh
|
||||
@@ -265,6 +265,11 @@ expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" "$tmp/0xff" "$tmp/def"
|
||||
expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" - < "$tmp/0xff" "$tmp/def"
|
||||
! test -e "$tmp/out"
|
||||
|
||||
+# Listing standard input multiple times should not fail (bug 32050).
|
||||
+
|
||||
+run_iconv -o "$tmp/out" "$tmp/xy" - - "$tmp/zt" < "$tmp/abc"
|
||||
+expect_files xy abc zt
|
||||
+
|
||||
if $failure ; then
|
||||
exit 1
|
||||
fi
|
323
SOURCES/glibc-RHEL-1915-8.patch
Normal file
323
SOURCES/glibc-RHEL-1915-8.patch
Normal file
@ -0,0 +1,323 @@
|
||||
commit fa1b0d5e9f6e0353e16339430770a7a8824c0468
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Sep 20 13:10:54 2024 +0200
|
||||
|
||||
iconv: Input buffering for the iconv program (bug 6050)
|
||||
|
||||
Do not read the entire input file into memory.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
|
||||
index dd4bc3a59a..a2f1d34e45 100644
|
||||
--- a/iconv/iconv_prog.c
|
||||
+++ b/iconv/iconv_prog.c
|
||||
@@ -118,8 +118,9 @@ static size_t output_buffer_size = 1024 * 1024;
|
||||
|
||||
/* Prototypes for the functions doing the actual work. */
|
||||
static void prepare_output_file (char **argv);
|
||||
-static void close_output_file (int status);
|
||||
-static int process_block (iconv_t cd, char *addr, size_t len);
|
||||
+static void close_output_file (__gconv_t cd, int status);
|
||||
+static int process_block (iconv_t cd, char **addr, size_t *len,
|
||||
+ off64_t file_offset, bool *incomplete);
|
||||
static int process_fd (iconv_t cd, int fd);
|
||||
static int process_file (iconv_t cd, FILE *input);
|
||||
static void print_known_names (void);
|
||||
@@ -311,7 +312,7 @@ conversions from `%s' and to `%s' are not supported"),
|
||||
status = EXIT_FAILURE;
|
||||
|
||||
/* Close the output file now. */
|
||||
- close_output_file (status);
|
||||
+ close_output_file (cd, status);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -599,7 +600,7 @@ flush_output (void)
|
||||
}
|
||||
|
||||
static void
|
||||
-close_output_file (int status)
|
||||
+close_output_file (__gconv_t cd, int status)
|
||||
{
|
||||
/* Do not perform a flush if a temporary file or the in-memory
|
||||
buffer is in use and there was an error. It would clobber the
|
||||
@@ -608,10 +609,28 @@ close_output_file (int status)
|
||||
(output_using_temporary_file || output_fd < 0))
|
||||
return;
|
||||
|
||||
- /* The current_input_file_index variable is now larger than
|
||||
- last_overlapping_file_index, so the flush_output call switches
|
||||
+ /* All the input text is processed. For state-dependent character
|
||||
+ sets we have to flush the state now.
|
||||
+
|
||||
+ The current_input_file_index variable is now larger than
|
||||
+ last_overlapping_file_index, so the flush_output calls switch
|
||||
away from the temporary file. */
|
||||
+ size_t n = iconv (cd, NULL, NULL,
|
||||
+ &output_buffer_current, &output_buffer_remaining);
|
||||
+ if (n == (size_t) -1 && errno == E2BIG)
|
||||
+ {
|
||||
+ /* Try again if the state flush exceeded the buffer space. */
|
||||
+ flush_output ();
|
||||
+ n = iconv (cd, NULL, NULL,
|
||||
+ &output_buffer_current, &output_buffer_remaining);
|
||||
+ }
|
||||
+ int saved_errno = errno;
|
||||
flush_output ();
|
||||
+ if (n == (size_t) -1 && !omit_invalid)
|
||||
+ {
|
||||
+ errno = saved_errno;
|
||||
+ output_error ();
|
||||
+ }
|
||||
|
||||
if (output_fd == STDOUT_FILENO)
|
||||
{
|
||||
@@ -625,51 +644,35 @@ close_output_file (int status)
|
||||
output_error ();
|
||||
}
|
||||
|
||||
+/* CD is the iconv handle. Input processing starts at *ADDR, and
|
||||
+ consumes upto *LEN bytes. *ADDR and *LEN are updated. FILE_OFFSET
|
||||
+ is the file offset of the data initially at ADDR. *INCOMPLETE is
|
||||
+ set to true if conversion stops due to an incomplete input
|
||||
+ sequence. */
|
||||
static int
|
||||
-process_block (iconv_t cd, char *addr, size_t len)
|
||||
+process_block (iconv_t cd, char **addr, size_t *len, off64_t file_offset,
|
||||
+ bool *incomplete)
|
||||
{
|
||||
- const char *start = addr;
|
||||
+ const char *start = *addr;
|
||||
size_t n;
|
||||
int ret = 0;
|
||||
|
||||
- while (len > 0)
|
||||
+ while (*len > 0)
|
||||
{
|
||||
- n = iconv (cd, &addr, &len,
|
||||
+ n = iconv (cd, addr, len,
|
||||
&output_buffer_current, &output_buffer_remaining);
|
||||
|
||||
if (n == (size_t) -1 && omit_invalid && errno == EILSEQ)
|
||||
{
|
||||
ret = 1;
|
||||
- if (len == 0)
|
||||
+ if (*len == 0)
|
||||
n = 0;
|
||||
else
|
||||
errno = E2BIG;
|
||||
}
|
||||
|
||||
if (n != (size_t) -1)
|
||||
- {
|
||||
- /* All the input test is processed. For state-dependent
|
||||
- character sets we have to flush the state now. */
|
||||
- n = iconv (cd, NULL, NULL,
|
||||
- &output_buffer_current, &output_buffer_remaining);
|
||||
- if (n == (size_t) -1 && errno == E2BIG)
|
||||
- {
|
||||
- /* Try again if the state flush exceeded the buffer space. */
|
||||
- flush_output ();
|
||||
- n = iconv (cd, NULL, NULL,
|
||||
- &output_buffer_current, &output_buffer_remaining);
|
||||
- }
|
||||
- bool errno_is_EILSEQ = errno == EILSEQ;
|
||||
-
|
||||
- if (n != (size_t) -1)
|
||||
- break;
|
||||
-
|
||||
- if (omit_invalid && errno_is_EILSEQ)
|
||||
- {
|
||||
- ret = 1;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
+ break;
|
||||
|
||||
if (errno == E2BIG)
|
||||
flush_output ();
|
||||
@@ -680,13 +683,12 @@ process_block (iconv_t cd, char *addr, size_t len)
|
||||
{
|
||||
case EILSEQ:
|
||||
if (! omit_invalid)
|
||||
- error (0, 0, _("illegal input sequence at position %ld"),
|
||||
- (long int) (addr - start));
|
||||
+ error (0, 0, _("illegal input sequence at position %lld"),
|
||||
+ (long long int) (file_offset + (*addr - start)));
|
||||
break;
|
||||
case EINVAL:
|
||||
- error (0, 0, _("\
|
||||
-incomplete character or shift sequence at end of buffer"));
|
||||
- break;
|
||||
+ *incomplete = true;
|
||||
+ return ret;
|
||||
case EBADF:
|
||||
error (0, 0, _("internal error (illegal descriptor)"));
|
||||
break;
|
||||
@@ -706,79 +708,49 @@ incomplete character or shift sequence at end of buffer"));
|
||||
static int
|
||||
process_fd (iconv_t cd, int fd)
|
||||
{
|
||||
- /* we have a problem with reading from a descriptor since we must not
|
||||
- provide the iconv() function an incomplete character or shift
|
||||
- sequence at the end of the buffer. Since we have to deal with
|
||||
- arbitrary encodings we must read the whole text in a buffer and
|
||||
- process it in one step. */
|
||||
- static char *inbuf = NULL;
|
||||
- static size_t maxlen = 0;
|
||||
- char *inptr = inbuf;
|
||||
- size_t actlen = 0;
|
||||
-
|
||||
- while (actlen < maxlen)
|
||||
+ char inbuf[BUFSIZ];
|
||||
+ char *inbuf_end = inbuf + sizeof (inbuf);
|
||||
+ size_t inbuf_used = 0;
|
||||
+ off64_t file_offset = 0;
|
||||
+ int status = 0;
|
||||
+ bool incomplete = false;
|
||||
+
|
||||
+ while (true)
|
||||
{
|
||||
- ssize_t n = read (fd, inptr, maxlen - actlen);
|
||||
-
|
||||
- if (n == 0)
|
||||
- /* No more text to read. */
|
||||
- break;
|
||||
-
|
||||
- if (n == -1)
|
||||
+ char *p = inbuf + inbuf_used;
|
||||
+ ssize_t read_ret = read (fd, p, inbuf_end - p);
|
||||
+ if (read_ret == 0)
|
||||
+ {
|
||||
+ /* On EOF, check if the previous iconv invocation saw an
|
||||
+ incomplete sequence. */
|
||||
+ if (incomplete)
|
||||
+ {
|
||||
+ error (0, 0, _("\
|
||||
+incomplete character or shift sequence at end of buffer"));
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (read_ret < 0)
|
||||
{
|
||||
- /* Error while reading. */
|
||||
error (0, errno, _("error while reading the input"));
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- inptr += n;
|
||||
- actlen += n;
|
||||
+ inbuf_used += read_ret;
|
||||
+ incomplete = false;
|
||||
+ p = inbuf;
|
||||
+ int ret = process_block (cd, &p, &inbuf_used, file_offset, &incomplete);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ status = ret;
|
||||
+ if (ret < 0)
|
||||
+ break;
|
||||
+ }
|
||||
+ /* The next loop iteration consumes the leftover bytes. */
|
||||
+ memmove (inbuf, p, inbuf_used);
|
||||
+ file_offset += read_ret - inbuf_used;
|
||||
}
|
||||
-
|
||||
- if (actlen == maxlen)
|
||||
- while (1)
|
||||
- {
|
||||
- ssize_t n;
|
||||
- char *new_inbuf;
|
||||
-
|
||||
- /* Increase the buffer. */
|
||||
- new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
|
||||
- if (new_inbuf == NULL)
|
||||
- {
|
||||
- error (0, errno, _("unable to allocate buffer for input"));
|
||||
- return -1;
|
||||
- }
|
||||
- inbuf = new_inbuf;
|
||||
- maxlen += 32768;
|
||||
- inptr = inbuf + actlen;
|
||||
-
|
||||
- do
|
||||
- {
|
||||
- n = read (fd, inptr, maxlen - actlen);
|
||||
-
|
||||
- if (n == 0)
|
||||
- /* No more text to read. */
|
||||
- break;
|
||||
-
|
||||
- if (n == -1)
|
||||
- {
|
||||
- /* Error while reading. */
|
||||
- error (0, errno, _("error while reading the input"));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- inptr += n;
|
||||
- actlen += n;
|
||||
- }
|
||||
- while (actlen < maxlen);
|
||||
-
|
||||
- if (n == 0)
|
||||
- /* Break again so we leave both loops. */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* Now we have all the input in the buffer. Process it in one run. */
|
||||
- return process_block (cd, inbuf, actlen);
|
||||
+ return status;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh
|
||||
index a9c3729d94..23098ac56a 100644
|
||||
--- a/iconv/tst-iconv_prog-buffer.sh
|
||||
+++ b/iconv/tst-iconv_prog-buffer.sh
|
||||
@@ -50,6 +50,9 @@ echo OUT > "$tmp/out-template"
|
||||
: > "$tmp/empty"
|
||||
printf '\xff' > "$tmp/0xff"
|
||||
|
||||
+# Length should be a prime number, to help with buffer alignment testing.
|
||||
+printf '\xc3\xa4\xe2\x80\x94\xe2\x80\x94\xc3\xa4\n' > "$tmp/utf8-sequence"
|
||||
+
|
||||
# Double all files to produce larger buffers.
|
||||
for p in "$tmp"/* ; do
|
||||
i=0
|
||||
@@ -270,6 +273,34 @@ expect_exit 1 run_iconv -o "$tmp/out" "$tmp/abc" - < "$tmp/0xff" "$tmp/def"
|
||||
run_iconv -o "$tmp/out" "$tmp/xy" - - "$tmp/zt" < "$tmp/abc"
|
||||
expect_files xy abc zt
|
||||
|
||||
+# NB: Extra iconv args are ignored after this point. Actual
|
||||
+# multi-byte conversion does not work with tiny buffers.
|
||||
+iconv_args="-f UTF-8 -t ASCII"
|
||||
+
|
||||
+printf 'x\n\xc3' > "$tmp/incomplete"
|
||||
+expect_exit 1 run_iconv -o "$tmp/out" "$tmp/incomplete"
|
||||
+check_out <<EOF
|
||||
+x
|
||||
+EOF
|
||||
+
|
||||
+# Test buffering behavior if the buffer ends with an incomplete
|
||||
+# multi-byte sequence.
|
||||
+prefix=""
|
||||
+prefix_length=0
|
||||
+while test $prefix_length -lt 12; do
|
||||
+ echo "info: testing prefix length $prefix_length" 2>&$logfd
|
||||
+ printf "%s" "$prefix" > "$tmp/prefix"
|
||||
+ cat "$tmp/prefix" "$tmp/utf8-sequence" > "$tmp/tmp"
|
||||
+ iconv_args="-f UTF-8 -t UCS-4"
|
||||
+ run_iconv -o "$tmp/out1" "$tmp/tmp"
|
||||
+ iconv_args="-f UCS-4 -t UTF-8"
|
||||
+ run_iconv -o "$tmp/out" "$tmp/out1"
|
||||
+ expect_files prefix utf8-sequence
|
||||
+
|
||||
+ prefix="$prefix@"
|
||||
+ prefix_length=$(($prefix_length + 1))
|
||||
+done
|
||||
+
|
||||
if $failure ; then
|
||||
exit 1
|
||||
fi
|
37
SOURCES/glibc-RHEL-1915-9.patch
Normal file
37
SOURCES/glibc-RHEL-1915-9.patch
Normal file
@ -0,0 +1,37 @@
|
||||
commit 079ebf7624e7fd0ad7fe94a7176a2e132c996d86
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 24 10:41:35 2024 +0200
|
||||
|
||||
iconv: Use $(run-program-prefix) for running iconv (bug 32197)
|
||||
|
||||
With --enable-hardcoded-path-in-tests, $(test-program-prefix)
|
||||
does not redirect to the built glibc, but we need to run
|
||||
iconv (the program) against the built glibc even with
|
||||
--enable-hardcoded-path-in-tests, as it is using the ABI
|
||||
path for the dynamic linker (as an installed program).
|
||||
Use $(run-program-prefix) instead.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/iconv/Makefile b/iconv/Makefile
|
||||
index c9af0c4d44..de9d964ed3 100644
|
||||
--- a/iconv/Makefile
|
||||
+++ b/iconv/Makefile
|
||||
@@ -153,14 +153,14 @@ $(objpfx)tst-translit-mchar.out: tst-translit-mchar.sh \
|
||||
|
||||
$(objpfx)tst-iconv_prog-buffer.out: \
|
||||
tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
- $(BASH) $< $(common-objdir) '$(test-program-prefix)' > $@; \
|
||||
+ $(BASH) $< $(common-objdir) '$(run-program-prefix)' > $@; \
|
||||
$(evaluate-test)
|
||||
$(objpfx)tst-iconv_prog-buffer-tiny.out: \
|
||||
tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
- $(BASH) $< $(common-objdir) '$(test-program-prefix)' \
|
||||
+ $(BASH) $< $(common-objdir) '$(run-program-prefix)' \
|
||||
'--buffer-size=1' > $@; \
|
||||
$(evaluate-test)
|
||||
$(objpfx)tst-iconv_prog-buffer-large.out: \
|
||||
tst-iconv_prog-buffer.sh $(objpfx)iconv_prog
|
||||
- $(BASH) $< $(common-objdir) '$(test-program-prefix)' '' '22' > $@; \
|
||||
+ $(BASH) $< $(common-objdir) '$(run-program-prefix)' '' '22' > $@; \
|
||||
$(evaluate-test)
|
447
SOURCES/glibc-RHEL-2419-1.patch
Normal file
447
SOURCES/glibc-RHEL-2419-1.patch
Normal file
@ -0,0 +1,447 @@
|
||||
commit 1db84775f831a1494993ce9c118deaf9537cc50a
|
||||
Author: Frank Barrus <frankbarrus_sw@shaggy.cc>
|
||||
Date: Wed Dec 4 07:55:02 2024 -0500
|
||||
|
||||
pthreads NPTL: lost wakeup fix 2
|
||||
|
||||
This fixes the lost wakeup (from a bug in signal stealing) with a change
|
||||
in the usage of g_signals[] in the condition variable internal state.
|
||||
It also completely eliminates the concept and handling of signal stealing,
|
||||
as well as the need for signalers to block to wait for waiters to wake
|
||||
up every time there is a G1/G2 switch. This greatly reduces the average
|
||||
and maximum latency for pthread_cond_signal.
|
||||
|
||||
The g_signals[] field now contains a signal count that is relative to
|
||||
the current g1_start value. Since it is a 32-bit field, and the LSB is
|
||||
still reserved (though not currently used anymore), it has a 31-bit value
|
||||
that corresponds to the low 31 bits of the sequence number in g1_start.
|
||||
(since g1_start also has an LSB flag, this means bits 31:1 in g_signals
|
||||
correspond to bits 31:1 in g1_start, plus the current signal count)
|
||||
|
||||
By making the signal count relative to g1_start, there is no longer
|
||||
any ambiguity or A/B/A issue, and thus any checks before blocking,
|
||||
including the futex call itself, are guaranteed not to block if the G1/G2
|
||||
switch occurs, even if the signal count remains the same. This allows
|
||||
initially safely blocking in G2 until the switch to G1 occurs, and
|
||||
then transitioning from G1 to a new G1 or G2, and always being able to
|
||||
distinguish the state change. This removes the race condition and A/B/A
|
||||
problems that otherwise ocurred if a late (pre-empted) waiter were to
|
||||
resume just as the futex call attempted to block on g_signal since
|
||||
otherwise there was no last opportunity to re-check things like whether
|
||||
the current G1 group was already closed.
|
||||
|
||||
By fixing these issues, the signal stealing code can be eliminated,
|
||||
since there is no concept of signal stealing anymore. The code to block
|
||||
for all waiters to exit g_refs can also be removed, since any waiters
|
||||
that are still in the g_refs region can be guaranteed to safely wake
|
||||
up and exit. If there are still any left at this time, they are all
|
||||
sent one final futex wakeup to ensure that they are not blocked any
|
||||
longer, but there is no need for the signaller to block and wait for
|
||||
them to wake up and exit the g_refs region.
|
||||
|
||||
The signal count is then effectively "zeroed" but since it is now
|
||||
relative to g1_start, this is done by advancing it to a new value that
|
||||
can be observed by any pending blocking waiters. Any late waiters can
|
||||
always tell the difference, and can thus just cleanly exit if they are
|
||||
in a stale G1 or G2. They can never steal a signal from the current
|
||||
G1 if they are not in the current G1, since the signal value that has
|
||||
to match in the cmpxchg has the low 31 bits of the g1_start value
|
||||
contained in it, and that's first checked, and then it won't match if
|
||||
there's a G1/G2 change.
|
||||
|
||||
Note: the 31-bit sequence number used in g_signals is designed to
|
||||
handle wrap-around when checking the signal count, but if the entire
|
||||
31-bit wraparound (2 billion signals) occurs while there is still a
|
||||
late waiter that has not yet resumed, and it happens to then match
|
||||
the current g1_start low bits, and the pre-emption occurs after the
|
||||
normal "closed group" checks (which are 64-bit) but then hits the
|
||||
futex syscall and signal consuming code, then an A/B/A issue could
|
||||
still result and cause an incorrect assumption about whether it
|
||||
should block. This particular scenario seems unlikely in practice.
|
||||
Note that once awake from the futex, the waiter would notice the
|
||||
closed group before consuming the signal (since that's still a 64-bit
|
||||
check that would not be aliased in the wrap-around in g_signals),
|
||||
so the biggest impact would be blocking on the futex until the next
|
||||
full wakeup from a G1/G2 switch.
|
||||
|
||||
Signed-off-by: Frank Barrus <frankbarrus_sw@shaggy.cc>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
# Conflicts:
|
||||
# nptl/pthread_cond_common.c (Missing spelling fixes)
|
||||
# nptl/pthread_cond_wait.c (Likewise)
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index c35b9ef03afd2c64..b1565b780d175d3a 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -341,7 +341,6 @@ static bool __attribute__ ((unused))
|
||||
__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
unsigned int *g1index, int private)
|
||||
{
|
||||
- const unsigned int maxspin = 0;
|
||||
unsigned int g1 = *g1index;
|
||||
|
||||
/* If there is no waiter in G2, we don't do anything. The expression may
|
||||
@@ -362,84 +361,46 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
into G2 until we atomically make the switch. Waiters existing in G2
|
||||
are not affected.
|
||||
- * Waiters in G1 will be closed out immediately by setting a flag in
|
||||
- __g_signals, which will prevent waiters from blocking using a futex on
|
||||
- __g_signals and also notifies them that the group is closed. As a
|
||||
- result, they will eventually remove their group reference, allowing us
|
||||
- to close switch group roles. */
|
||||
-
|
||||
- /* First, set the closed flag on __g_signals. This tells waiters that are
|
||||
- about to wait that they shouldn't do that anymore. This basically
|
||||
- serves as an advance notificaton of the upcoming change to __g1_start;
|
||||
- waiters interpret it as if __g1_start was larger than their waiter
|
||||
- sequence position. This allows us to change __g1_start after waiting
|
||||
- for all existing waiters with group references to leave, which in turn
|
||||
- makes recovery after stealing a signal simpler because it then can be
|
||||
- skipped if __g1_start indicates that the group is closed (otherwise,
|
||||
- we would have to recover always because waiters don't know how big their
|
||||
- groups are). Relaxed MO is fine. */
|
||||
- atomic_fetch_or_relaxed (cond->__data.__g_signals + g1, 1);
|
||||
-
|
||||
- /* Wait until there are no group references anymore. The fetch-or operation
|
||||
- injects us into the modification order of __g_refs; release MO ensures
|
||||
- that waiters incrementing __g_refs after our fetch-or see the previous
|
||||
- changes to __g_signals and to __g1_start that had to happen before we can
|
||||
- switch this G1 and alias with an older group (we have two groups, so
|
||||
- aliasing requires switching group roles twice). Note that nobody else
|
||||
- can have set the wake-request flag, so we do not have to act upon it.
|
||||
-
|
||||
- Also note that it is harmless if older waiters or waiters from this G1
|
||||
- get a group reference after we have quiesced the group because it will
|
||||
- remain closed for them either because of the closed flag in __g_signals
|
||||
- or the later update to __g1_start. New waiters will never arrive here
|
||||
- but instead continue to go into the still current G2. */
|
||||
- unsigned r = atomic_fetch_or_release (cond->__data.__g_refs + g1, 0);
|
||||
- while ((r >> 1) > 0)
|
||||
- {
|
||||
- for (unsigned int spin = maxspin; ((r >> 1) > 0) && (spin > 0); spin--)
|
||||
- {
|
||||
- /* TODO Back off. */
|
||||
- r = atomic_load_relaxed (cond->__data.__g_refs + g1);
|
||||
- }
|
||||
- if ((r >> 1) > 0)
|
||||
- {
|
||||
- /* There is still a waiter after spinning. Set the wake-request
|
||||
- flag and block. Relaxed MO is fine because this is just about
|
||||
- this futex word.
|
||||
-
|
||||
- Update r to include the set wake-request flag so that the upcoming
|
||||
- futex_wait only blocks if the flag is still set (otherwise, we'd
|
||||
- violate the basic client-side futex protocol). */
|
||||
- r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
|
||||
-
|
||||
- if ((r >> 1) > 0)
|
||||
- futex_wait_simple (cond->__data.__g_refs + g1, r, private);
|
||||
- /* Reload here so we eventually see the most recent value even if we
|
||||
- do not spin. */
|
||||
- r = atomic_load_relaxed (cond->__data.__g_refs + g1);
|
||||
- }
|
||||
- }
|
||||
- /* Acquire MO so that we synchronize with the release operation that waiters
|
||||
- use to decrement __g_refs and thus happen after the waiters we waited
|
||||
- for. */
|
||||
- atomic_thread_fence_acquire ();
|
||||
+ * Waiters in G1 will be closed out immediately by the advancing of
|
||||
+ __g_signals to the next "lowseq" (low 31 bits of the new g1_start),
|
||||
+ which will prevent waiters from blocking using a futex on
|
||||
+ __g_signals since it provides enough signals for all possible
|
||||
+ remaining waiters. As a result, they can each consume a signal
|
||||
+ and they will eventually remove their group reference. */
|
||||
|
||||
/* Update __g1_start, which finishes closing this group. The value we add
|
||||
will never be negative because old_orig_size can only be zero when we
|
||||
switch groups the first time after a condvar was initialized, in which
|
||||
- case G1 will be at index 1 and we will add a value of 1. See above for
|
||||
- why this takes place after waiting for quiescence of the group.
|
||||
+ case G1 will be at index 1 and we will add a value of 1.
|
||||
Relaxed MO is fine because the change comes with no additional
|
||||
constraints that others would have to observe. */
|
||||
__condvar_add_g1_start_relaxed (cond,
|
||||
(old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
|
||||
- /* Now reopen the group, thus enabling waiters to again block using the
|
||||
- futex controlled by __g_signals. Release MO so that observers that see
|
||||
- no signals (and thus can block) also see the write __g1_start and thus
|
||||
- that this is now a new group (see __pthread_cond_wait_common for the
|
||||
- matching acquire MO loads). */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, 0);
|
||||
+ unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
+
|
||||
+ /* If any waiters still hold group references (and thus could be blocked),
|
||||
+ then wake them all up now and prevent any running ones from blocking.
|
||||
+ This is effectively a catch-all for any possible current or future
|
||||
+ bugs that can allow the group size to reach 0 before all G1 waiters
|
||||
+ have been awakened or at least given signals to consume, or any
|
||||
+ other case that can leave blocked (or about to block) older waiters.. */
|
||||
+ if ((atomic_fetch_or_release (cond->__data.__g_refs + g1, 0) >> 1) > 0)
|
||||
+ {
|
||||
+ /* First advance signals to the end of the group (i.e. enough signals
|
||||
+ for the entire G1 group) to ensure that waiters which have not
|
||||
+ yet blocked in the futex will not block.
|
||||
+ Note that in the vast majority of cases, this should never
|
||||
+ actually be necessary, since __g_signals will have enough
|
||||
+ signals for the remaining g_refs waiters. As an optimization,
|
||||
+ we could check this first before proceeding, although that
|
||||
+ could still leave the potential for futex lost wakeup bugs
|
||||
+ if the signal count was non-zero but the futex wakeup
|
||||
+ was somehow lost. */
|
||||
+ atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
+
|
||||
+ futex_wake (cond->__data.__g_signals + g1, INT_MAX, private);
|
||||
+ }
|
||||
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
@@ -451,6 +412,10 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
g1 ^= 1;
|
||||
*g1index ^= 1;
|
||||
|
||||
+ /* Now advance the new G1 g_signals to the new lowseq, giving it
|
||||
+ an effective signal count of 0 to start. */
|
||||
+ atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
+
|
||||
/* These values are just observed by signalers, and thus protected by the
|
||||
lock. */
|
||||
unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index dc8c511f1a72517a..c34280c6bc9e80fb 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -239,9 +239,7 @@ __condvar_cleanup_waiting (void *arg)
|
||||
signaled), and a reference count.
|
||||
|
||||
The group reference count is used to maintain the number of waiters that
|
||||
- are using the group's futex. Before a group can change its role, the
|
||||
- reference count must show that no waiters are using the futex anymore; this
|
||||
- prevents ABA issues on the futex word.
|
||||
+ are using the group's futex.
|
||||
|
||||
To represent which intervals in the waiter sequence the groups cover (and
|
||||
thus also which group slot contains G1 or G2), we use a 64b counter to
|
||||
@@ -301,11 +299,12 @@ __condvar_cleanup_waiting (void *arg)
|
||||
last reference.
|
||||
* Reference count used by waiters concurrently with signalers that have
|
||||
acquired the condvar-internal lock.
|
||||
- __g_signals: The number of signals that can still be consumed.
|
||||
+ __g_signals: The number of signals that can still be consumed, relative to
|
||||
+ the current g1_start. (i.e. bits 31 to 1 of __g_signals are bits
|
||||
+ 31 to 1 of g1_start with the signal count added)
|
||||
* Used as a futex word by waiters. Used concurrently by waiters and
|
||||
signalers.
|
||||
- * LSB is true iff this group has been completely signaled (i.e., it is
|
||||
- closed).
|
||||
+ * LSB is currently reserved and 0.
|
||||
__g_size: Waiters remaining in this group (i.e., which have not been
|
||||
signaled yet.
|
||||
* Accessed by signalers and waiters that cancel waiting (both do so only
|
||||
@@ -329,18 +328,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
sufficient because if a waiter can see a sufficiently large value, it could
|
||||
have also consume a signal in the waiters group.
|
||||
|
||||
- Waiters try to grab a signal from __g_signals without holding a reference
|
||||
- count, which can lead to stealing a signal from a more recent group after
|
||||
- their own group was already closed. They cannot always detect whether they
|
||||
- in fact did because they do not know when they stole, but they can
|
||||
- conservatively add a signal back to the group they stole from; if they
|
||||
- did so unnecessarily, all that happens is a spurious wake-up. To make this
|
||||
- even less likely, __g1_start contains the index of the current g2 too,
|
||||
- which allows waiters to check if there aliasing on the group slots; if
|
||||
- there wasn't, they didn't steal from the current G1, which means that the
|
||||
- G1 they stole from must have been already closed and they do not need to
|
||||
- fix anything.
|
||||
-
|
||||
It is essential that the last field in pthread_cond_t is __g_signals[1]:
|
||||
The previous condvar used a pointer-sized field in pthread_cond_t, so a
|
||||
PTHREAD_COND_INITIALIZER from that condvar implementation might only
|
||||
@@ -436,6 +423,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+
|
||||
/* Spin-wait first.
|
||||
Note that spinning first without checking whether a timeout
|
||||
passed might lead to what looks like a spurious wake-up even
|
||||
@@ -447,35 +437,45 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
having to compare against the current time seems to be the right
|
||||
choice from a performance perspective for most use cases. */
|
||||
unsigned int spin = maxspin;
|
||||
- while (signals == 0 && spin > 0)
|
||||
+ while (spin > 0 && ((int)(signals - lowseq) < 2))
|
||||
{
|
||||
/* Check that we are not spinning on a group that's already
|
||||
closed. */
|
||||
- if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
|
||||
- goto done;
|
||||
+ if (seq < (g1_start >> 1))
|
||||
+ break;
|
||||
|
||||
/* TODO Back off. */
|
||||
|
||||
/* Reload signals. See above for MO. */
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
+ g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
spin--;
|
||||
}
|
||||
|
||||
- /* If our group will be closed as indicated by the flag on signals,
|
||||
- don't bother grabbing a signal. */
|
||||
- if (signals & 1)
|
||||
- goto done;
|
||||
-
|
||||
- /* If there is an available signal, don't block. */
|
||||
- if (signals != 0)
|
||||
+ if (seq < (g1_start >> 1))
|
||||
+ {
|
||||
+ /* If the group is closed already,
|
||||
+ then this waiter originally had enough extra signals to
|
||||
+ consume, up until the time its group was closed. */
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is an available signal, don't block.
|
||||
+ If __g1_start has advanced at all, then we must be in G1
|
||||
+ by now, perhaps in the process of switching back to an older
|
||||
+ G2, but in either case we're allowed to consume the available
|
||||
+ signal and should not block anymore. */
|
||||
+ if ((int)(signals - lowseq) >= 2)
|
||||
break;
|
||||
|
||||
/* No signals available after spinning, so prepare to block.
|
||||
We first acquire a group reference and use acquire MO for that so
|
||||
that we synchronize with the dummy read-modify-write in
|
||||
__condvar_quiesce_and_switch_g1 if we read from that. In turn,
|
||||
- in this case this will make us see the closed flag on __g_signals
|
||||
- that designates a concurrent attempt to reuse the group's slot.
|
||||
+ in this case this will make us see the advancement of __g_signals
|
||||
+ to the upcoming new g1_start that occurs with a concurrent
|
||||
+ attempt to reuse the group's slot.
|
||||
We use acquire MO for the __g_signals check to make the
|
||||
__g1_start check work (see spinning above).
|
||||
Note that the group reference acquisition will not mask the
|
||||
@@ -483,15 +483,24 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
an atomic read-modify-write operation and thus extend the release
|
||||
sequence. */
|
||||
atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
- if (((atomic_load_acquire (cond->__data.__g_signals + g) & 1) != 0)
|
||||
- || (seq < (__condvar_load_g1_start_relaxed (cond) >> 1)))
|
||||
+ signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
+ g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+
|
||||
+ if (seq < (g1_start >> 1))
|
||||
{
|
||||
- /* Our group is closed. Wake up any signalers that might be
|
||||
- waiting. */
|
||||
+ /* group is closed already, so don't block */
|
||||
__condvar_dec_grefs (cond, g, private);
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if ((int)(signals - lowseq) >= 2)
|
||||
+ {
|
||||
+ /* a signal showed up or G1/G2 switched after we grabbed the refcount */
|
||||
+ __condvar_dec_grefs (cond, g, private);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
struct _condvar_cleanup_buffer cbuffer;
|
||||
@@ -502,7 +511,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
__pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
|
||||
err = __futex_abstimed_wait_cancelable64 (
|
||||
- cond->__data.__g_signals + g, 0, clockid, abstime, private);
|
||||
+ cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
|
||||
__pthread_cleanup_pop (&buffer, 0);
|
||||
|
||||
@@ -525,6 +534,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
}
|
||||
|
||||
+ if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
|
||||
+ goto done;
|
||||
}
|
||||
/* Try to grab a signal. Use acquire MO so that we see an up-to-date value
|
||||
of __g1_start below (see spinning above for a similar case). In
|
||||
@@ -533,69 +544,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
|
||||
&signals, signals - 2));
|
||||
|
||||
- /* We consumed a signal but we could have consumed from a more recent group
|
||||
- that aliased with ours due to being in the same group slot. If this
|
||||
- might be the case our group must be closed as visible through
|
||||
- __g1_start. */
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- if (seq < (g1_start >> 1))
|
||||
- {
|
||||
- /* We potentially stole a signal from a more recent group but we do not
|
||||
- know which group we really consumed from.
|
||||
- We do not care about groups older than current G1 because they are
|
||||
- closed; we could have stolen from these, but then we just add a
|
||||
- spurious wake-up for the current groups.
|
||||
- We will never steal a signal from current G2 that was really intended
|
||||
- for G2 because G2 never receives signals (until it becomes G1). We
|
||||
- could have stolen a signal from G2 that was conservatively added by a
|
||||
- previous waiter that also thought it stole a signal -- but given that
|
||||
- that signal was added unnecessarily, it's not a problem if we steal
|
||||
- it.
|
||||
- Thus, the remaining case is that we could have stolen from the current
|
||||
- G1, where "current" means the __g1_start value we observed. However,
|
||||
- if the current G1 does not have the same slot index as we do, we did
|
||||
- not steal from it and do not need to undo that. This is the reason
|
||||
- for putting a bit with G2's index into__g1_start as well. */
|
||||
- if (((g1_start & 1) ^ 1) == g)
|
||||
- {
|
||||
- /* We have to conservatively undo our potential mistake of stealing
|
||||
- a signal. We can stop trying to do that when the current G1
|
||||
- changes because other spinning waiters will notice this too and
|
||||
- __condvar_quiesce_and_switch_g1 has checked that there are no
|
||||
- futex waiters anymore before switching G1.
|
||||
- Relaxed MO is fine for the __g1_start load because we need to
|
||||
- merely be able to observe this fact and not have to observe
|
||||
- something else as well.
|
||||
- ??? Would it help to spin for a little while to see whether the
|
||||
- current G1 gets closed? This might be worthwhile if the group is
|
||||
- small or close to being closed. */
|
||||
- unsigned int s = atomic_load_relaxed (cond->__data.__g_signals + g);
|
||||
- while (__condvar_load_g1_start_relaxed (cond) == g1_start)
|
||||
- {
|
||||
- /* Try to add a signal. We don't need to acquire the lock
|
||||
- because at worst we can cause a spurious wake-up. If the
|
||||
- group is in the process of being closed (LSB is true), this
|
||||
- has an effect similar to us adding a signal. */
|
||||
- if (((s & 1) != 0)
|
||||
- || atomic_compare_exchange_weak_relaxed
|
||||
- (cond->__data.__g_signals + g, &s, s + 2))
|
||||
- {
|
||||
- /* If we added a signal, we also need to add a wake-up on
|
||||
- the futex. We also need to do that if we skipped adding
|
||||
- a signal because the group is being closed because
|
||||
- while __condvar_quiesce_and_switch_g1 could have closed
|
||||
- the group, it might stil be waiting for futex waiters to
|
||||
- leave (and one of those waiters might be the one we stole
|
||||
- the signal from, which cause it to block using the
|
||||
- futex). */
|
||||
- futex_wake (cond->__data.__g_signals + g, 1, private);
|
||||
- break;
|
||||
- }
|
||||
- /* TODO Back off. */
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
done:
|
||||
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
39
SOURCES/glibc-RHEL-2419-10.patch
Normal file
39
SOURCES/glibc-RHEL-2419-10.patch
Normal file
@ -0,0 +1,39 @@
|
||||
Partial revert of commit c36fc50781995e6758cae2b6927839d0157f213c
|
||||
to restore the layout of pthread_cond_t and avoid a downstream
|
||||
rpminspect and abidiff (libabigail tooling) spurious warning
|
||||
about internal ABI changes. Without this change all RHEL developers
|
||||
using pthread_cond_t would have to audit and waive the warning.
|
||||
The alternative is to update the supression lists used in abidiff,
|
||||
propagate that to the rpminspect service, and wait for that to
|
||||
complete before doing the update. The more conservative position
|
||||
is the partial revert of the layout change.
|
||||
|
||||
This is a downstream-only change and is not required upstream.
|
||||
|
||||
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
index 5cd33b765d9689eb..5644472323fe5424 100644
|
||||
--- a/sysdeps/nptl/bits/thread-shared-types.h
|
||||
+++ b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
@@ -109,7 +109,8 @@ struct __pthread_cond_s
|
||||
unsigned int __high;
|
||||
} __g1_start32;
|
||||
};
|
||||
- unsigned int __g_size[2] __LOCK_ALIGNMENT;
|
||||
+ unsigned int __glibc_unused___g_refs[2] __LOCK_ALIGNMENT;
|
||||
+ unsigned int __g_size[2];
|
||||
unsigned int __g1_orig_size;
|
||||
unsigned int __wrefs;
|
||||
unsigned int __g_signals[2];
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
|
||||
index 7ea6001784783371..43146e91c9d9579b 100644
|
||||
--- a/sysdeps/nptl/pthread.h
|
||||
+++ b/sysdeps/nptl/pthread.h
|
||||
@@ -152,7 +152,7 @@ enum
|
||||
|
||||
|
||||
/* Conditional variable handling. */
|
||||
-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
|
||||
|
||||
/* Cleanup buffers */
|
133
SOURCES/glibc-RHEL-2419-2.patch
Normal file
133
SOURCES/glibc-RHEL-2419-2.patch
Normal file
@ -0,0 +1,133 @@
|
||||
commit 0cc973160c23bb67f895bc887dd6942d29f8fee3
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 07:55:22 2024 -0500
|
||||
|
||||
nptl: Update comments and indentation for new condvar implementation
|
||||
|
||||
Some comments were wrong after the most recent commit. This fixes that.
|
||||
|
||||
Also fixing indentation where it was using spaces instead of tabs.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index b1565b780d175d3a..b355e38fb57862b1 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -361,8 +361,9 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
into G2 until we atomically make the switch. Waiters existing in G2
|
||||
are not affected.
|
||||
- * Waiters in G1 will be closed out immediately by the advancing of
|
||||
- __g_signals to the next "lowseq" (low 31 bits of the new g1_start),
|
||||
+ * Waiters in G1 have already received a signal and been woken. If they
|
||||
+ haven't woken yet, they will be closed out immediately by the advancing
|
||||
+ of __g_signals to the next "lowseq" (low 31 bits of the new g1_start),
|
||||
which will prevent waiters from blocking using a futex on
|
||||
__g_signals since it provides enough signals for all possible
|
||||
remaining waiters. As a result, they can each consume a signal
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index c34280c6bc9e80fb..7dabcb15d2d818e7 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -250,7 +250,7 @@ __condvar_cleanup_waiting (void *arg)
|
||||
figure out whether they are in a group that has already been completely
|
||||
signaled (i.e., if the current G1 starts at a later position that the
|
||||
waiter's position). Waiters cannot determine whether they are currently
|
||||
- in G2 or G1 -- but they do not have too because all they are interested in
|
||||
+ in G2 or G1 -- but they do not have to because all they are interested in
|
||||
is whether there are available signals, and they always start in G2 (whose
|
||||
group slot they know because of the bit in the waiter sequence. Signalers
|
||||
will simply fill the right group until it is completely signaled and can
|
||||
@@ -413,7 +413,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
}
|
||||
|
||||
/* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe a value of zero written after group
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
store and will see the prior update of __g1_start done while switching
|
||||
groups too. */
|
||||
@@ -423,8 +423,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
/* Spin-wait first.
|
||||
Note that spinning first without checking whether a timeout
|
||||
@@ -448,21 +448,21 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
|
||||
/* Reload signals. See above for MO. */
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+ g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
spin--;
|
||||
}
|
||||
|
||||
- if (seq < (g1_start >> 1))
|
||||
+ if (seq < (g1_start >> 1))
|
||||
{
|
||||
- /* If the group is closed already,
|
||||
+ /* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
consume, up until the time its group was closed. */
|
||||
goto done;
|
||||
- }
|
||||
+ }
|
||||
|
||||
/* If there is an available signal, don't block.
|
||||
- If __g1_start has advanced at all, then we must be in G1
|
||||
+ If __g1_start has advanced at all, then we must be in G1
|
||||
by now, perhaps in the process of switching back to an older
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
@@ -484,22 +484,23 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
sequence. */
|
||||
atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+ g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
- if (seq < (g1_start >> 1))
|
||||
+ if (seq < (g1_start >> 1))
|
||||
{
|
||||
- /* group is closed already, so don't block */
|
||||
+ /* group is closed already, so don't block */
|
||||
__condvar_dec_grefs (cond, g, private);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
{
|
||||
- /* a signal showed up or G1/G2 switched after we grabbed the refcount */
|
||||
+ /* a signal showed up or G1/G2 switched after we grabbed the
|
||||
+ refcount */
|
||||
__condvar_dec_grefs (cond, g, private);
|
||||
break;
|
||||
- }
|
||||
+ }
|
||||
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
@@ -537,10 +538,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
|
||||
goto done;
|
||||
}
|
||||
- /* Try to grab a signal. Use acquire MO so that we see an up-to-date value
|
||||
- of __g1_start below (see spinning above for a similar case). In
|
||||
- particular, if we steal from a more recent group, we will also see a
|
||||
- more recent __g1_start below. */
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
|
||||
&signals, signals - 2));
|
||||
|
67
SOURCES/glibc-RHEL-2419-3.patch
Normal file
67
SOURCES/glibc-RHEL-2419-3.patch
Normal file
@ -0,0 +1,67 @@
|
||||
commit b42cc6af11062c260c7dfa91f1c89891366fed3e
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 07:55:50 2024 -0500
|
||||
|
||||
nptl: Remove unnecessary catch-all-wake in condvar group switch
|
||||
|
||||
This wake is unnecessary. We only switch groups after every sleeper in a group
|
||||
has been woken. Sure, they may take a while to actually wake up and may still
|
||||
hold a reference, but waking them a second time doesn't speed that up. Instead
|
||||
this just makes the code more complicated and may hide problems.
|
||||
|
||||
In particular this safety wake wouldn't even have helped with the bug that was
|
||||
fixed by Barrus' patch: The bug there was that pthread_cond_signal would not
|
||||
switch g1 when it should, so we wouldn't even have entered this code path.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index b355e38fb57862b1..517ad52077829552 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -361,13 +361,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
into G2 until we atomically make the switch. Waiters existing in G2
|
||||
are not affected.
|
||||
- * Waiters in G1 have already received a signal and been woken. If they
|
||||
- haven't woken yet, they will be closed out immediately by the advancing
|
||||
- of __g_signals to the next "lowseq" (low 31 bits of the new g1_start),
|
||||
- which will prevent waiters from blocking using a futex on
|
||||
- __g_signals since it provides enough signals for all possible
|
||||
- remaining waiters. As a result, they can each consume a signal
|
||||
- and they will eventually remove their group reference. */
|
||||
+ * Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
/* Update __g1_start, which finishes closing this group. The value we add
|
||||
will never be negative because old_orig_size can only be zero when we
|
||||
@@ -380,29 +374,6 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
|
||||
unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
|
||||
- /* If any waiters still hold group references (and thus could be blocked),
|
||||
- then wake them all up now and prevent any running ones from blocking.
|
||||
- This is effectively a catch-all for any possible current or future
|
||||
- bugs that can allow the group size to reach 0 before all G1 waiters
|
||||
- have been awakened or at least given signals to consume, or any
|
||||
- other case that can leave blocked (or about to block) older waiters.. */
|
||||
- if ((atomic_fetch_or_release (cond->__data.__g_refs + g1, 0) >> 1) > 0)
|
||||
- {
|
||||
- /* First advance signals to the end of the group (i.e. enough signals
|
||||
- for the entire G1 group) to ensure that waiters which have not
|
||||
- yet blocked in the futex will not block.
|
||||
- Note that in the vast majority of cases, this should never
|
||||
- actually be necessary, since __g_signals will have enough
|
||||
- signals for the remaining g_refs waiters. As an optimization,
|
||||
- we could check this first before proceeding, although that
|
||||
- could still leave the potential for futex lost wakeup bugs
|
||||
- if the signal count was non-zero but the futex wakeup
|
||||
- was somehow lost. */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
-
|
||||
- futex_wake (cond->__data.__g_signals + g1, INT_MAX, private);
|
||||
- }
|
||||
-
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
noticing that __g1_start is larger.
|
107
SOURCES/glibc-RHEL-2419-4.patch
Normal file
107
SOURCES/glibc-RHEL-2419-4.patch
Normal file
@ -0,0 +1,107 @@
|
||||
commit 4f7b051f8ee3feff1b53b27a906f245afaa9cee1
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 07:56:13 2024 -0500
|
||||
|
||||
nptl: Remove unnecessary quadruple check in pthread_cond_wait
|
||||
|
||||
pthread_cond_wait was checking whether it was in a closed group no less than
|
||||
four times. Checking once is enough. Here are the four checks:
|
||||
|
||||
1. While spin-waiting. This was dead code: maxspin is set to 0 and has been
|
||||
for years.
|
||||
2. Before deciding to go to sleep, and before incrementing grefs: I kept this
|
||||
3. After incrementing grefs. There is no reason to think that the group would
|
||||
close while we do an atomic increment. Obviously it could close at any
|
||||
point, but that doesn't mean we have to recheck after every step. This
|
||||
check was equally good as check 2, except it has to do more work.
|
||||
4. When we find ourselves in a group that has a signal. We only get here after
|
||||
we check that we're not in a closed group. There is no need to check again.
|
||||
The check would only have helped in cases where the compare_exchange in the
|
||||
next line would also have failed. Relying on the compare_exchange is fine.
|
||||
|
||||
Removing the duplicate checks clarifies the code.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 7dabcb15d2d818e7..ba9a19bedc2c176f 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -367,7 +367,6 @@ static __always_inline int
|
||||
__pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
clockid_t clockid, const struct __timespec64 *abstime)
|
||||
{
|
||||
- const int maxspin = 0;
|
||||
int err;
|
||||
int result = 0;
|
||||
|
||||
@@ -426,33 +425,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
- /* Spin-wait first.
|
||||
- Note that spinning first without checking whether a timeout
|
||||
- passed might lead to what looks like a spurious wake-up even
|
||||
- though we should return ETIMEDOUT (e.g., if the caller provides
|
||||
- an absolute timeout that is clearly in the past). However,
|
||||
- (1) spurious wake-ups are allowed, (2) it seems unlikely that a
|
||||
- user will (ab)use pthread_cond_wait as a check for whether a
|
||||
- point in time is in the past, and (3) spinning first without
|
||||
- having to compare against the current time seems to be the right
|
||||
- choice from a performance perspective for most use cases. */
|
||||
- unsigned int spin = maxspin;
|
||||
- while (spin > 0 && ((int)(signals - lowseq) < 2))
|
||||
- {
|
||||
- /* Check that we are not spinning on a group that's already
|
||||
- closed. */
|
||||
- if (seq < (g1_start >> 1))
|
||||
- break;
|
||||
-
|
||||
- /* TODO Back off. */
|
||||
-
|
||||
- /* Reload signals. See above for MO. */
|
||||
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
- spin--;
|
||||
- }
|
||||
-
|
||||
if (seq < (g1_start >> 1))
|
||||
{
|
||||
/* If the group is closed already,
|
||||
@@ -483,24 +455,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
an atomic read-modify-write operation and thus extend the release
|
||||
sequence. */
|
||||
atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
-
|
||||
- if (seq < (g1_start >> 1))
|
||||
- {
|
||||
- /* group is closed already, so don't block */
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
- {
|
||||
- /* a signal showed up or G1/G2 switched after we grabbed the
|
||||
- refcount */
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
- break;
|
||||
- }
|
||||
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
@@ -534,9 +488,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* Reload signals. See above for MO. */
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
}
|
||||
-
|
||||
- if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
|
||||
- goto done;
|
||||
}
|
||||
/* Try to grab a signal. See above for MO. (if we do another loop
|
||||
iteration we need to see the correct value of g1_start) */
|
172
SOURCES/glibc-RHEL-2419-5.patch
Normal file
172
SOURCES/glibc-RHEL-2419-5.patch
Normal file
@ -0,0 +1,172 @@
|
||||
commit c36fc50781995e6758cae2b6927839d0157f213c
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 07:56:38 2024 -0500
|
||||
|
||||
nptl: Remove g_refs from condition variables
|
||||
|
||||
This variable used to be needed to wait in group switching until all sleepers
|
||||
have confirmed that they have woken. This is no longer needed. Nothing waits
|
||||
on this variable so there is no need to track how many threads are currently
|
||||
asleep in each group.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
# Conflicts:
|
||||
# nptl/tst-cond22.c (No atomic wide counter refactor)
|
||||
# sysdeps/nptl/bits/thread-shared-types.h (Likewise)
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index ba9a19bedc2c176f..9652dbafe08dfde1 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -144,23 +144,6 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
|
||||
}
|
||||
}
|
||||
|
||||
-/* Wake up any signalers that might be waiting. */
|
||||
-static void
|
||||
-__condvar_dec_grefs (pthread_cond_t *cond, unsigned int g, int private)
|
||||
-{
|
||||
- /* Release MO to synchronize-with the acquire load in
|
||||
- __condvar_quiesce_and_switch_g1. */
|
||||
- if (atomic_fetch_add_release (cond->__data.__g_refs + g, -2) == 3)
|
||||
- {
|
||||
- /* Clear the wake-up request flag before waking up. We do not need more
|
||||
- than relaxed MO and it doesn't matter if we apply this for an aliased
|
||||
- group because we wake all futex waiters right after clearing the
|
||||
- flag. */
|
||||
- atomic_fetch_and_relaxed (cond->__data.__g_refs + g, ~(unsigned int) 1);
|
||||
- futex_wake (cond->__data.__g_refs + g, INT_MAX, private);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* Clean-up for cancellation of waiters waiting for normal signals. We cancel
|
||||
our registration as a waiter, confirm we have woken up, and re-acquire the
|
||||
mutex. */
|
||||
@@ -172,8 +155,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
pthread_cond_t *cond = cbuffer->cond;
|
||||
unsigned g = cbuffer->wseq & 1;
|
||||
|
||||
- __condvar_dec_grefs (cond, g, cbuffer->private);
|
||||
-
|
||||
__condvar_cancel_waiting (cond, cbuffer->wseq >> 1, g, cbuffer->private);
|
||||
/* FIXME With the current cancellation implementation, it is possible that
|
||||
a thread is cancelled after it has returned from a syscall. This could
|
||||
@@ -328,15 +309,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
sufficient because if a waiter can see a sufficiently large value, it could
|
||||
have also consume a signal in the waiters group.
|
||||
|
||||
- It is essential that the last field in pthread_cond_t is __g_signals[1]:
|
||||
- The previous condvar used a pointer-sized field in pthread_cond_t, so a
|
||||
- PTHREAD_COND_INITIALIZER from that condvar implementation might only
|
||||
- initialize 4 bytes to zero instead of the 8 bytes we need (i.e., 44 bytes
|
||||
- in total instead of the 48 we need). __g_signals[1] is not accessed before
|
||||
- the first group switch (G2 starts at index 0), which will set its value to
|
||||
- zero after a harmless fetch-or whose return value is ignored. This
|
||||
- effectively completes initialization.
|
||||
-
|
||||
|
||||
Limitations:
|
||||
* This condvar isn't designed to allow for more than
|
||||
@@ -441,21 +413,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
break;
|
||||
|
||||
- /* No signals available after spinning, so prepare to block.
|
||||
- We first acquire a group reference and use acquire MO for that so
|
||||
- that we synchronize with the dummy read-modify-write in
|
||||
- __condvar_quiesce_and_switch_g1 if we read from that. In turn,
|
||||
- in this case this will make us see the advancement of __g_signals
|
||||
- to the upcoming new g1_start that occurs with a concurrent
|
||||
- attempt to reuse the group's slot.
|
||||
- We use acquire MO for the __g_signals check to make the
|
||||
- __g1_start check work (see spinning above).
|
||||
- Note that the group reference acquisition will not mask the
|
||||
- release MO when decrementing the reference count because we use
|
||||
- an atomic read-modify-write operation and thus extend the release
|
||||
- sequence. */
|
||||
- atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
-
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
struct _condvar_cleanup_buffer cbuffer;
|
||||
@@ -472,18 +429,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
|
||||
if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
{
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
- /* If we timed out, we effectively cancel waiting. Note that
|
||||
- we have decremented __g_refs before cancellation, so that a
|
||||
- deadlock between waiting for quiescence of our group in
|
||||
- __condvar_quiesce_and_switch_g1 and us trying to acquire
|
||||
- the lock during cancellation is not possible. */
|
||||
+ /* If we timed out, we effectively cancel waiting. */
|
||||
__condvar_cancel_waiting (cond, seq, g, private);
|
||||
result = err;
|
||||
goto done;
|
||||
}
|
||||
- else
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
|
||||
/* Reload signals. See above for MO. */
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c
|
||||
index 64f19ea0a55af057..ebeeeaf666070076 100644
|
||||
--- a/nptl/tst-cond22.c
|
||||
+++ b/nptl/tst-cond22.c
|
||||
@@ -106,10 +106,10 @@ do_test (void)
|
||||
status = 1;
|
||||
}
|
||||
|
||||
- printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n",
|
||||
+ printf ("cond = { %llu, %llu, %u/%u, %u/%u, %u, %u }\n",
|
||||
c.__data.__wseq, c.__data.__g1_start,
|
||||
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
|
||||
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
|
||||
+ c.__data.__g_signals[0], c.__data.__g_size[0],
|
||||
+ c.__data.__g_signals[1], c.__data.__g_size[1],
|
||||
c.__data.__g1_orig_size, c.__data.__wrefs);
|
||||
|
||||
if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
|
||||
@@ -149,10 +149,10 @@ do_test (void)
|
||||
status = 1;
|
||||
}
|
||||
|
||||
- printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n",
|
||||
+ printf ("cond = { %llu, %llu, %u/%u, %u/%u, %u, %u }\n",
|
||||
c.__data.__wseq, c.__data.__g1_start,
|
||||
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
|
||||
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
|
||||
+ c.__data.__g_signals[0], c.__data.__g_size[0],
|
||||
+ c.__data.__g_signals[1], c.__data.__g_size[1],
|
||||
c.__data.__g1_orig_size, c.__data.__wrefs);
|
||||
|
||||
return status;
|
||||
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
index 44bf1e358dbdaaff..5cd33b765d9689eb 100644
|
||||
--- a/sysdeps/nptl/bits/thread-shared-types.h
|
||||
+++ b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
@@ -109,8 +109,7 @@ struct __pthread_cond_s
|
||||
unsigned int __high;
|
||||
} __g1_start32;
|
||||
};
|
||||
- unsigned int __g_refs[2] __LOCK_ALIGNMENT;
|
||||
- unsigned int __g_size[2];
|
||||
+ unsigned int __g_size[2] __LOCK_ALIGNMENT;
|
||||
unsigned int __g1_orig_size;
|
||||
unsigned int __wrefs;
|
||||
unsigned int __g_signals[2];
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
|
||||
index 43146e91c9d9579b..7ea6001784783371 100644
|
||||
--- a/sysdeps/nptl/pthread.h
|
||||
+++ b/sysdeps/nptl/pthread.h
|
||||
@@ -152,7 +152,7 @@ enum
|
||||
|
||||
|
||||
/* Conditional variable handling. */
|
||||
-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
|
||||
|
||||
/* Cleanup buffers */
|
91
SOURCES/glibc-RHEL-2419-6.patch
Normal file
91
SOURCES/glibc-RHEL-2419-6.patch
Normal file
@ -0,0 +1,91 @@
|
||||
commit 929a4764ac90382616b6a21f099192b2475da674
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 08:03:44 2024 -0500
|
||||
|
||||
nptl: Use a single loop in pthread_cond_wait instaed of a nested loop
|
||||
|
||||
The loop was a little more complicated than necessary. There was only one
|
||||
break statement out of the inner loop, and the outer loop was nearly empty.
|
||||
So just remove the outer loop, moving its code to the one break statement in
|
||||
the inner loop. This allows us to replace all gotos with break statements.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 9652dbafe08dfde1..4886056d136db138 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -383,17 +383,15 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
return err;
|
||||
}
|
||||
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
-
|
||||
- do
|
||||
- {
|
||||
+
|
||||
while (1)
|
||||
{
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
@@ -402,7 +400,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
consume, up until the time its group was closed. */
|
||||
- goto done;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* If there is an available signal, don't block.
|
||||
@@ -411,7 +409,16 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
- break;
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
+ &signals, signals - 2))
|
||||
+ break;
|
||||
+ else
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
@@ -432,19 +439,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* If we timed out, we effectively cancel waiting. */
|
||||
__condvar_cancel_waiting (cond, seq, g, private);
|
||||
result = err;
|
||||
- goto done;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- /* Reload signals. See above for MO. */
|
||||
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
}
|
||||
- }
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2));
|
||||
-
|
||||
- done:
|
||||
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
||||
to allow for execution of pthread_cond_destroy while having acquired the
|
138
SOURCES/glibc-RHEL-2419-7.patch
Normal file
138
SOURCES/glibc-RHEL-2419-7.patch
Normal file
@ -0,0 +1,138 @@
|
||||
commit ee6c14ed59d480720721aaacc5fb03213dc153da
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 08:04:10 2024 -0500
|
||||
|
||||
nptl: Fix indentation
|
||||
|
||||
In my previous change I turned a nested loop into a simple loop. I'm doing
|
||||
the resulting indentation changes in a separate commit to make the diff on
|
||||
the previous commit easier to review.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 4886056d136db138..6c130436b016977a 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -384,65 +384,65 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
}
|
||||
|
||||
|
||||
- while (1)
|
||||
- {
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
-
|
||||
- if (seq < (g1_start >> 1))
|
||||
- {
|
||||
- /* If the group is closed already,
|
||||
- then this waiter originally had enough extra signals to
|
||||
- consume, up until the time its group was closed. */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* If there is an available signal, don't block.
|
||||
- If __g1_start has advanced at all, then we must be in G1
|
||||
- by now, perhaps in the process of switching back to an older
|
||||
- G2, but in either case we're allowed to consume the available
|
||||
- signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
- {
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- if (atomic_compare_exchange_weak_acquire (
|
||||
- cond->__data.__g_signals + g,
|
||||
+ while (1)
|
||||
+ {
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+
|
||||
+ if (seq < (g1_start >> 1))
|
||||
+ {
|
||||
+ /* If the group is closed already,
|
||||
+ then this waiter originally had enough extra signals to
|
||||
+ consume, up until the time its group was closed. */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is an available signal, don't block.
|
||||
+ If __g1_start has advanced at all, then we must be in G1
|
||||
+ by now, perhaps in the process of switching back to an older
|
||||
+ G2, but in either case we're allowed to consume the available
|
||||
+ signal and should not block anymore. */
|
||||
+ if ((int)(signals - lowseq) >= 2)
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
&signals, signals - 2))
|
||||
- break;
|
||||
- else
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- // Now block.
|
||||
- struct _pthread_cleanup_buffer buffer;
|
||||
- struct _condvar_cleanup_buffer cbuffer;
|
||||
- cbuffer.wseq = wseq;
|
||||
- cbuffer.cond = cond;
|
||||
- cbuffer.mutex = mutex;
|
||||
- cbuffer.private = private;
|
||||
- __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
-
|
||||
- err = __futex_abstimed_wait_cancelable64 (
|
||||
- cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
-
|
||||
- __pthread_cleanup_pop (&buffer, 0);
|
||||
-
|
||||
- if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
- {
|
||||
- /* If we timed out, we effectively cancel waiting. */
|
||||
- __condvar_cancel_waiting (cond, seq, g, private);
|
||||
- result = err;
|
||||
break;
|
||||
- }
|
||||
+ else
|
||||
+ continue;
|
||||
}
|
||||
|
||||
+ // Now block.
|
||||
+ struct _pthread_cleanup_buffer buffer;
|
||||
+ struct _condvar_cleanup_buffer cbuffer;
|
||||
+ cbuffer.wseq = wseq;
|
||||
+ cbuffer.cond = cond;
|
||||
+ cbuffer.mutex = mutex;
|
||||
+ cbuffer.private = private;
|
||||
+ __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
+
|
||||
+ err = __futex_abstimed_wait_cancelable64 (
|
||||
+ cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
+
|
||||
+ __pthread_cleanup_pop (&buffer, 0);
|
||||
+
|
||||
+ if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
+ {
|
||||
+ /* If we timed out, we effectively cancel waiting. */
|
||||
+ __condvar_cancel_waiting (cond, seq, g, private);
|
||||
+ result = err;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
||||
to allow for execution of pthread_cond_destroy while having acquired the
|
||||
mutex. */
|
147
SOURCES/glibc-RHEL-2419-8.patch
Normal file
147
SOURCES/glibc-RHEL-2419-8.patch
Normal file
@ -0,0 +1,147 @@
|
||||
commit 4b79e27a5073c02f6bff9aa8f4791230a0ab1867
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 08:04:54 2024 -0500
|
||||
|
||||
nptl: rename __condvar_quiesce_and_switch_g1
|
||||
|
||||
This function no longer waits for threads to leave g1, so rename it to
|
||||
__condvar_switch_g1
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
|
||||
index f1275b2f15817788..3dff819952718892 100644
|
||||
--- a/nptl/pthread_cond_broadcast.c
|
||||
+++ b/nptl/pthread_cond_broadcast.c
|
||||
@@ -61,7 +61,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
cond->__data.__g_size[g1] << 1);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
|
||||
- /* We need to wake G1 waiters before we quiesce G1 below. */
|
||||
+ /* We need to wake G1 waiters before we switch G1 below. */
|
||||
/* TODO Only set it if there are indeed futex waiters. We could
|
||||
also try to move this out of the critical section in cases when
|
||||
G2 is empty (and we don't need to quiesce). */
|
||||
@@ -70,7 +70,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
|
||||
/* G1 is complete. Step (2) is next unless there are no waiters in G2, in
|
||||
which case we can stop. */
|
||||
- if (__condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ if (__condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 517ad52077829552..7b2b1e4605f163e7 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -329,16 +329,15 @@ __condvar_get_private (int flags)
|
||||
return FUTEX_SHARED;
|
||||
}
|
||||
|
||||
-/* This closes G1 (whose index is in G1INDEX), waits for all futex waiters to
|
||||
- leave G1, converts G1 into a fresh G2, and then switches group roles so that
|
||||
- the former G2 becomes the new G1 ending at the current __wseq value when we
|
||||
- eventually make the switch (WSEQ is just an observation of __wseq by the
|
||||
- signaler).
|
||||
+/* This closes G1 (whose index is in G1INDEX), converts G1 into a fresh G2,
|
||||
+ and then switches group roles so that the former G2 becomes the new G1
|
||||
+ ending at the current __wseq value when we eventually make the switch
|
||||
+ (WSEQ is just an observation of __wseq by the signaler).
|
||||
If G2 is empty, it will not switch groups because then it would create an
|
||||
empty G1 which would require switching groups again on the next signal.
|
||||
Returns false iff groups were not switched because G2 was empty. */
|
||||
static bool __attribute__ ((unused))
|
||||
-__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+__condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
unsigned int *g1index, int private)
|
||||
{
|
||||
unsigned int g1 = *g1index;
|
||||
@@ -354,8 +353,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+ cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
return false;
|
||||
|
||||
- /* Now try to close and quiesce G1. We have to consider the following kinds
|
||||
- of waiters:
|
||||
+ /* We have to consider the following kinds of waiters:
|
||||
* Waiters from less recent groups than G1 are not affected because
|
||||
nothing will change for them apart from __g1_start getting larger.
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
@@ -363,12 +361,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
are not affected.
|
||||
* Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
- /* Update __g1_start, which finishes closing this group. The value we add
|
||||
- will never be negative because old_orig_size can only be zero when we
|
||||
- switch groups the first time after a condvar was initialized, in which
|
||||
- case G1 will be at index 1 and we will add a value of 1.
|
||||
- Relaxed MO is fine because the change comes with no additional
|
||||
- constraints that others would have to observe. */
|
||||
+ /* Update __g1_start, which closes this group. The value we add will never
|
||||
+ be negative because old_orig_size can only be zero when we switch groups
|
||||
+ the first time after a condvar was initialized, in which case G1 will be
|
||||
+ at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
+ change comes with no additional constraints that others would have to
|
||||
+ observe. */
|
||||
__condvar_add_g1_start_relaxed (cond,
|
||||
(old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
|
||||
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
|
||||
index 171193b13e203290..4f7639e386fc207a 100644
|
||||
--- a/nptl/pthread_cond_signal.c
|
||||
+++ b/nptl/pthread_cond_signal.c
|
||||
@@ -70,18 +70,17 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
bool do_futex_wake = false;
|
||||
|
||||
/* If G1 is still receiving signals, we put the signal there. If not, we
|
||||
- check if G2 has waiters, and if so, quiesce and switch G1 to the former
|
||||
- G2; if this results in a new G1 with waiters (G2 might have cancellations
|
||||
- already, see __condvar_quiesce_and_switch_g1), we put the signal in the
|
||||
- new G1. */
|
||||
+ check if G2 has waiters, and if so, switch G1 to the former G2; if this
|
||||
+ results in a new G1 with waiters (G2 might have cancellations already,
|
||||
+ see __condvar_switch_g1), we put the signal in the new G1. */
|
||||
if ((cond->__data.__g_size[g1] != 0)
|
||||
- || __condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ || __condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Add a signal. Relaxed MO is fine because signaling does not need to
|
||||
- establish a happens-before relation (see above). We do not mask the
|
||||
- release-MO store when initializing a group in
|
||||
- __condvar_quiesce_and_switch_g1 because we use an atomic
|
||||
- read-modify-write and thus extend that store's release sequence. */
|
||||
+ establish a happens-before relation (see above). We do not mask the
|
||||
+ release-MO store when initializing a group in __condvar_switch_g1
|
||||
+ because we use an atomic read-modify-write and thus extend that
|
||||
+ store's release sequence. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
cond->__data.__g_size[g1]--;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 6c130436b016977a..173bd134164eed44 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -355,8 +355,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
because we do not need to establish any happens-before relation with
|
||||
signalers (see __pthread_cond_signal); modification order alone
|
||||
establishes a total order of waiters/signals. We do need acquire MO
|
||||
- to synchronize with group reinitialization in
|
||||
- __condvar_quiesce_and_switch_g1. */
|
||||
+ to synchronize with group reinitialization in __condvar_switch_g1. */
|
||||
uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2);
|
||||
/* Find our group's index. We always go into what was G2 when we acquired
|
||||
our position. */
|
||||
@@ -388,9 +387,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
{
|
||||
/* Now wait until a signal is available in our group or it is closed.
|
||||
Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
+ switching in __condvar_switch_g1, we synchronize with that store and
|
||||
+ will see the prior update of __g1_start done while switching groups
|
||||
+ too. */
|
||||
unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
179
SOURCES/glibc-RHEL-2419-9.patch
Normal file
179
SOURCES/glibc-RHEL-2419-9.patch
Normal file
@ -0,0 +1,179 @@
|
||||
commit 91bb902f58264a2fd50fbce8f39a9a290dd23706
|
||||
Author: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Wed Dec 4 08:05:40 2024 -0500
|
||||
|
||||
nptl: Use all of g1_start and g_signals
|
||||
|
||||
The LSB of g_signals was unused. The LSB of g1_start was used to indicate
|
||||
which group is G2. This was used to always go to sleep in pthread_cond_wait
|
||||
if a waiter is in G2. A comment earlier in the file says that this is not
|
||||
correct to do:
|
||||
|
||||
"Waiters cannot determine whether they are currently in G2 or G1 -- but they
|
||||
do not have to because all they are interested in is whether there are
|
||||
available signals"
|
||||
|
||||
I either would have had to update the comment, or get rid of the check. I
|
||||
chose to get rid of the check. In fact I don't quite know why it was there.
|
||||
There will never be available signals for group G2, so we didn't need the
|
||||
special case. Even if there were, this would just be a spurious wake. This
|
||||
might have caught some cases where the count has wrapped around, but it
|
||||
wouldn't reliably do that, (and even if it did, why would you want to force a
|
||||
sleep in that case?) and we don't support that many concurrent waiters
|
||||
anyway. Getting rid of it allows us to use one more bit, making us more
|
||||
robust to wraparound.
|
||||
|
||||
Signed-off-by: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
|
||||
index 3dff819952718892..6fd6cfe9d002c5d5 100644
|
||||
--- a/nptl/pthread_cond_broadcast.c
|
||||
+++ b/nptl/pthread_cond_broadcast.c
|
||||
@@ -58,7 +58,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
{
|
||||
/* Add as many signals as the remaining size of the group. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
|
||||
/* We need to wake G1 waiters before we switch G1 below. */
|
||||
@@ -74,7 +74,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
{
|
||||
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 7b2b1e4605f163e7..485aca4076a372d7 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -348,9 +348,9 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
behavior.
|
||||
Note that this works correctly for a zero-initialized condvar too. */
|
||||
unsigned int old_orig_size = __condvar_get_orig_size (cond);
|
||||
- uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
- if (((unsigned) (wseq - old_g1_start - old_orig_size)
|
||||
- + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
+ uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ uint64_t new_g1_start = old_g1_start + old_orig_size;
|
||||
+ if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
return false;
|
||||
|
||||
/* We have to consider the following kinds of waiters:
|
||||
@@ -361,16 +361,10 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
are not affected.
|
||||
* Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
- /* Update __g1_start, which closes this group. The value we add will never
|
||||
- be negative because old_orig_size can only be zero when we switch groups
|
||||
- the first time after a condvar was initialized, in which case G1 will be
|
||||
- at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
- change comes with no additional constraints that others would have to
|
||||
- observe. */
|
||||
- __condvar_add_g1_start_relaxed (cond,
|
||||
- (old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
-
|
||||
- unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
+ /* Update __g1_start, which closes this group. Relaxed MO is fine because
|
||||
+ the change comes with no additional constraints that others would have
|
||||
+ to observe. */
|
||||
+ __condvar_add_g1_start_relaxed (cond, old_orig_size);
|
||||
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
@@ -382,13 +376,13 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
g1 ^= 1;
|
||||
*g1index ^= 1;
|
||||
|
||||
- /* Now advance the new G1 g_signals to the new lowseq, giving it
|
||||
+ /* Now advance the new G1 g_signals to the new g1_start, giving it
|
||||
an effective signal count of 0 to start. */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
+ atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start);
|
||||
|
||||
/* These values are just observed by signalers, and thus protected by the
|
||||
lock. */
|
||||
- unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
|
||||
+ unsigned int orig_size = wseq - new_g1_start;
|
||||
__condvar_set_orig_size (cond, orig_size);
|
||||
/* Use and addition to not loose track of cancellations in what was
|
||||
previously G2. */
|
||||
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
|
||||
index 4f7639e386fc207a..9a5bac92fe8fc246 100644
|
||||
--- a/nptl/pthread_cond_signal.c
|
||||
+++ b/nptl/pthread_cond_signal.c
|
||||
@@ -81,7 +81,7 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
release-MO store when initializing a group in __condvar_switch_g1
|
||||
because we use an atomic read-modify-write and thus extend that
|
||||
store's release sequence. */
|
||||
- atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
+ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1);
|
||||
cond->__data.__g_size[g1]--;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 173bd134164eed44..944b241ec26b9b32 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -85,7 +85,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
|
||||
not hold a reference on the group. */
|
||||
__condvar_acquire_lock (cond, private);
|
||||
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
if (g1_start > seq)
|
||||
{
|
||||
/* Our group is closed, so someone provided enough signals for it.
|
||||
@@ -260,7 +260,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Waiters fetch-add while having acquire the mutex associated with the
|
||||
condvar. Signalers load it and fetch-xor it concurrently.
|
||||
__g1_start: Starting position of G1 (inclusive)
|
||||
- * LSB is index of current G2.
|
||||
* Modified by signalers while having acquired the condvar-internal lock
|
||||
and observed concurrently by waiters.
|
||||
__g1_orig_size: Initial size of G1
|
||||
@@ -281,11 +280,9 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Reference count used by waiters concurrently with signalers that have
|
||||
acquired the condvar-internal lock.
|
||||
__g_signals: The number of signals that can still be consumed, relative to
|
||||
- the current g1_start. (i.e. bits 31 to 1 of __g_signals are bits
|
||||
- 31 to 1 of g1_start with the signal count added)
|
||||
+ the current g1_start. (i.e. g1_start with the signal count added)
|
||||
* Used as a futex word by waiters. Used concurrently by waiters and
|
||||
signalers.
|
||||
- * LSB is currently reserved and 0.
|
||||
__g_size: Waiters remaining in this group (i.e., which have not been
|
||||
signaled yet.
|
||||
* Accessed by signalers and waiters that cancel waiting (both do so only
|
||||
@@ -392,9 +389,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
too. */
|
||||
unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
- if (seq < (g1_start >> 1))
|
||||
+ if (seq < g1_start)
|
||||
{
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
@@ -407,13 +403,13 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
by now, perhaps in the process of switching back to an older
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
+ if ((int)(signals - (unsigned int)g1_start) > 0)
|
||||
{
|
||||
/* Try to grab a signal. See above for MO. (if we do another loop
|
||||
iteration we need to see the correct value of g1_start) */
|
||||
if (atomic_compare_exchange_weak_acquire (
|
||||
cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2))
|
||||
+ &signals, signals - 1))
|
||||
break;
|
||||
else
|
||||
continue;
|
315
SOURCES/glibc-RHEL-24740-1.patch
Normal file
315
SOURCES/glibc-RHEL-24740-1.patch
Normal file
@ -0,0 +1,315 @@
|
||||
commit 3367d8e180848030d1646f088759f02b8dfe0d6f
|
||||
Author: Amrita H S <amritahs@linux.vnet.ibm.com>
|
||||
Date: Wed Dec 6 11:43:11 2023 -0500
|
||||
|
||||
powerpc: Optimized strcmp for power10
|
||||
|
||||
This patch is based on __strcmp_power9 and __strlen_power10.
|
||||
|
||||
Improvements from __strcmp_power9:
|
||||
|
||||
1. Uses new POWER10 instructions
|
||||
- This code uses lxvp to decrease contention on load
|
||||
by loading 32 bytes per instruction.
|
||||
|
||||
2. Performance implication
|
||||
- This version has around 30% better performance on average.
|
||||
- Performance regression is seen for a specific combination
|
||||
of sizes and alignments. Some of them is observed without
|
||||
changes also, while rest may be induced by the patch.
|
||||
|
||||
Signed-off-by: Amrita H S <amritahs@linux.vnet.ibm.com>
|
||||
Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/power10/strcmp.S b/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..a3c1adad539978e0
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
|
||||
@@ -0,0 +1,204 @@
|
||||
+/* Optimized strcmp implementation for PowerPC64/POWER10.
|
||||
+ Copyright (C) 2021-2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+#include <sysdep.h>
|
||||
+
|
||||
+#ifndef STRCMP
|
||||
+# define STRCMP strcmp
|
||||
+#endif
|
||||
+
|
||||
+/* Implements the function
|
||||
+ int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]). */
|
||||
+
|
||||
+/* TODO: Change this to actual instructions when minimum binutils is upgraded
|
||||
+ to 2.27. Macros are defined below for these newer instructions in order
|
||||
+ to maintain compatibility. */
|
||||
+
|
||||
+#define LXVP(xtp,dq,ra) \
|
||||
+ .long(((6)<<(32-6)) \
|
||||
+ | ((((xtp)-32)>>1)<<(32-10)) \
|
||||
+ | ((1)<<(32-11)) \
|
||||
+ | ((ra)<<(32-16)) \
|
||||
+ | dq)
|
||||
+
|
||||
+#define COMPARE_16(vreg1,vreg2,offset) \
|
||||
+ lxv vreg1+32,offset(r3); \
|
||||
+ lxv vreg2+32,offset(r4); \
|
||||
+ vcmpnezb. v7,vreg1,vreg2; \
|
||||
+ bne cr6,L(different); \
|
||||
+
|
||||
+#define COMPARE_32(vreg1,vreg2,offset,label1,label2) \
|
||||
+ LXVP(vreg1+32,offset,r3); \
|
||||
+ LXVP(vreg2+32,offset,r4); \
|
||||
+ vcmpnezb. v7,vreg1+1,vreg2+1; \
|
||||
+ bne cr6,L(label1); \
|
||||
+ vcmpnezb. v7,vreg1,vreg2; \
|
||||
+ bne cr6,L(label2); \
|
||||
+
|
||||
+#define TAIL(vreg1,vreg2) \
|
||||
+ vctzlsbb r6,v7; \
|
||||
+ vextubrx r5,r6,vreg1; \
|
||||
+ vextubrx r4,r6,vreg2; \
|
||||
+ subf r3,r4,r5; \
|
||||
+ blr; \
|
||||
+
|
||||
+#define CHECK_N_BYTES(reg1,reg2,len_reg) \
|
||||
+ sldi r0,len_reg,56; \
|
||||
+ lxvl 32+v4,reg1,r0; \
|
||||
+ lxvl 32+v5,reg2,r0; \
|
||||
+ add reg1,reg1,len_reg; \
|
||||
+ add reg2,reg2,len_reg; \
|
||||
+ vcmpnezb. v7,v4,v5; \
|
||||
+ vctzlsbb r6,v7; \
|
||||
+ cmpld cr7,r6,len_reg; \
|
||||
+ blt cr7,L(different); \
|
||||
+
|
||||
+ /* TODO: change this to .machine power10 when the minimum required
|
||||
+ binutils allows it. */
|
||||
+
|
||||
+ .machine power9
|
||||
+ENTRY_TOCLESS (STRCMP, 4)
|
||||
+ li r11,16
|
||||
+ /* eq bit of cr1 used as swap status flag to indicate if
|
||||
+ source pointers were swapped. */
|
||||
+ crclr 4*cr1+eq
|
||||
+ vspltisb v19,-1
|
||||
+ andi. r7,r3,15
|
||||
+ sub r7,r11,r7 /* r7(nalign1) = 16 - (str1 & 15). */
|
||||
+ andi. r9,r4,15
|
||||
+ sub r5,r11,r9 /* r5(nalign2) = 16 - (str2 & 15). */
|
||||
+ cmpld cr7,r7,r5
|
||||
+ beq cr7,L(same_aligned)
|
||||
+ blt cr7,L(nalign1_min)
|
||||
+ /* Swap r3 and r4, and r7 and r5 such that r3 and r7 hold the
|
||||
+ pointer which is closer to the next 16B boundary so that only
|
||||
+ one CHECK_N_BYTES is needed before entering the loop below. */
|
||||
+ mr r8,r4
|
||||
+ mr r4,r3
|
||||
+ mr r3,r8
|
||||
+ mr r12,r7
|
||||
+ mr r7,r5
|
||||
+ mr r5,r12
|
||||
+ crset 4*cr1+eq /* Set bit on swapping source pointers. */
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(nalign1_min):
|
||||
+ CHECK_N_BYTES(r3,r4,r7)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(s1_aligned):
|
||||
+ /* r9 and r5 is number of bytes to be read after and before
|
||||
+ page boundary correspondingly. */
|
||||
+ sub r5,r5,r7
|
||||
+ subfic r9,r5,16
|
||||
+ /* Now let r7 hold the count of quadwords which can be
|
||||
+ checked without crossing a page boundary. quadword offset is
|
||||
+ (str2>>4)&0xFF. */
|
||||
+ rlwinm r7,r4,28,0xFF
|
||||
+ /* Below check is required only for first iteration. For second
|
||||
+ iteration and beyond, the new loop counter is always 255. */
|
||||
+ cmpldi r7,255
|
||||
+ beq L(L3)
|
||||
+ /* Get the initial loop count by 255-((str2>>4)&0xFF). */
|
||||
+ subfic r11,r7,255
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(L1):
|
||||
+ mtctr r11
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(L2):
|
||||
+ COMPARE_16(v4,v5,0) /* Load 16B blocks using lxv. */
|
||||
+ addi r3,r3,16
|
||||
+ addi r4,r4,16
|
||||
+ bdnz L(L2)
|
||||
+ /* Cross the page boundary of s2, carefully. */
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(L3):
|
||||
+ CHECK_N_BYTES(r3,r4,r5)
|
||||
+ CHECK_N_BYTES(r3,r4,r9)
|
||||
+ li r11,255 /* Load the new loop counter. */
|
||||
+ b L(L1)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(same_aligned):
|
||||
+ CHECK_N_BYTES(r3,r4,r7)
|
||||
+ /* Align s1 to 32B and adjust s2 address.
|
||||
+ Use lxvp only if both s1 and s2 are 32B aligned. */
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ COMPARE_16(v4,v5,32)
|
||||
+ COMPARE_16(v4,v5,48)
|
||||
+ addi r3,r3,64
|
||||
+ addi r4,r4,64
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+
|
||||
+ clrldi r6,r3,59
|
||||
+ subfic r5,r6,32
|
||||
+ add r3,r3,r5
|
||||
+ add r4,r4,r5
|
||||
+ andi. r5,r4,0x1F
|
||||
+ beq cr0,L(32B_aligned_loop)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(16B_aligned_loop):
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ COMPARE_16(v4,v5,32)
|
||||
+ COMPARE_16(v4,v5,48)
|
||||
+ addi r3,r3,64
|
||||
+ addi r4,r4,64
|
||||
+ b L(16B_aligned_loop)
|
||||
+
|
||||
+ /* Calculate and return the difference. */
|
||||
+L(different):
|
||||
+ vctzlsbb r6,v7
|
||||
+ vextubrx r5,r6,v4
|
||||
+ vextubrx r4,r6,v5
|
||||
+ bt 4*cr1+eq,L(swapped)
|
||||
+ subf r3,r4,r5
|
||||
+ blr
|
||||
+
|
||||
+ /* If src pointers were swapped, then swap the
|
||||
+ indices and calculate the return value. */
|
||||
+L(swapped):
|
||||
+ subf r3,r5,r4
|
||||
+ blr
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(32B_aligned_loop):
|
||||
+ COMPARE_32(v14,v16,0,tail1,tail2)
|
||||
+ COMPARE_32(v18,v20,32,tail3,tail4)
|
||||
+ COMPARE_32(v22,v24,64,tail5,tail6)
|
||||
+ COMPARE_32(v26,v28,96,tail7,tail8)
|
||||
+ addi r3,r3,128
|
||||
+ addi r4,r4,128
|
||||
+ b L(32B_aligned_loop)
|
||||
+
|
||||
+L(tail1): TAIL(v15,v17)
|
||||
+L(tail2): TAIL(v14,v16)
|
||||
+L(tail3): TAIL(v19,v21)
|
||||
+L(tail4): TAIL(v18,v20)
|
||||
+L(tail5): TAIL(v23,v25)
|
||||
+L(tail6): TAIL(v22,v24)
|
||||
+L(tail7): TAIL(v27,v29)
|
||||
+L(tail8): TAIL(v26,v28)
|
||||
+
|
||||
+END (STRCMP)
|
||||
+libc_hidden_builtin_def (strcmp)
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
index 0ee7ce39d6470d80..91ed88a9c716800d 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
@@ -33,7 +33,8 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \
|
||||
ifneq (,$(filter %le,$(config-machine)))
|
||||
sysdep_routines += memcmp-power10 memcpy-power10 memmove-power10 memset-power10 \
|
||||
rawmemchr-power9 rawmemchr-power10 \
|
||||
- strcmp-power9 strncmp-power9 strcpy-power9 stpcpy-power9 \
|
||||
+ strcmp-power9 strcmp-power10 strncmp-power9 \
|
||||
+ strcpy-power9 stpcpy-power9 \
|
||||
strlen-power9 strncpy-power9 stpncpy-power9 strlen-power10
|
||||
endif
|
||||
CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
index 2c84d287ee76a7ea..caec2047ab10d209 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
@@ -416,6 +416,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||
/* Support sysdeps/powerpc/powerpc64/multiarch/strcmp.c. */
|
||||
IFUNC_IMPL (i, name, strcmp,
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
+ IFUNC_IMPL_ADD (array, i, strcmp,
|
||||
+ (hwcap2 & PPC_FEATURE2_ARCH_3_1)
|
||||
+ && (hwcap & PPC_FEATURE_HAS_VSX),
|
||||
+ __strcmp_power10)
|
||||
IFUNC_IMPL_ADD (array, i, strcmp,
|
||||
hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..c80067ce3305de81
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* Optimized strcmp implementation for POWER10/PPC64.
|
||||
+ Copyright (C) 2021-2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
|
||||
+#define STRCMP __strcmp_power10
|
||||
+
|
||||
+#undef libc_hidden_builtin_def
|
||||
+#define libc_hidden_builtin_def(name)
|
||||
+
|
||||
+#include <sysdeps/powerpc/powerpc64/le/power10/strcmp.S>
|
||||
+#endif /* __LITTLE_ENDIAN__ && IS_IN (libc) */
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||
index 8132682a992edb7a..4e77005117525edb 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
|
||||
@@ -29,12 +29,16 @@ extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
|
||||
extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
extern __typeof (strcmp) __strcmp_power9 attribute_hidden;
|
||||
+extern __typeof (strcmp) __strcmp_power10 attribute_hidden;
|
||||
# endif
|
||||
|
||||
# undef strcmp
|
||||
|
||||
libc_ifunc_redirected (__redirect_strcmp, strcmp,
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
+ (hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||
+ ? __strcmp_power10 :
|
||||
(hwcap2 & PPC_FEATURE2_ARCH_3_00
|
||||
&& hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||
? __strcmp_power9 :
|
435
SOURCES/glibc-RHEL-24740-2.patch
Normal file
435
SOURCES/glibc-RHEL-24740-2.patch
Normal file
@ -0,0 +1,435 @@
|
||||
commit b9182c793caa05df5d697427c0538936e6396d4b
|
||||
Author: MAHESH BODAPATI <bmahi496@linux.ibm.com>
|
||||
Date: Tue Dec 12 08:52:45 2023 -0600
|
||||
|
||||
powerpc : Add optimized memchr for POWER10
|
||||
|
||||
Optimized memchr for POWER10 based on existing rawmemchr and strlen.
|
||||
Reordering instructions and loop unrolling helped in getting better performance.
|
||||
Reviewed-by: Rajalakshmi Srinivasaraghavan <rajis@linux.ibm.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/power10/memchr.S b/sysdeps/powerpc/powerpc64/le/power10/memchr.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..faf293f3447e6fc6
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/power10/memchr.S
|
||||
@@ -0,0 +1,315 @@
|
||||
+/* Optimized memchr implementation for POWER10 LE.
|
||||
+ Copyright (C) 2021-2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <sysdep.h>
|
||||
+
|
||||
+# ifndef MEMCHR
|
||||
+# define MEMCHR __memchr
|
||||
+# endif
|
||||
+# define M_VREG_ZERO v20
|
||||
+# define M_OFF_START_LOOP 256
|
||||
+# define MEMCHR_SUBTRACT_VECTORS \
|
||||
+ vsububm v4,v4,v18; \
|
||||
+ vsububm v5,v5,v18; \
|
||||
+ vsububm v6,v6,v18; \
|
||||
+ vsububm v7,v7,v18;
|
||||
+# define M_TAIL(vreg,increment) \
|
||||
+ vctzlsbb r4,vreg; \
|
||||
+ cmpld r5,r4; \
|
||||
+ ble L(null); \
|
||||
+ addi r4,r4,increment; \
|
||||
+ add r3,r6,r4; \
|
||||
+ blr
|
||||
+
|
||||
+/* TODO: Replace macros by the actual instructions when minimum binutils becomes
|
||||
+ >= 2.35. This is used to keep compatibility with older versions. */
|
||||
+#define M_VEXTRACTBM(rt,vrb) \
|
||||
+ .long(((4)<<(32-6)) \
|
||||
+ | ((rt)<<(32-11)) \
|
||||
+ | ((8)<<(32-16)) \
|
||||
+ | ((vrb)<<(32-21)) \
|
||||
+ | 1602)
|
||||
+
|
||||
+#define M_LXVP(xtp,dq,ra) \
|
||||
+ .long(((6)<<(32-6)) \
|
||||
+ | ((((xtp)-32)>>1)<<(32-10)) \
|
||||
+ | ((1)<<(32-11)) \
|
||||
+ | ((ra)<<(32-16)) \
|
||||
+ | dq)
|
||||
+
|
||||
+#define CHECK16B(vreg,offset,addr,label) \
|
||||
+ lxv vreg+32,offset(addr); \
|
||||
+ vcmpequb. vreg,vreg,v18; \
|
||||
+ bne cr6,L(label); \
|
||||
+ cmpldi r5,16; \
|
||||
+ ble L(null); \
|
||||
+ addi r5,r5,-16;
|
||||
+
|
||||
+/* Load 4 quadwords, merge into one VR for speed and check for NULLs. r6 has #
|
||||
+ of bytes already checked. */
|
||||
+#define CHECK64B(offset,addr,label) \
|
||||
+ M_LXVP(v4+32,offset,addr); \
|
||||
+ M_LXVP(v6+32,offset+32,addr); \
|
||||
+ MEMCHR_SUBTRACT_VECTORS; \
|
||||
+ vminub v14,v4,v5; \
|
||||
+ vminub v15,v6,v7; \
|
||||
+ vminub v16,v14,v15; \
|
||||
+ vcmpequb. v0,v16,M_VREG_ZERO; \
|
||||
+ beq cr6,$+12; \
|
||||
+ li r7,offset; \
|
||||
+ b L(label); \
|
||||
+ cmpldi r5,64; \
|
||||
+ ble L(null); \
|
||||
+ addi r5,r5,-64
|
||||
+
|
||||
+/* Implements the function
|
||||
+ void *[r3] memchr (const void *s [r3], int c [r4], size_t n [r5]). */
|
||||
+
|
||||
+ .machine power9
|
||||
+
|
||||
+ENTRY_TOCLESS (MEMCHR)
|
||||
+ CALL_MCOUNT 3
|
||||
+
|
||||
+ cmpldi r5,0
|
||||
+ beq L(null)
|
||||
+ mr r0,r5
|
||||
+ xori r6,r4,0xff
|
||||
+
|
||||
+ mtvsrd v18+32,r4 /* matching char in v18 */
|
||||
+ mtvsrd v19+32,r6 /* non matching char in v19 */
|
||||
+
|
||||
+ vspltb v18,v18,7 /* replicate */
|
||||
+ vspltb v19,v19,7 /* replicate */
|
||||
+ vspltisb M_VREG_ZERO,0
|
||||
+
|
||||
+ /* Next 16B-aligned address. Prepare address for L(aligned). */
|
||||
+ addi r6,r3,16
|
||||
+ clrrdi r6,r6,4
|
||||
+
|
||||
+ /* Align data and fill bytes not loaded with non matching char. */
|
||||
+ lvx v0,0,r3
|
||||
+ lvsr v1,0,r3
|
||||
+ vperm v0,v19,v0,v1
|
||||
+
|
||||
+ vcmpequb. v6,v0,v18
|
||||
+ bne cr6,L(found)
|
||||
+ sub r4,r6,r3
|
||||
+ cmpld r5,r4
|
||||
+ ble L(null)
|
||||
+ sub r5,r5,r4
|
||||
+
|
||||
+ /* Test up to OFF_START_LOOP-16 bytes in 16B chunks. The main loop is
|
||||
+ optimized for longer strings, so checking the first bytes in 16B
|
||||
+ chunks benefits a lot small strings. */
|
||||
+ .p2align 5
|
||||
+L(aligned):
|
||||
+ cmpldi r5,0
|
||||
+ beq L(null)
|
||||
+
|
||||
+ CHECK16B(v0,0,r6,tail1)
|
||||
+ CHECK16B(v1,16,r6,tail2)
|
||||
+ CHECK16B(v2,32,r6,tail3)
|
||||
+ CHECK16B(v3,48,r6,tail4)
|
||||
+ CHECK16B(v4,64,r6,tail5)
|
||||
+ CHECK16B(v5,80,r6,tail6)
|
||||
+ CHECK16B(v6,96,r6,tail7)
|
||||
+ CHECK16B(v7,112,r6,tail8)
|
||||
+ CHECK16B(v8,128,r6,tail9)
|
||||
+ CHECK16B(v9,144,r6,tail10)
|
||||
+ CHECK16B(v10,160,r6,tail11)
|
||||
+ CHECK16B(v0,176,r6,tail12)
|
||||
+ CHECK16B(v1,192,r6,tail13)
|
||||
+ CHECK16B(v2,208,r6,tail14)
|
||||
+ CHECK16B(v3,224,r6,tail15)
|
||||
+
|
||||
+ cmpdi cr5,r4,0 /* Check if c == 0. This will be useful to
|
||||
+ choose how we will perform the main loop. */
|
||||
+
|
||||
+ /* Prepare address for the loop. */
|
||||
+ addi r4,r3,M_OFF_START_LOOP
|
||||
+ clrrdi r4,r4,6
|
||||
+ sub r6,r4,r3
|
||||
+ sub r5,r0,r6
|
||||
+ addi r6,r4,128
|
||||
+
|
||||
+ /* If c == 0, use the loop without the vsububm. */
|
||||
+ beq cr5,L(loop)
|
||||
+
|
||||
+ /* This is very similar to the block after L(loop), the difference is
|
||||
+ that here MEMCHR_SUBTRACT_VECTORS is not empty, and we subtract
|
||||
+ each byte loaded by the char we are looking for, this way we can keep
|
||||
+ using vminub to merge the results and checking for nulls. */
|
||||
+ .p2align 5
|
||||
+L(memchr_loop):
|
||||
+ CHECK64B(0,r4,pre_tail_64b)
|
||||
+ CHECK64B(64,r4,pre_tail_64b)
|
||||
+ addi r4,r4,256
|
||||
+
|
||||
+ CHECK64B(0,r6,tail_64b)
|
||||
+ CHECK64B(64,r6,tail_64b)
|
||||
+ addi r6,r6,256
|
||||
+
|
||||
+ CHECK64B(0,r4,pre_tail_64b)
|
||||
+ CHECK64B(64,r4,pre_tail_64b)
|
||||
+ addi r4,r4,256
|
||||
+
|
||||
+ CHECK64B(0,r6,tail_64b)
|
||||
+ CHECK64B(64,r6,tail_64b)
|
||||
+ addi r6,r6,256
|
||||
+
|
||||
+ b L(memchr_loop)
|
||||
+ /* Switch to a more aggressive approach checking 64B each time. Use 2
|
||||
+ pointers 128B apart and unroll the loop once to make the pointer
|
||||
+ updates and usages separated enough to avoid stalls waiting for
|
||||
+ address calculation. */
|
||||
+ .p2align 5
|
||||
+L(loop):
|
||||
+#undef MEMCHR_SUBTRACT_VECTORS
|
||||
+#define MEMCHR_SUBTRACT_VECTORS /* nothing */
|
||||
+ CHECK64B(0,r4,pre_tail_64b)
|
||||
+ CHECK64B(64,r4,pre_tail_64b)
|
||||
+ addi r4,r4,256
|
||||
+
|
||||
+ CHECK64B(0,r6,tail_64b)
|
||||
+ CHECK64B(64,r6,tail_64b)
|
||||
+ addi r6,r6,256
|
||||
+
|
||||
+ CHECK64B(0,r4,pre_tail_64b)
|
||||
+ CHECK64B(64,r4,pre_tail_64b)
|
||||
+ addi r4,r4,256
|
||||
+
|
||||
+ CHECK64B(0,r6,tail_64b)
|
||||
+ CHECK64B(64,r6,tail_64b)
|
||||
+ addi r6,r6,256
|
||||
+
|
||||
+ b L(loop)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(pre_tail_64b):
|
||||
+ mr r6,r4
|
||||
+L(tail_64b):
|
||||
+ /* OK, we found a null byte. Let's look for it in the current 64-byte
|
||||
+ block and mark it in its corresponding VR. lxvp vx,0(ry) puts the
|
||||
+ low 16B bytes into vx+1, and the high into vx, so the order here is
|
||||
+ v5, v4, v7, v6. */
|
||||
+ vcmpequb v1,v5,M_VREG_ZERO
|
||||
+ vcmpequb v2,v4,M_VREG_ZERO
|
||||
+ vcmpequb v3,v7,M_VREG_ZERO
|
||||
+ vcmpequb v4,v6,M_VREG_ZERO
|
||||
+
|
||||
+ /* Take into account the other 64B blocks we had already checked. */
|
||||
+ add r6,r6,r7
|
||||
+ /* Extract first bit of each byte. */
|
||||
+ M_VEXTRACTBM(r8,v1)
|
||||
+ M_VEXTRACTBM(r9,v2)
|
||||
+ M_VEXTRACTBM(r10,v3)
|
||||
+ M_VEXTRACTBM(r11,v4)
|
||||
+
|
||||
+ /* Shift each value into their corresponding position. */
|
||||
+ sldi r9,r9,16
|
||||
+ sldi r10,r10,32
|
||||
+ sldi r11,r11,48
|
||||
+
|
||||
+ /* Merge the results. */
|
||||
+ or r8,r8,r9
|
||||
+ or r9,r10,r11
|
||||
+ or r11,r9,r8
|
||||
+
|
||||
+ cnttzd r0,r11 /* Count trailing zeros before the match. */
|
||||
+ cmpld r5,r0
|
||||
+ ble L(null)
|
||||
+ add r3,r6,r0 /* Compute final address. */
|
||||
+ blr
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail1):
|
||||
+ M_TAIL(v0,0)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail2):
|
||||
+ M_TAIL(v1,16)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail3):
|
||||
+ M_TAIL(v2,32)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail4):
|
||||
+ M_TAIL(v3,48)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail5):
|
||||
+ M_TAIL(v4,64)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail6):
|
||||
+ M_TAIL(v5,80)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail7):
|
||||
+ M_TAIL(v6,96)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail8):
|
||||
+ M_TAIL(v7,112)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail9):
|
||||
+ M_TAIL(v8,128)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail10):
|
||||
+ M_TAIL(v9,144)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail11):
|
||||
+ M_TAIL(v10,160)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail12):
|
||||
+ M_TAIL(v0,176)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail13):
|
||||
+ M_TAIL(v1,192)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail14):
|
||||
+ M_TAIL(v2,208)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(tail15):
|
||||
+ M_TAIL(v3,224)
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(found):
|
||||
+ vctzlsbb r7,v6
|
||||
+ cmpld r5,r7
|
||||
+ ble L(null)
|
||||
+ add r3,r3,r7
|
||||
+ blr
|
||||
+
|
||||
+ .p2align 5
|
||||
+L(null):
|
||||
+ li r3,0
|
||||
+ blr
|
||||
+
|
||||
+END (MEMCHR)
|
||||
+
|
||||
+weak_alias (__memchr, memchr)
|
||||
+libc_hidden_builtin_def (memchr)
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
index 91ed88a9c716800d..b4251932de1854c2 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||
@@ -31,10 +31,10 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \
|
||||
strncase-power8
|
||||
|
||||
ifneq (,$(filter %le,$(config-machine)))
|
||||
-sysdep_routines += memcmp-power10 memcpy-power10 memmove-power10 memset-power10 \
|
||||
- rawmemchr-power9 rawmemchr-power10 \
|
||||
- strcmp-power9 strcmp-power10 strncmp-power9 \
|
||||
- strcpy-power9 stpcpy-power9 \
|
||||
+sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
|
||||
+ memmove-power10 memset-power10 rawmemchr-power9 \
|
||||
+ rawmemchr-power10 strcmp-power9 strcmp-power10 \
|
||||
+ strncmp-power9 strcpy-power9 stpcpy-power9 \
|
||||
strlen-power9 strncpy-power9 stpncpy-power9 strlen-power10
|
||||
endif
|
||||
CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
index caec2047ab10d209..e8a38fd4d5e1357e 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||
@@ -265,6 +265,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||
|
||||
/* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */
|
||||
IFUNC_IMPL (i, name, memchr,
|
||||
+#ifdef __LITTLE_ENDIAN__
|
||||
+ IFUNC_IMPL_ADD (array, i, memchr,
|
||||
+ hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||
+ && hwcap & PPC_FEATURE_HAS_VSX,
|
||||
+ __memchr_power10)
|
||||
+#endif
|
||||
IFUNC_IMPL_ADD (array, i, memchr,
|
||||
hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S b/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..b9ed7926762e2b6f
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* Optimized memchr implementation for POWER10/PPC64.
|
||||
+ Copyright (C) 2016-2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
|
||||
+#define MEMCHR __memchr_power10
|
||||
+
|
||||
+#undef libc_hidden_builtin_def
|
||||
+#define libc_hidden_builtin_def(name)
|
||||
+#undef weak_alias
|
||||
+#define weak_alias(name,alias)
|
||||
+
|
||||
+#include <sysdeps/powerpc/powerpc64/le/power10/memchr.S>
|
||||
+#endif
|
||||
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||
index f40013e06113096f..389d5f18683c2dfc 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||
+++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
|
||||
@@ -25,15 +25,23 @@ extern __typeof (__memchr) __memchr_ppc attribute_hidden;
|
||||
extern __typeof (__memchr) __memchr_power7 attribute_hidden;
|
||||
extern __typeof (__memchr) __memchr_power8 attribute_hidden;
|
||||
|
||||
+# ifdef __LITTLE_ENDIAN__
|
||||
+extern __typeof (__memchr) __memchr_power10 attribute_hidden;
|
||||
+# endif
|
||||
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||
ifunc symbol properly. */
|
||||
libc_ifunc (__memchr,
|
||||
- (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||
- && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||
- ? __memchr_power8 :
|
||||
- (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||
- ? __memchr_power7
|
||||
- : __memchr_ppc);
|
||||
+# ifdef __LITTLE_ENDIAN__
|
||||
+ (hwcap2 & PPC_FEATURE2_ARCH_3_1
|
||||
+ && hwcap & PPC_FEATURE_HAS_VSX)
|
||||
+ ? __memchr_power10 :
|
||||
+# endif
|
||||
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
|
||||
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
|
||||
+ ? __memchr_power8 :
|
||||
+ (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||
+ ? __memchr_power7
|
||||
+ : __memchr_ppc);
|
||||
|
||||
weak_alias (__memchr, memchr)
|
||||
libc_hidden_builtin_def (memchr)
|
218
SOURCES/glibc-RHEL-24740-3.patch
Normal file
218
SOURCES/glibc-RHEL-24740-3.patch
Normal file
@ -0,0 +1,218 @@
|
||||
commit 90bcc8721ef82b7378d2b080141228660e862d56
|
||||
Author: Amrita H S <amritahs@linux.vnet.ibm.com>
|
||||
Date: Fri Dec 15 11:48:17 2023 -0500
|
||||
|
||||
powerpc: Fix performance issues of strcmp power10
|
||||
|
||||
Current implementation of strcmp for power10 has
|
||||
performance regression for multiple small sizes
|
||||
and alignment combination.
|
||||
|
||||
Most of these performance issues are fixed by this
|
||||
patch. The compare loop is unrolled and page crosses
|
||||
of unrolled loop is handled.
|
||||
|
||||
Thanks to Paul E. Murphy for helping in fixing the
|
||||
performance issues.
|
||||
|
||||
Signed-off-by: Amrita H S <amritahs@linux.vnet.ibm.com>
|
||||
Co-Authored-By: Paul E. Murphy <murphyp@linux.ibm.com>
|
||||
Reviewed-by: Rajalakshmi Srinivasaraghavan <rajis@linux.ibm.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/power10/strcmp.S b/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
|
||||
index a3c1adad539978e0..3406f4f26a214270 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
|
||||
@@ -62,7 +62,7 @@
|
||||
lxvl 32+v5,reg2,r0; \
|
||||
add reg1,reg1,len_reg; \
|
||||
add reg2,reg2,len_reg; \
|
||||
- vcmpnezb. v7,v4,v5; \
|
||||
+ vcmpnezb v7,v4,v5; \
|
||||
vctzlsbb r6,v7; \
|
||||
cmpld cr7,r6,len_reg; \
|
||||
blt cr7,L(different); \
|
||||
@@ -72,70 +72,110 @@
|
||||
|
||||
.machine power9
|
||||
ENTRY_TOCLESS (STRCMP, 4)
|
||||
- li r11,16
|
||||
- /* eq bit of cr1 used as swap status flag to indicate if
|
||||
- source pointers were swapped. */
|
||||
- crclr 4*cr1+eq
|
||||
- vspltisb v19,-1
|
||||
- andi. r7,r3,15
|
||||
- sub r7,r11,r7 /* r7(nalign1) = 16 - (str1 & 15). */
|
||||
- andi. r9,r4,15
|
||||
- sub r5,r11,r9 /* r5(nalign2) = 16 - (str2 & 15). */
|
||||
- cmpld cr7,r7,r5
|
||||
- beq cr7,L(same_aligned)
|
||||
- blt cr7,L(nalign1_min)
|
||||
- /* Swap r3 and r4, and r7 and r5 such that r3 and r7 hold the
|
||||
- pointer which is closer to the next 16B boundary so that only
|
||||
- one CHECK_N_BYTES is needed before entering the loop below. */
|
||||
- mr r8,r4
|
||||
- mr r4,r3
|
||||
- mr r3,r8
|
||||
- mr r12,r7
|
||||
- mr r7,r5
|
||||
- mr r5,r12
|
||||
- crset 4*cr1+eq /* Set bit on swapping source pointers. */
|
||||
+ andi. r7,r3,4095
|
||||
+ andi. r8,r4,4095
|
||||
+ cmpldi cr0,r7,4096-16
|
||||
+ cmpldi cr1,r8,4096-16
|
||||
+ bgt cr0,L(crosses)
|
||||
+ bgt cr1,L(crosses)
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
|
||||
- .p2align 5
|
||||
+L(crosses):
|
||||
+ andi. r7,r3,15
|
||||
+ subfic r7,r7,16 /* r7(nalign1) = 16 - (str1 & 15). */
|
||||
+ andi. r9,r4,15
|
||||
+ subfic r5,r9,16 /* r5(nalign2) = 16 - (str2 & 15). */
|
||||
+ cmpld cr7,r7,r5
|
||||
+ beq cr7,L(same_aligned)
|
||||
+ blt cr7,L(nalign1_min)
|
||||
+
|
||||
+ /* nalign2 is minimum and s2 pointer is aligned. */
|
||||
+ CHECK_N_BYTES(r3,r4,r5)
|
||||
+ /* Are we on the 64B hunk which crosses a page? */
|
||||
+ andi. r10,r3,63 /* Determine offset into 64B hunk. */
|
||||
+ andi. r8,r3,15 /* The offset into the 16B hunk. */
|
||||
+ neg r7,r3
|
||||
+ andi. r9,r7,15 /* Number of bytes after a 16B cross. */
|
||||
+ rlwinm. r7,r7,26,0x3F /* ((r3-4096))>>6&63. */
|
||||
+ beq L(compare_64_pagecross)
|
||||
+ mtctr r7
|
||||
+ b L(compare_64B_unaligned)
|
||||
+
|
||||
+ /* nalign1 is minimum and s1 pointer is aligned. */
|
||||
L(nalign1_min):
|
||||
CHECK_N_BYTES(r3,r4,r7)
|
||||
+ /* Are we on the 64B hunk which crosses a page? */
|
||||
+ andi. r10,r4,63 /* Determine offset into 64B hunk. */
|
||||
+ andi. r8,r4,15 /* The offset into the 16B hunk. */
|
||||
+ neg r7,r4
|
||||
+ andi. r9,r7,15 /* Number of bytes after a 16B cross. */
|
||||
+ rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
|
||||
+ beq L(compare_64_pagecross)
|
||||
+ mtctr r7
|
||||
|
||||
.p2align 5
|
||||
-L(s1_aligned):
|
||||
- /* r9 and r5 is number of bytes to be read after and before
|
||||
- page boundary correspondingly. */
|
||||
- sub r5,r5,r7
|
||||
- subfic r9,r5,16
|
||||
- /* Now let r7 hold the count of quadwords which can be
|
||||
- checked without crossing a page boundary. quadword offset is
|
||||
- (str2>>4)&0xFF. */
|
||||
- rlwinm r7,r4,28,0xFF
|
||||
- /* Below check is required only for first iteration. For second
|
||||
- iteration and beyond, the new loop counter is always 255. */
|
||||
- cmpldi r7,255
|
||||
- beq L(L3)
|
||||
- /* Get the initial loop count by 255-((str2>>4)&0xFF). */
|
||||
- subfic r11,r7,255
|
||||
+L(compare_64B_unaligned):
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ COMPARE_16(v4,v5,32)
|
||||
+ COMPARE_16(v4,v5,48)
|
||||
+ addi r3,r3,64
|
||||
+ addi r4,r4,64
|
||||
+ bdnz L(compare_64B_unaligned)
|
||||
|
||||
- .p2align 5
|
||||
-L(L1):
|
||||
+ /* Cross the page boundary of s2, carefully. Only for first
|
||||
+ iteration we have to get the count of 64B blocks to be checked.
|
||||
+ From second iteration and beyond, loop counter is always 63. */
|
||||
+L(compare_64_pagecross):
|
||||
+ li r11, 63
|
||||
mtctr r11
|
||||
-
|
||||
- .p2align 5
|
||||
-L(L2):
|
||||
- COMPARE_16(v4,v5,0) /* Load 16B blocks using lxv. */
|
||||
+ cmpldi r10,16
|
||||
+ ble L(cross_4)
|
||||
+ cmpldi r10,32
|
||||
+ ble L(cross_3)
|
||||
+ cmpldi r10,48
|
||||
+ ble L(cross_2)
|
||||
+L(cross_1):
|
||||
+ CHECK_N_BYTES(r3,r4,r9)
|
||||
+ CHECK_N_BYTES(r3,r4,r8)
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ COMPARE_16(v4,v5,32)
|
||||
+ addi r3,r3,48
|
||||
+ addi r4,r4,48
|
||||
+ b L(compare_64B_unaligned)
|
||||
+L(cross_2):
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
addi r3,r3,16
|
||||
addi r4,r4,16
|
||||
- bdnz L(L2)
|
||||
- /* Cross the page boundary of s2, carefully. */
|
||||
-
|
||||
- .p2align 5
|
||||
-L(L3):
|
||||
- CHECK_N_BYTES(r3,r4,r5)
|
||||
CHECK_N_BYTES(r3,r4,r9)
|
||||
- li r11,255 /* Load the new loop counter. */
|
||||
- b L(L1)
|
||||
+ CHECK_N_BYTES(r3,r4,r8)
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ addi r3,r3,32
|
||||
+ addi r4,r4,32
|
||||
+ b L(compare_64B_unaligned)
|
||||
+L(cross_3):
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ addi r3,r3,32
|
||||
+ addi r4,r4,32
|
||||
+ CHECK_N_BYTES(r3,r4,r9)
|
||||
+ CHECK_N_BYTES(r3,r4,r8)
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ addi r3,r3,16
|
||||
+ addi r4,r4,16
|
||||
+ b L(compare_64B_unaligned)
|
||||
+L(cross_4):
|
||||
+ COMPARE_16(v4,v5,0)
|
||||
+ COMPARE_16(v4,v5,16)
|
||||
+ COMPARE_16(v4,v5,32)
|
||||
+ addi r3,r3,48
|
||||
+ addi r4,r4,48
|
||||
+ CHECK_N_BYTES(r3,r4,r9)
|
||||
+ CHECK_N_BYTES(r3,r4,r8)
|
||||
+ b L(compare_64B_unaligned)
|
||||
|
||||
- .p2align 5
|
||||
L(same_aligned):
|
||||
CHECK_N_BYTES(r3,r4,r7)
|
||||
/* Align s1 to 32B and adjust s2 address.
|
||||
@@ -168,18 +208,7 @@ L(16B_aligned_loop):
|
||||
|
||||
/* Calculate and return the difference. */
|
||||
L(different):
|
||||
- vctzlsbb r6,v7
|
||||
- vextubrx r5,r6,v4
|
||||
- vextubrx r4,r6,v5
|
||||
- bt 4*cr1+eq,L(swapped)
|
||||
- subf r3,r4,r5
|
||||
- blr
|
||||
-
|
||||
- /* If src pointers were swapped, then swap the
|
||||
- indices and calculate the return value. */
|
||||
-L(swapped):
|
||||
- subf r3,r5,r4
|
||||
- blr
|
||||
+ TAIL(v4,v5)
|
||||
|
||||
.p2align 5
|
||||
L(32B_aligned_loop):
|
69
SOURCES/glibc-RHEL-38225-1.patch
Normal file
69
SOURCES/glibc-RHEL-38225-1.patch
Normal file
@ -0,0 +1,69 @@
|
||||
commit f942a732d37a96217ef828116ebe64a644db18d7
|
||||
Author: Joe Talbott <joetalbott@gmail.com>
|
||||
Date: Tue May 14 14:39:38 2024 +0000
|
||||
|
||||
math: Add GLIBC_TEST_LIBM_VERBOSE environment variable support.
|
||||
|
||||
Allow the libm-test-driver based tests to have their verbosity set based
|
||||
on the GLIBC_TEST_LIBM_VERBOSE environment variable. This allows the entire
|
||||
testsuite to be run with a non-default verbosity.
|
||||
|
||||
While here check the conversion for the verbose option as well.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/math/libm-test-support.c b/math/libm-test-support.c
|
||||
index 9b4cb2ee7d072578..9e64dcfc99234bc7 100644
|
||||
--- a/math/libm-test-support.c
|
||||
+++ b/math/libm-test-support.c
|
||||
@@ -130,7 +130,7 @@ static int noTests; /* number of tests (without testing exceptions) */
|
||||
static int noExcTests; /* number of tests for exception flags */
|
||||
static int noErrnoTests;/* number of tests for errno values */
|
||||
|
||||
-static int verbose;
|
||||
+static unsigned int verbose;
|
||||
static int output_max_error; /* Should the maximal errors printed? */
|
||||
static int output_points; /* Should the single function results printed? */
|
||||
static int ignore_max_ulp; /* Should we ignore max_ulp? */
|
||||
@@ -1057,7 +1057,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
break;
|
||||
case 'v':
|
||||
if (optarg)
|
||||
- verbose = (unsigned int) strtoul (optarg, NULL, 0);
|
||||
+ {
|
||||
+ char *optstr_conv = optarg;
|
||||
+ unsigned int opt_verbose;
|
||||
+
|
||||
+ opt_verbose = (unsigned int) strtoul (optarg, &optstr_conv, 0);
|
||||
+ if (*optstr_conv == '\0' && optstr_conv != optarg)
|
||||
+ verbose = opt_verbose;
|
||||
+ }
|
||||
else
|
||||
verbose = 3;
|
||||
break;
|
||||
@@ -1139,6 +1146,7 @@ libm_test_init (int argc, char **argv)
|
||||
int remaining;
|
||||
char *ulps_file_path;
|
||||
size_t dir_len = 0;
|
||||
+ char *envstr_verbose;
|
||||
|
||||
verbose = 1;
|
||||
output_ulps = 0;
|
||||
@@ -1148,6 +1156,17 @@ libm_test_init (int argc, char **argv)
|
||||
/* XXX set to 0 for releases. */
|
||||
ignore_max_ulp = 0;
|
||||
|
||||
+ envstr_verbose = getenv("GLIBC_TEST_LIBM_VERBOSE");
|
||||
+ if (envstr_verbose != NULL)
|
||||
+ {
|
||||
+ char *envstr_conv = envstr_verbose;
|
||||
+ unsigned int env_verbose;
|
||||
+
|
||||
+ env_verbose = (unsigned int) strtoul (envstr_verbose, &envstr_conv, 0);
|
||||
+ if (*envstr_conv == '\0' && envstr_conv != envstr_verbose)
|
||||
+ verbose = env_verbose;
|
||||
+ }
|
||||
+
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
529
SOURCES/glibc-RHEL-38225-2.patch
Normal file
529
SOURCES/glibc-RHEL-38225-2.patch
Normal file
@ -0,0 +1,529 @@
|
||||
commit ae18044f95271ed422ed847bd8d8c6d8e84674ce
|
||||
Author: Joe Simmons-Talbott <josimmon@redhat.com>
|
||||
Date: Mon May 20 14:09:35 2024 +0000
|
||||
|
||||
math: Add more details to the test driver output.
|
||||
|
||||
Add start and end indicators that identify the test being run in the
|
||||
verbose output. Better identify the tests for max errors in the
|
||||
summary output. Count each exception checked for each test. Remove
|
||||
double counting of tests for the check_<type> functions other than
|
||||
check_float_internal. Rename print_max_error and
|
||||
print_complex_max_error to check_max_error and check_complex_max_error
|
||||
respectively since they have side effects.
|
||||
|
||||
Co-Authored-By: Carlos O'Donell <carlos@redhat.com>
|
||||
Reviewed-By: Joseph Myers <josmyers@redhat.com>
|
||||
|
||||
diff --git a/math/libm-test-driver.c b/math/libm-test-driver.c
|
||||
index 0a430a86067766e3..5448ea2109a264b7 100644
|
||||
--- a/math/libm-test-driver.c
|
||||
+++ b/math/libm-test-driver.c
|
||||
@@ -1059,9 +1059,9 @@ struct test_Ff_b1_data
|
||||
= STR_CON3 (FUN, SUFF, TEST_SUFF) TEST_SUFF_STR; \
|
||||
init_max_error (this_func, EXACT, TEST_COND_any_ibm128)
|
||||
#define END \
|
||||
- print_max_error (this_func)
|
||||
+ check_max_error (this_func)
|
||||
#define END_COMPLEX \
|
||||
- print_complex_max_error (this_func)
|
||||
+ check_complex_max_error (this_func)
|
||||
|
||||
/* Run tests for a given function in all rounding modes. */
|
||||
#define ALL_RM_TEST(FUNC, EXACT, ARRAY, LOOP_MACRO, END_MACRO, ...) \
|
||||
diff --git a/math/libm-test-support.c b/math/libm-test-support.c
|
||||
index 9e64dcfc99234bc7..5cf5aa5df2cacb24 100644
|
||||
--- a/math/libm-test-support.c
|
||||
+++ b/math/libm-test-support.c
|
||||
@@ -112,6 +112,7 @@
|
||||
#include <argp.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
+#include <assert.h>
|
||||
|
||||
/* This header defines func_ulps, func_real_ulps and func_imag_ulps
|
||||
arrays. */
|
||||
@@ -125,10 +126,13 @@ static FILE *ulps_file; /* File to document difference. */
|
||||
static int output_ulps; /* Should ulps printed? */
|
||||
static char *output_dir; /* Directory where generated files will be written. */
|
||||
|
||||
-static int noErrors; /* number of errors */
|
||||
-static int noTests; /* number of tests (without testing exceptions) */
|
||||
-static int noExcTests; /* number of tests for exception flags */
|
||||
-static int noErrnoTests;/* number of tests for errno values */
|
||||
+#define TEST_INPUT 1
|
||||
+#define TEST_MAXERROR 2
|
||||
+static int noErrors; /* number of errors */
|
||||
+static int noTests; /* number of tests (without testing exceptions) */
|
||||
+static int noMaxErrorTests; /* number of max error tests */
|
||||
+static int noExcTests; /* number of tests for exception flags */
|
||||
+static int noErrnoTests; /* number of tests for errno values */
|
||||
|
||||
static unsigned int verbose;
|
||||
static int output_max_error; /* Should the maximal errors printed? */
|
||||
@@ -299,9 +303,19 @@ print_screen_max_error (int ok)
|
||||
|
||||
/* Update statistic counters. */
|
||||
static void
|
||||
-update_stats (int ok)
|
||||
+update_stats (int ok, int testType)
|
||||
{
|
||||
- ++noTests;
|
||||
+ switch (testType)
|
||||
+ {
|
||||
+ case TEST_INPUT:
|
||||
+ ++noTests;
|
||||
+ break;
|
||||
+ case TEST_MAXERROR:
|
||||
+ ++noMaxErrorTests;
|
||||
+ break;
|
||||
+ default:
|
||||
+ abort();
|
||||
+ }
|
||||
if (!ok)
|
||||
++noErrors;
|
||||
}
|
||||
@@ -367,11 +381,30 @@ fpstack_test (const char *test_name)
|
||||
#endif
|
||||
}
|
||||
|
||||
+static void
|
||||
+print_test_start (int test_num, const char *test_name, int test_type)
|
||||
+{
|
||||
+ if (print_screen (1))
|
||||
+ printf ("--- Start of%s test # %d, named \"%s\" ---\n",
|
||||
+ test_type == TEST_MAXERROR ? " max error" : "", test_num, test_name);
|
||||
+}
|
||||
|
||||
+static void
|
||||
+print_test_end (int test_num, const char *test_name, int test_type)
|
||||
+{
|
||||
+ if (print_screen (1))
|
||||
+ printf ("--- End of%s test # %d, named \"%s\" ---\n",
|
||||
+ test_type == TEST_MAXERROR ? " max error" : "", test_num, test_name);
|
||||
+}
|
||||
+
|
||||
+/* This is a builtin test of overall max error. */
|
||||
void
|
||||
-print_max_error (const char *func_name)
|
||||
+check_max_error (const char *func_name)
|
||||
{
|
||||
int ok = 0;
|
||||
+ int thisTest = noMaxErrorTests;
|
||||
+
|
||||
+ print_test_start (thisTest, func_name, TEST_MAXERROR);
|
||||
|
||||
if (max_error == 0.0 || (max_error <= prev_max_error && !ignore_max_ulp))
|
||||
{
|
||||
@@ -392,14 +425,19 @@ print_max_error (const char *func_name)
|
||||
printf (" accepted: %s ulp\n", pmestr);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
-}
|
||||
+ update_stats (ok, TEST_MAXERROR);
|
||||
|
||||
+ print_test_end (thisTest, func_name, TEST_MAXERROR);
|
||||
+}
|
||||
|
||||
+/* This is a builtin test of overall max error. */
|
||||
void
|
||||
-print_complex_max_error (const char *func_name)
|
||||
+check_complex_max_error (const char *func_name)
|
||||
{
|
||||
int real_ok = 0, imag_ok = 0, ok;
|
||||
+ int thisTest = noMaxErrorTests;
|
||||
+
|
||||
+ print_test_start (thisTest, func_name, TEST_MAXERROR);
|
||||
|
||||
if (real_max_error == 0
|
||||
|| (real_max_error <= prev_real_max_error && !ignore_max_ulp))
|
||||
@@ -436,7 +474,8 @@ print_complex_max_error (const char *func_name)
|
||||
printf (" accepted: %s ulp\n", pimestr);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_MAXERROR);
|
||||
+ print_test_end (thisTest, func_name, TEST_MAXERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -477,12 +516,13 @@ test_single_exception (const char *test_name,
|
||||
else
|
||||
{
|
||||
if (print_screen (1))
|
||||
- printf ("%s: Exception \"%s\" not set\n", test_name,
|
||||
+ printf ("Pass: %s: Exception \"%s\" not set\n", test_name,
|
||||
flag_name);
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
++noErrors;
|
||||
+ ++noExcTests;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -494,23 +534,32 @@ test_exceptions (const char *test_name, int exception)
|
||||
{
|
||||
if (flag_test_exceptions && EXCEPTION_TESTS (FLOAT))
|
||||
{
|
||||
- ++noExcTests;
|
||||
+ int ran = 0;
|
||||
#ifdef FE_DIVBYZERO
|
||||
if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0)
|
||||
- test_single_exception (test_name, exception,
|
||||
- DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
|
||||
- "Divide by zero");
|
||||
+ {
|
||||
+ test_single_exception (test_name, exception,
|
||||
+ DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
|
||||
+ "Divide by zero");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
#endif
|
||||
#ifdef FE_INVALID
|
||||
if ((exception & INVALID_EXCEPTION_OK) == 0)
|
||||
- test_single_exception (test_name, exception,
|
||||
- INVALID_EXCEPTION, FE_INVALID,
|
||||
- "Invalid operation");
|
||||
+ {
|
||||
+ test_single_exception (test_name, exception,
|
||||
+ INVALID_EXCEPTION, FE_INVALID,
|
||||
+ "Invalid operation");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
#endif
|
||||
#ifdef FE_OVERFLOW
|
||||
if ((exception & OVERFLOW_EXCEPTION_OK) == 0)
|
||||
- test_single_exception (test_name, exception, OVERFLOW_EXCEPTION,
|
||||
- FE_OVERFLOW, "Overflow");
|
||||
+ {
|
||||
+ test_single_exception (test_name, exception, OVERFLOW_EXCEPTION,
|
||||
+ FE_OVERFLOW, "Overflow");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
#endif
|
||||
/* Spurious "underflow" and "inexact" exceptions are always
|
||||
allowed for IBM long double, in line with the underlying
|
||||
@@ -519,17 +568,30 @@ test_exceptions (const char *test_name, int exception)
|
||||
if ((exception & UNDERFLOW_EXCEPTION_OK) == 0
|
||||
&& !(test_ibm128
|
||||
&& (exception & UNDERFLOW_EXCEPTION) == 0))
|
||||
- test_single_exception (test_name, exception, UNDERFLOW_EXCEPTION,
|
||||
- FE_UNDERFLOW, "Underflow");
|
||||
+ {
|
||||
+ test_single_exception (test_name, exception, UNDERFLOW_EXCEPTION,
|
||||
+ FE_UNDERFLOW, "Underflow");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
+
|
||||
#endif
|
||||
#ifdef FE_INEXACT
|
||||
if ((exception & (INEXACT_EXCEPTION | NO_INEXACT_EXCEPTION)) != 0
|
||||
&& !(test_ibm128
|
||||
&& (exception & NO_INEXACT_EXCEPTION) != 0))
|
||||
- test_single_exception (test_name, exception, INEXACT_EXCEPTION,
|
||||
- FE_INEXACT, "Inexact");
|
||||
+ {
|
||||
+ test_single_exception (test_name, exception, INEXACT_EXCEPTION,
|
||||
+ FE_INEXACT, "Inexact");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
#endif
|
||||
+ assert (ran == 1);
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ if (print_screen (1))
|
||||
+ printf ("Info: %s: No exceptions tested\n", test_name);
|
||||
+ }
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
@@ -552,6 +614,7 @@ test_single_errno (const char *test_name, int errno_value,
|
||||
printf ("Failure: %s: errno set to %d, expected %d (%s)\n",
|
||||
test_name, errno_value, expected_value, expected_name);
|
||||
}
|
||||
+ ++noErrnoTests;
|
||||
}
|
||||
|
||||
/* Test whether errno (value ERRNO_VALUE) has been for TEST_NAME set
|
||||
@@ -561,13 +624,39 @@ test_errno (const char *test_name, int errno_value, int exceptions)
|
||||
{
|
||||
if (flag_test_errno)
|
||||
{
|
||||
- ++noErrnoTests;
|
||||
+ int ran = 0;
|
||||
+
|
||||
+ if ((exceptions & (ERRNO_UNCHANGED|ERRNO_EDOM|ERRNO_ERANGE)) == 0)
|
||||
+ {
|
||||
+ if (print_screen (1))
|
||||
+ printf ("Info: %s: The value of errno was not tested\n",
|
||||
+ test_name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
if (exceptions & ERRNO_UNCHANGED)
|
||||
- test_single_errno (test_name, errno_value, 0, "unchanged");
|
||||
+ {
|
||||
+ test_single_errno (test_name, errno_value, 0, "unchanged");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
if (exceptions & ERRNO_EDOM)
|
||||
- test_single_errno (test_name, errno_value, EDOM, "EDOM");
|
||||
+ {
|
||||
+ test_single_errno (test_name, errno_value, EDOM, "EDOM");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
if (exceptions & ERRNO_ERANGE)
|
||||
- test_single_errno (test_name, errno_value, ERANGE, "ERANGE");
|
||||
+ {
|
||||
+ test_single_errno (test_name, errno_value, ERANGE, "ERANGE");
|
||||
+ ran = 1;
|
||||
+ }
|
||||
+
|
||||
+ assert (ran == 1);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (print_screen (1))
|
||||
+ printf ("Info: %s: No errno tests\n", test_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,6 +708,9 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
|
||||
FLOAT diff = 0;
|
||||
FLOAT ulps = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
@@ -716,12 +808,13 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
|
||||
printf (" max.ulp : %s\n", mustrn);
|
||||
}
|
||||
}
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -776,12 +869,14 @@ check_int (const char *test_name, int computed, int expected,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if (computed == expected)
|
||||
ok = 1;
|
||||
|
||||
@@ -795,11 +890,12 @@ check_int (const char *test_name, int computed, int expected,
|
||||
printf (" should be: %d\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -810,12 +906,14 @@ check_long (const char *test_name, long int computed, long int expected,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if (computed == expected)
|
||||
ok = 1;
|
||||
|
||||
@@ -829,11 +927,12 @@ check_long (const char *test_name, long int computed, long int expected,
|
||||
printf (" should be: %ld\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -844,12 +943,14 @@ check_bool (const char *test_name, int computed, int expected,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if ((computed == 0) == (expected == 0))
|
||||
ok = 1;
|
||||
|
||||
@@ -863,11 +964,12 @@ check_bool (const char *test_name, int computed, int expected,
|
||||
printf (" should be: %d\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -879,12 +981,14 @@ check_longlong (const char *test_name, long long int computed,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if (computed == expected)
|
||||
ok = 1;
|
||||
|
||||
@@ -898,11 +1002,12 @@ check_longlong (const char *test_name, long long int computed,
|
||||
printf (" should be: %lld\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -913,12 +1018,14 @@ check_intmax_t (const char *test_name, intmax_t computed,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if (computed == expected)
|
||||
ok = 1;
|
||||
|
||||
@@ -932,11 +1039,12 @@ check_intmax_t (const char *test_name, intmax_t computed,
|
||||
printf (" should be: %jd\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -947,12 +1055,14 @@ check_uintmax_t (const char *test_name, uintmax_t computed,
|
||||
{
|
||||
int ok = 0;
|
||||
int errno_value = errno;
|
||||
+ int thisTest = noTests;
|
||||
+
|
||||
+ print_test_start (thisTest, test_name, TEST_INPUT);
|
||||
|
||||
test_exceptions (test_name, exceptions);
|
||||
test_errno (test_name, errno_value, exceptions);
|
||||
if (exceptions & IGNORE_RESULT)
|
||||
goto out;
|
||||
- noTests++;
|
||||
if (computed == expected)
|
||||
ok = 1;
|
||||
|
||||
@@ -966,11 +1076,12 @@ check_uintmax_t (const char *test_name, uintmax_t computed,
|
||||
printf (" should be: %ju\n", expected);
|
||||
}
|
||||
|
||||
- update_stats (ok);
|
||||
+ update_stats (ok, TEST_INPUT);
|
||||
out:
|
||||
fpstack_test (test_name);
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
errno = 0;
|
||||
+ print_test_end (thisTest, test_name, TEST_INPUT);
|
||||
}
|
||||
|
||||
/* Return whether a test with flags EXCEPTIONS should be run. */
|
||||
@@ -1211,9 +1322,11 @@ libm_test_finish (void)
|
||||
fclose (ulps_file);
|
||||
|
||||
printf ("\nTest suite completed:\n");
|
||||
- printf (" %d test cases plus %d tests for exception flags and\n"
|
||||
- " %d tests for errno executed.\n",
|
||||
- noTests, noExcTests, noErrnoTests);
|
||||
+ printf (" %d max error test cases,\n", noMaxErrorTests);
|
||||
+ printf (" %d input tests,\n", noTests);
|
||||
+ printf (" - with %d tests for exception flags,\n", noExcTests);
|
||||
+ printf (" - with %d tests for errno executed.\n", noErrnoTests);
|
||||
+
|
||||
if (noErrors)
|
||||
{
|
||||
printf (" %d errors occurred.\n", noErrors);
|
||||
diff --git a/math/libm-test-support.h b/math/libm-test-support.h
|
||||
index ba670014548e73eb..e6f03ee154e7a65d 100644
|
||||
--- a/math/libm-test-support.h
|
||||
+++ b/math/libm-test-support.h
|
||||
@@ -170,8 +170,8 @@ extern const char doc[];
|
||||
|
||||
int enable_test (int);
|
||||
void init_max_error (const char *, int, int);
|
||||
-void print_max_error (const char *);
|
||||
-void print_complex_max_error (const char *);
|
||||
+void check_max_error (const char *);
|
||||
+void check_complex_max_error (const char *);
|
||||
void check_float (const char *, FLOAT, FLOAT, int);
|
||||
void check_complex (const char *, CFLOAT, CFLOAT, int);
|
||||
void check_int (const char *, int, int, int);
|
320
SOURCES/glibc-RHEL-41189.patch
Normal file
320
SOURCES/glibc-RHEL-41189.patch
Normal file
@ -0,0 +1,320 @@
|
||||
From 3de73f974fab55430177c811c9c9ba3f251d5747 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed, 7 Aug 2024 14:57:41 +0200
|
||||
Subject: manual: Add Descriptor-Relative Access section
|
||||
|
||||
Reference this new section from the O_PATH documentation.
|
||||
|
||||
And document the functions openat, openat64, fstatat, fstatat64.
|
||||
(The safety assessment for fstatat was already obsolete because
|
||||
current glibc assumes kernel support for the underlying system
|
||||
call.)
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/manual/filesys.texi b/manual/filesys.texi
|
||||
index 47d929744e..aabb68385b 100644
|
||||
--- a/manual/filesys.texi
|
||||
+++ b/manual/filesys.texi
|
||||
@@ -15,6 +15,7 @@ access permissions and modification times.
|
||||
@menu
|
||||
* Working Directory:: This is used to resolve relative
|
||||
file names.
|
||||
+* Descriptor-Relative Access:: Ways to control file name lookup.
|
||||
* Accessing Directories:: Finding out what files a directory
|
||||
contains.
|
||||
* Working with Directory Trees:: Apply actions to all files or a selectable
|
||||
@@ -206,6 +207,151 @@ An I/O error occurred.
|
||||
@end table
|
||||
@end deftypefun
|
||||
|
||||
+@node Descriptor-Relative Access
|
||||
+@section Descriptor-Relative Access
|
||||
+@cindex file name resolution based on descriptors
|
||||
+@cindex descriptor-based file name resolution
|
||||
+@cindex @code{@dots{}at} functions
|
||||
+
|
||||
+Many functions that accept file names have @code{@dots{}at} variants
|
||||
+which accept a file descriptor and a file name argument instead of just
|
||||
+a file name argument. For example, @code{fstatat} is the
|
||||
+descriptor-based variant of the @code{fstat} function. Most such
|
||||
+functions also accept an additional flags argument which changes the
|
||||
+behavior of the file name lookup based on the passed @code{AT_@dots{}}
|
||||
+flags.
|
||||
+
|
||||
+There are several reasons to use descriptor-relative access:
|
||||
+
|
||||
+@itemize @bullet
|
||||
+@item
|
||||
+The working directory is a process-wide resource, so individual threads
|
||||
+cannot change it without affecting other threads in the process.
|
||||
+Explicitly specifying the directory against which relative paths are
|
||||
+resolved can be a thread-safe alternative to changing the working
|
||||
+directory.
|
||||
+
|
||||
+@item
|
||||
+If a program wishes to access a directory tree which is being modified
|
||||
+concurrently, perhaps even by a different user on the system, the
|
||||
+program must avoid looking up file names with multiple components, in
|
||||
+order to detect symbolic links, using the @code{O_NOFOLLOW} flag
|
||||
+(@pxref{Open-time Flags}) or the @code{AT_SYMLINK_FOLLOW} flag
|
||||
+(described below). Without directory-relative access, it is necessary
|
||||
+to use the @code{fchdir} function to change the working directory
|
||||
+(@pxref{Working Directory}), which is not thread-safe.
|
||||
+
|
||||
+@item
|
||||
+Listing directory contents using the @code{readdir} or @code{readdir64}
|
||||
+functions (@pxref{Reading/Closing Directory}) does not provide full file
|
||||
+name paths. Using @code{@dots{}at} functions, it is possible to use the
|
||||
+file names directly, without having to construct such full paths.
|
||||
+
|
||||
+@item
|
||||
+Additional flags available with some of the @code{@dots{}at} functions
|
||||
+provide access to functionality which is not available otherwise.
|
||||
+@end itemize
|
||||
+
|
||||
+The file descriptor used by these @code{@dots{}at} functions has the
|
||||
+following uses:
|
||||
+
|
||||
+@itemize @bullet
|
||||
+@item
|
||||
+It can be a file descriptor referring to a directory. Such a descriptor
|
||||
+can be created explicitly using the @code{open} function and the
|
||||
+@code{O_RDONLY} file access mode, with or without the @code{O_DIRECTORY}
|
||||
+flag. @xref{Opening and Closing Files}. Or it can be created
|
||||
+implicitly by @code{opendir} and retrieved using the @code{dirfd}
|
||||
+function. @xref{Opening a Directory}.
|
||||
+
|
||||
+If a directory descriptor is used with one of the @code{@dots{}at}
|
||||
+functions, a relative file name argument is resolved relative to
|
||||
+directory referred to by the file descriptor, just as if that directory
|
||||
+were the current working directory. Absolute file name arguments
|
||||
+(starting with @samp{/}) are resolved against the file system root, and
|
||||
+the descriptor argument is effectively ignored.
|
||||
+
|
||||
+This means that file name lookup is not constrained to the directory of
|
||||
+the descriptor. For example, it is possible to access a file
|
||||
+@file{example} in the descriptor's parent directory using a file name
|
||||
+argument @code{"../example"}, or in the root directory using
|
||||
+@code{"/example"}.
|
||||
+
|
||||
+If the file descriptor refers to a directory, the empty string @code{""}
|
||||
+is not a valid file name argument. It is possible to use @code{"."} to
|
||||
+refer to the directory itself. Also see @code{AT_EMPTY_PATH} below.
|
||||
+
|
||||
+@item
|
||||
+@vindex @code{AT_FDCWD}
|
||||
+The special value @code{AT_FDCWD}. This means that the current working
|
||||
+directory is used for the lookup if the file name is a relative. For
|
||||
+@code{@dots{}at} functions with an @code{AT_@dots{}} flags argument,
|
||||
+this provides a shortcut to use those flags with regular (not
|
||||
+descriptor-based) file name lookups.
|
||||
+
|
||||
+If @code{AT_FDCWD} is used, the empty string @code{""} is not a valid
|
||||
+file name argument.
|
||||
+
|
||||
+@item
|
||||
+An arbitrary file descriptor, along with an empty string @code{""} as
|
||||
+the file name argument, and the @code{AT_EMPTY_PATH} flag. In this
|
||||
+case, the operation uses the file descriptor directly, without further
|
||||
+file name resolution. On Linux, this allows operations on descriptors
|
||||
+opened with the @code{O_PATH} flag. For regular descriptors (opened
|
||||
+without @code{O_PATH}), the same functionality is also available through
|
||||
+the plain descriptor-based functions (for example, @code{fstat} instead
|
||||
+of @code{fstatat}).
|
||||
+
|
||||
+This is a GNU extension.
|
||||
+@end itemize
|
||||
+
|
||||
+@cindex file name resolution flags
|
||||
+@cindex @code{AT_*} file name resolution flags
|
||||
+The flags argument in @code{@dots{}at} functions can be a combination of
|
||||
+the following flags, defined in @file{fcntl.h}. Not all such functions
|
||||
+support all flags, and some (such as @code{openat}) do not accept a
|
||||
+flags argument at all.
|
||||
+
|
||||
+In the flag descriptions below, the @dfn{effective final path component}
|
||||
+refers to the final component (basename) of the full path constructed
|
||||
+from the descriptor and file name arguments, using file name lookup, as
|
||||
+described above.
|
||||
+
|
||||
+@vtable @code
|
||||
+@item AT_EMPTY_PATH
|
||||
+This flag is used with an empty file name @code{""} and a descriptor
|
||||
+which does not necessarily refer to a directory. It is most useful with
|
||||
+@code{O_PATH} descriptors, as described above. This flag is a GNU
|
||||
+extension.
|
||||
+
|
||||
+@item AT_NO_AUTOMOUNT
|
||||
+If the effective final path component refers to a potential file system
|
||||
+mount point controlled by an auto-mounting service, the operation does
|
||||
+not trigger auto-mounting and refers to the unmounted mount point
|
||||
+instead. @xref{Mount-Unmount-Remount}. If a file system has already
|
||||
+been mounted at the effective final path component, the operation
|
||||
+applies to the file or directory in the mounted file system, not the
|
||||
+underlying file system that was mounted over. This flag is a GNU
|
||||
+extension.
|
||||
+
|
||||
+@item AT_SYMLINK_FOLLOW
|
||||
+If the effective final path component is a symbolic link, the
|
||||
+operation follows the symbolic link and operates on its target. (For
|
||||
+most functions, this is the default behavior.)
|
||||
+
|
||||
+@item AT_SYMLINK_NOFOLLOW
|
||||
+If the effective final path component is a symbolic link, the
|
||||
+operation operates on the symbolic link, without following it. The
|
||||
+difference in behavior enabled by this flag is similar to the difference
|
||||
+between the @code{lstat} and @code{stat} functions, or the behavior
|
||||
+activated by the @code{O_NOFOLLOW} argument to the @code{open} function.
|
||||
+Even with the @code{AT_SYMLINK_NOFOLLOW} flag present, symbolic links in
|
||||
+a non-final component of the file name are still followed.
|
||||
+@end vtable
|
||||
+
|
||||
+@strong{Note:} There is no relationship between these flags and the type
|
||||
+argument to the @code{getauxval} function (with @code{AT_@dots{}}
|
||||
+constants defined in @file{elf.h}). @xref{Auxiliary Vector}.
|
||||
|
||||
@node Accessing Directories
|
||||
@section Accessing Directories
|
||||
@@ -1250,10 +1396,11 @@ A hardware error occurred while trying to read or write the to filesystem.
|
||||
|
||||
The @code{linkat} function is analogous to the @code{link} function,
|
||||
except that it identifies its source and target using a combination of a
|
||||
-file descriptor (referring to a directory) and a pathname. If a
|
||||
-pathnames is not absolute, it is resolved relative to the corresponding
|
||||
-file descriptor. The special file descriptor @code{AT_FDCWD} denotes
|
||||
-the current directory.
|
||||
+file descriptor (referring to a directory) and a file name.
|
||||
+@xref{Descriptor-Relative Access}. For @code{linkat}, if a file name is
|
||||
+not absolute, it is resolved relative to the corresponding file
|
||||
+descriptor. As usual, the special value @code{AT_FDCWD} denotes the
|
||||
+current directory.
|
||||
|
||||
The @var{flags} argument is a combination of the following flags:
|
||||
|
||||
@@ -2091,9 +2238,44 @@ function is available under the name @code{fstat} and so transparently
|
||||
replaces the interface for small files on 32-bit machines.
|
||||
@end deftypefun
|
||||
|
||||
-@c fstatat will call alloca and snprintf if the syscall is not
|
||||
-@c available.
|
||||
-@c @safety{@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
|
||||
+@deftypefun int fstatat (int @var{filedes}, const char *@var{filename}, struct stat *@var{buf}, int @var{flags})
|
||||
+@standards{POSIX.1, sys/stat.h}
|
||||
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||
+This function is a descriptor-relative version of the @code{fstat}
|
||||
+function above. @xref{Descriptor-Relative Access}. The @var{flags}
|
||||
+argument can contain a combination of the flags @code{AT_EMPTY_PATH},
|
||||
+@code{AT_NO_AUTOMOUNT}, @code{AT_SYMLINK_NOFOLLOW}.
|
||||
+
|
||||
+Compared to @code{fstat}, the following additional error conditions can
|
||||
+occur:
|
||||
+
|
||||
+@table @code
|
||||
+@item EBADF
|
||||
+The @var{filedes} argument is not a valid file descriptor.
|
||||
+
|
||||
+@item EINVAL
|
||||
+The @var{flags} argument is not valid for this function.
|
||||
+
|
||||
+@item ENOTDIR
|
||||
+The descriptor @var{filedes} is not associated with a directory, and
|
||||
+@var{filename} is a relative file name.
|
||||
+@end table
|
||||
+
|
||||
+When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
|
||||
+function is in fact @code{fstatat64} since the LFS interface transparently
|
||||
+replaces the normal implementation.
|
||||
+@end deftypefun
|
||||
+
|
||||
+@deftypefun int fstatat64 (int @var{filedes}, const char *@var{filename}, struct stat64 *@var{buf}, int @var{flags})
|
||||
+@standards{GNU, sys/stat.h}
|
||||
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||
+This function is the large-file variant of @code{fstatat}, similar to
|
||||
+how @code{fstat64} is the variant of @code{fstat}.
|
||||
+
|
||||
+When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
|
||||
+function is available under the name @code{fstatat} and so transparently
|
||||
+replaces the interface for small files on 32-bit machines.
|
||||
+@end deftypefun
|
||||
|
||||
@deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf})
|
||||
@standards{BSD, sys/stat.h}
|
||||
diff --git a/manual/llio.texi b/manual/llio.texi
|
||||
index ea84196abd..a035c3e20f 100644
|
||||
--- a/manual/llio.texi
|
||||
+++ b/manual/llio.texi
|
||||
@@ -181,6 +181,43 @@ new, extended API using 64 bit file sizes and offsets transparently
|
||||
replaces the old API.
|
||||
@end deftypefun
|
||||
|
||||
+@deftypefun int openat (int @var{filedes}, const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
|
||||
+@standards{POSIX.1, fcntl.h}
|
||||
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
|
||||
+This function is the descriptor-relative variant of the @code{open}
|
||||
+function. @xref{Descriptor-Relative Access}.
|
||||
+
|
||||
+Note that the @var{flags} argument of @code{openat} does not accept
|
||||
+@code{AT_@dots{}} flags, only the flags described for the @code{open}
|
||||
+function above.
|
||||
+
|
||||
+The @code{openat} function can fail for additional reasons:
|
||||
+
|
||||
+@table @code
|
||||
+@item EBADF
|
||||
+The @var{filedes} argument is not a valid file descriptor.
|
||||
+
|
||||
+@item ENOTDIR
|
||||
+The descriptor @var{filedes} is not associated with a directory, and
|
||||
+@var{filename} is a relative file name.
|
||||
+@end table
|
||||
+
|
||||
+When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
|
||||
+function is in fact @code{openat64} since the LFS interface transparently
|
||||
+replaces the normal implementation.
|
||||
+@end deftypefun
|
||||
+
|
||||
+@deftypefun int openat64 (int @var{filedes}, const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
|
||||
+@standards{GNU, fcntl.h}
|
||||
+The large-file variant of the @code{openat}, similar to how
|
||||
+@code{open64} is the large-file variant of @code{open}.
|
||||
+
|
||||
+When the sources are translated with @code{_FILE_OFFSET_BITS == 64} this
|
||||
+function is actually available under the name @code{openat}. I.e., the
|
||||
+new, extended API using 64 bit file sizes and offsets transparently
|
||||
+replaces the old API.
|
||||
+@end deftypefun
|
||||
+
|
||||
@deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode})
|
||||
@standards{POSIX.1, fcntl.h}
|
||||
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
|
||||
@@ -3775,7 +3812,9 @@ contains it is still needed), and permissions are checked when the
|
||||
descriptor is used later on.
|
||||
|
||||
For example, such descriptors can be used with the @code{fexecve}
|
||||
-function (@pxref{Executing a File}).
|
||||
+function (@pxref{Executing a File}). Other applications involve the
|
||||
+@samp{*at} function variants, along with the @code{AT_EMPTY_PATH} flag.
|
||||
+@xref{Descriptor-Relative Access}.
|
||||
|
||||
This access mode is specific to Linux. On @gnuhurdsystems{}, it is
|
||||
possible to use @code{O_EXEC} explicitly, or specify no access modes
|
||||
diff --git a/manual/startup.texi b/manual/startup.texi
|
||||
index 747beed4d9..8ac3b97eed 100644
|
||||
--- a/manual/startup.texi
|
||||
+++ b/manual/startup.texi
|
||||
@@ -665,8 +665,12 @@ basis there may be information that is not available any other way.
|
||||
This function is used to inquire about the entries in the auxiliary
|
||||
vector. The @var{type} argument should be one of the @samp{AT_} symbols
|
||||
defined in @file{elf.h}. If a matching entry is found, the value is
|
||||
-returned; if the entry is not found, zero is returned and @code{errno} is
|
||||
-set to @code{ENOENT}.
|
||||
+returned; if the entry is not found, zero is returned and @code{errno}
|
||||
+is set to @code{ENOENT}.
|
||||
+
|
||||
+@strong{Note:} There is no relationship between the @samp{AT_} contants
|
||||
+defined in @file{elf.h} and the file name lookup flags in
|
||||
+@file{fcntl.h}. @xref{Descriptor-Relative Access}.
|
||||
@end deftypefun
|
||||
|
||||
For some platforms, the key @code{AT_HWCAP} is the easiest way to inquire
|
70
SOURCES/glibc-RHEL-46724.patch
Normal file
70
SOURCES/glibc-RHEL-46724.patch
Normal file
@ -0,0 +1,70 @@
|
||||
commit 7fe1fde499507126f7de10ebf12fecaf77ae6602
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Mon Oct 28 22:22:26 2024 +0000
|
||||
|
||||
Document further requirement on mixing streams / file descriptors
|
||||
|
||||
The gilbc manual has some documentation in llio.texi of requirements
|
||||
for moving between I/O on FILE * streams and file descriptors on the
|
||||
same open file description.
|
||||
|
||||
The documentation of what must be done on a FILE * stream to move from
|
||||
it to either a file descriptor or another FILE * for the same open
|
||||
file description seems to match POSIX. However, there is an
|
||||
additional requirement in POSIX on the *second* of the two handles
|
||||
being moved between, which is not mentioned in the glibc manual: "If
|
||||
any previous active handle has been used by a function that explicitly
|
||||
changed the file offset, except as required above for the first
|
||||
handle, the application shall perform an lseek() or fseek() (as
|
||||
appropriate to the type of handle) to an appropriate location.".
|
||||
|
||||
Document this requirement on seeking in the glibc manual, limited to
|
||||
the case that seems relevant to glibc (the new channel is a previously
|
||||
active stream, on which the seeking previously occurred). Note that
|
||||
I'm not sure what the "except as required above for the first handle"
|
||||
is meant to be about, so I haven't documented anything for it. As far
|
||||
as I can tell, nothing specified for moving from the first handle
|
||||
actually list calling a seek function as one of the steps to be done.
|
||||
(Current POSIX doesn't seem to have any relevant rationale for this
|
||||
section. The rationale in the 1996 edition says "In requiring the
|
||||
seek to an appropriate location for the new handle, the application is
|
||||
required to know what it is doing if it is passing streams with seeks
|
||||
involved. If the required seek is not done, the results are undefined
|
||||
(and in fact the program probably will not work on many common
|
||||
implementations)." - which also doesn't help in understanding the
|
||||
purpose of "except as required above for the first handle".)
|
||||
|
||||
Tested with "make info" and "make pdf".
|
||||
|
||||
diff --git a/manual/llio.texi b/manual/llio.texi
|
||||
index 12194273801adc18..0f84a593ee92b31f 100644
|
||||
--- a/manual/llio.texi
|
||||
+++ b/manual/llio.texi
|
||||
@@ -1097,6 +1097,27 @@ streams persist in other processes, their file positions become
|
||||
undefined as a result. To prevent this, you must clean up the streams
|
||||
before destroying them.
|
||||
|
||||
+In addition to cleaning up a stream before doing I/O using another
|
||||
+linked channel, additional precautions are needed to ensure a
|
||||
+well-defined file position indicator in some cases. If both the
|
||||
+following conditions hold, you must set the file position indicator on
|
||||
+the new channel (a stream) using a function such as @code{fseek}.
|
||||
+
|
||||
+@itemize @bullet
|
||||
+@item
|
||||
+The new linked channel is a stream that was previously active.
|
||||
+
|
||||
+@item
|
||||
+The file position indicator was previously set on that channel (while
|
||||
+it was previously active) with a function such as @code{fseek}.
|
||||
+@end itemize
|
||||
+
|
||||
+POSIX requires such precautions in more cases: if either the old or
|
||||
+the new linked channel is a stream (whether or not previously active)
|
||||
+and the file position indicator was previously set on any channel
|
||||
+linked to those channels with a function such as @code{fseek} or
|
||||
+@code{lseek}.
|
||||
+
|
||||
@node Independent Channels
|
||||
@subsection Independent Channels
|
||||
@cindex independent channels
|
2531
SOURCES/glibc-RHEL-46725-1.patch
Normal file
2531
SOURCES/glibc-RHEL-46725-1.patch
Normal file
File diff suppressed because it is too large
Load Diff
428
SOURCES/glibc-RHEL-46725-10.patch
Normal file
428
SOURCES/glibc-RHEL-46725-10.patch
Normal file
@ -0,0 +1,428 @@
|
||||
commit 6018ba05c01b1e17d77742a123e8c443f8fc713c
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vfprintf output specifiers
|
||||
|
||||
Wire vfprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 437acef216b04237..dc825f415af283ad 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn v vas vd
|
||||
+xprintf-funcs := p as d f s sn v vas vd vf
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-vf-c.c b/stdio-common/tst-printf-format-vf-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b31b551327bb4ebe
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-char.c b/stdio-common/tst-printf-format-vf-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..daa2886adb9f1636
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-double.c b/stdio-common/tst-printf-format-vf-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..63ec8c0cae6c272e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-int.c b/stdio-common/tst-printf-format-vf-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e687099b1052d040
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-ldouble.c b/stdio-common/tst-printf-format-vf-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..801e359dab8ca159
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-llong.c b/stdio-common/tst-printf-format-vf-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a1b9ae340c4aa5ff
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-long.c b/stdio-common/tst-printf-format-vf-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7afc127b844d1e10
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-s.c b/stdio-common/tst-printf-format-vf-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6faa6d0dfe4b4132
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-short.c b/stdio-common/tst-printf-format-vf-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c3d17ca501974f83
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-uchar.c b/stdio-common/tst-printf-format-vf-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..643438c693abf51f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-uint.c b/stdio-common/tst-printf-format-vf-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..844192cc9ccf5db8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-ullong.c b/stdio-common/tst-printf-format-vf-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ab58abd7f8c4e267
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-ulong.c b/stdio-common/tst-printf-format-vf-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e76251f9d0e3337f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf-ushort.c b/stdio-common/tst-printf-format-vf-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..bf78a919a6599054
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vfprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vf.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vf.h b/stdio-common/tst-printf-format-vf.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..f824364f4c041ab8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vf.h
|
||||
@@ -0,0 +1,34 @@
|
||||
+/* Test feature wrapper for formatted 'vfprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vfprintf (stdout, fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ perror ("vfprintf");
|
||||
+ return result;
|
||||
+}
|
458
SOURCES/glibc-RHEL-46725-11.patch
Normal file
458
SOURCES/glibc-RHEL-46725-11.patch
Normal file
@ -0,0 +1,458 @@
|
||||
commit ac72dd90905e1693c108c9f36f0c7e79d6ad5501
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vsprintf output specifiers
|
||||
|
||||
Wire vsprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index dc825f415af283ad..f0c414427ab109c7 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn v vas vd vf
|
||||
+xprintf-funcs := p as d f s sn v vas vd vf vs
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-vs-c.c b/stdio-common/tst-printf-format-vs-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..72bcb5f04957c4ef
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-char.c b/stdio-common/tst-printf-format-vs-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..30135cf1be1616ac
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-double.c b/stdio-common/tst-printf-format-vs-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..56290d383ebc33c8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-int.c b/stdio-common/tst-printf-format-vs-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f954e1f4f8277c64
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-ldouble.c b/stdio-common/tst-printf-format-vs-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3088e42813abd537
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-llong.c b/stdio-common/tst-printf-format-vs-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..348ec2c3d73b8f88
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-long.c b/stdio-common/tst-printf-format-vs-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..874e3ba479eda8fb
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-s.c b/stdio-common/tst-printf-format-vs-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..051f1b79bf2cb028
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-short.c b/stdio-common/tst-printf-format-vs-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..36595a82b445e8a3
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-uchar.c b/stdio-common/tst-printf-format-vs-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8e35614110bd7d57
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-uint.c b/stdio-common/tst-printf-format-vs-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4a13d6c409ad4245
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-ullong.c b/stdio-common/tst-printf-format-vs-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..313dfaf02bda3059
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-ulong.c b/stdio-common/tst-printf-format-vs-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5ab7e2e7fe9b237a
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs-ushort.c b/stdio-common/tst-printf-format-vs-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a4af138a2f8485ab
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vs.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vs.h b/stdio-common/tst-printf-format-vs.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..e00e1b085bc58150
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vs.h
|
||||
@@ -0,0 +1,64 @@
|
||||
+/* Test feature wrapper for formatted 'vsprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/next_to_fault.h>
|
||||
+
|
||||
+#define SPRINTF_BUFFER_SIZE 65536
|
||||
+
|
||||
+static struct support_next_to_fault ntf;
|
||||
+
|
||||
+#define PREPARE printf_under_test_init
|
||||
+static void
|
||||
+printf_under_test_init (int argc, char **argv)
|
||||
+{
|
||||
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((destructor))
|
||||
+printf_under_test_fini (void)
|
||||
+{
|
||||
+ support_next_to_fault_free (&ntf);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ char *str = ntf.buffer;
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vsprintf (str, fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ perror ("vsprintf");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
|
||||
+ {
|
||||
+ perror ("fwrite");
|
||||
+ result = -1;
|
||||
+ }
|
||||
+out:
|
||||
+ return result;
|
||||
+}
|
458
SOURCES/glibc-RHEL-46725-12.patch
Normal file
458
SOURCES/glibc-RHEL-46725-12.patch
Normal file
@ -0,0 +1,458 @@
|
||||
commit 11a2169e4066e6b848f1e6e4c31ec4e2210cecd8
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vsnprintf output specifiers
|
||||
|
||||
Wire vsnprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index f0c414427ab109c7..905a5a510f1e5bc6 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn v vas vd vf vs
|
||||
+xprintf-funcs := p as d f s sn v vas vd vf vs vsn
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-c.c b/stdio-common/tst-printf-format-vsn-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..47c8a0f5dfbddb49
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-char.c b/stdio-common/tst-printf-format-vsn-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..48d4393a46d80e33
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-double.c b/stdio-common/tst-printf-format-vsn-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..06c1003fb5fde4b0
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-int.c b/stdio-common/tst-printf-format-vsn-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2aae92616f2f6007
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-ldouble.c b/stdio-common/tst-printf-format-vsn-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0b5aafb124307526
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-llong.c b/stdio-common/tst-printf-format-vsn-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8e79b8384f6858c6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-long.c b/stdio-common/tst-printf-format-vsn-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e94f7dec23ece2ca
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-s.c b/stdio-common/tst-printf-format-vsn-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..efd8a4c23f5f42e6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-short.c b/stdio-common/tst-printf-format-vsn-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3d375b59e7a990f0
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-uchar.c b/stdio-common/tst-printf-format-vsn-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6d0f396481d3e2d6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-uint.c b/stdio-common/tst-printf-format-vsn-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b637f7bdb11f7913
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-ullong.c b/stdio-common/tst-printf-format-vsn-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d2442715f087acaf
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-ulong.c b/stdio-common/tst-printf-format-vsn-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..67417d174043a605
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn-ushort.c b/stdio-common/tst-printf-format-vsn-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..396ea43ae7067c86
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vsnprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vsn.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vsn.h b/stdio-common/tst-printf-format-vsn.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..4f25f1af767dc221
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vsn.h
|
||||
@@ -0,0 +1,64 @@
|
||||
+/* Test feature wrapper for formatted 'vsnprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/next_to_fault.h>
|
||||
+
|
||||
+#define SPRINTF_BUFFER_SIZE 65536
|
||||
+
|
||||
+static struct support_next_to_fault ntf;
|
||||
+
|
||||
+#define PREPARE printf_under_test_init
|
||||
+static void
|
||||
+printf_under_test_init (int argc, char **argv)
|
||||
+{
|
||||
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((destructor))
|
||||
+printf_under_test_fini (void)
|
||||
+{
|
||||
+ support_next_to_fault_free (&ntf);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ char *str = ntf.buffer;
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vsnprintf (str, ntf.length, fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ perror ("vsnprintf");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
|
||||
+ {
|
||||
+ perror ("fwrite");
|
||||
+ result = -1;
|
||||
+ }
|
||||
+out:
|
||||
+ return result;
|
||||
+}
|
459
SOURCES/glibc-RHEL-46725-2.patch
Normal file
459
SOURCES/glibc-RHEL-46725-2.patch
Normal file
@ -0,0 +1,459 @@
|
||||
commit b350a60b6ecd77b7ec30c7969de1df8b73642e55
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted asprintf output specifiers
|
||||
|
||||
Wire asprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Owing to mtrace logging of lots of memory allocation calls these tests
|
||||
take a considerable amount of time to complete, except for the character
|
||||
conversion, taking from 00m20s for 'tst-printf-format-as-s --direct s',
|
||||
through 01m10s and 03m53s for 'tst-printf-format-as-char --direct i' and
|
||||
'tst-printf-format-as-double --direct f' respectively, to 19m24s for
|
||||
'tst-printf-format-as-ldouble --direct f', all in standalone execution
|
||||
from NFS on a RISC-V FU740@1.2GHz system and with output redirected over
|
||||
100Mbps network via SSH. It is with the skeleton's stub implementation
|
||||
of dladdr(3); execution times with regular dladdr(3) are up to over
|
||||
twice longer.
|
||||
|
||||
Set timeouts for the tests accordingly then, with a global default for
|
||||
all the asprintf tests, and then individual higher settings for double
|
||||
and long double tests each.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 0a45dcb4f45c0a5d..da279a969f7a8785 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p
|
||||
+xprintf-funcs := p as
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-as-c.c b/stdio-common/tst-printf-format-as-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9eaf7aec73201b4d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-char.c b/stdio-common/tst-printf-format-as-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d9266d5760fb8808
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-double.c b/stdio-common/tst-printf-format-as-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..370ce8c11bd94fe8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-double.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Test for formatted 'asprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define TIMEOUT (DEFAULT_TIMEOUT * 32)
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-int.c b/stdio-common/tst-printf-format-as-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e6e10a9769f079a4
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-ldouble.c b/stdio-common/tst-printf-format-as-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e7f72208cec76078
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-ldouble.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Test for formatted 'asprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define TIMEOUT (DEFAULT_TIMEOUT * 128)
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-llong.c b/stdio-common/tst-printf-format-as-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..beaad73c235c344e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-long.c b/stdio-common/tst-printf-format-as-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7d968a873c3b5e29
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-s.c b/stdio-common/tst-printf-format-as-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..baa883d5316cbf2f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-short.c b/stdio-common/tst-printf-format-as-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8d0b078815f299a6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-uchar.c b/stdio-common/tst-printf-format-as-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8e46254a2f32b457
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-uint.c b/stdio-common/tst-printf-format-as-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8cf38d71a2f53358
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-ullong.c b/stdio-common/tst-printf-format-as-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..30b31ed8f7b36ae1
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-ulong.c b/stdio-common/tst-printf-format-as-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9b108aa2b5132686
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as-ushort.c b/stdio-common/tst-printf-format-as-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..44b912fc38c46d28
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'asprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-as.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-as.h b/stdio-common/tst-printf-format-as.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..c30d2e2c42822f24
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-as.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/* Test feature wrapper for formatted 'asprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#define printf_under_test(...) \
|
||||
+({ \
|
||||
+ __label__ out; \
|
||||
+ int result; \
|
||||
+ char *str; \
|
||||
+ \
|
||||
+ result = asprintf (&str, __VA_ARGS__); \
|
||||
+ if (result < 0) \
|
||||
+ { \
|
||||
+ perror ("asprintf"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
|
||||
+ { \
|
||||
+ perror ("fwrite"); \
|
||||
+ result = -1; \
|
||||
+ } \
|
||||
+ free (str); \
|
||||
+out: \
|
||||
+ result; \
|
||||
+})
|
||||
+
|
||||
+#ifndef TIMEOUT
|
||||
+# define TIMEOUT (DEFAULT_TIMEOUT * 12)
|
||||
+#endif
|
452
SOURCES/glibc-RHEL-46725-3.patch
Normal file
452
SOURCES/glibc-RHEL-46725-3.patch
Normal file
@ -0,0 +1,452 @@
|
||||
commit b3e8a756ad569fd31181b74b3729d29df3eb55f3
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted dprintf output specifiers
|
||||
|
||||
Wire dprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index da279a969f7a8785..2bc830597085678a 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as
|
||||
+xprintf-funcs := p as d
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-d-c.c b/stdio-common/tst-printf-format-d-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..61fd06654d2a957e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-char.c b/stdio-common/tst-printf-format-d-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..baa6e1683e923841
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-double.c b/stdio-common/tst-printf-format-d-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e432a9570d46e776
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-int.c b/stdio-common/tst-printf-format-d-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6d59b23517b54a85
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-ldouble.c b/stdio-common/tst-printf-format-d-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..67a2bae1bc4e0301
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-llong.c b/stdio-common/tst-printf-format-d-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..950a2b84b9fc1abc
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-long.c b/stdio-common/tst-printf-format-d-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4fabb41b0b013011
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-s.c b/stdio-common/tst-printf-format-d-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1ef896e6e7d146bc
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-short.c b/stdio-common/tst-printf-format-d-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..17767bb30d2f0d3e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-uchar.c b/stdio-common/tst-printf-format-d-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..732479ecab2cdc4e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-uint.c b/stdio-common/tst-printf-format-d-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5b68aec803f653ac
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-ullong.c b/stdio-common/tst-printf-format-d-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0e20a1dccd58e84b
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-ulong.c b/stdio-common/tst-printf-format-d-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..62085ace806b6d33
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d-ushort.c b/stdio-common/tst-printf-format-d-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7d8ef76d60b70e2d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'dprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-d.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-d.h b/stdio-common/tst-printf-format-d.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..af7f26c17bde88ea
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-d.h
|
||||
@@ -0,0 +1,58 @@
|
||||
+/* Test feature wrapper for formatted 'dprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* We need to go through the POSIX-mandated dance to switch between
|
||||
+ handles on an open file description. */
|
||||
+
|
||||
+#define printf_under_test(...) \
|
||||
+({ \
|
||||
+ __label__ out; \
|
||||
+ int result; \
|
||||
+ \
|
||||
+ result = fflush (stdout); \
|
||||
+ if (result == EOF) \
|
||||
+ { \
|
||||
+ perror ("fflush"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ result = lseek (STDOUT_FILENO, 0, SEEK_END); \
|
||||
+ if (result < 0 && errno == ESPIPE) \
|
||||
+ result = 0; \
|
||||
+ if (result < 0) \
|
||||
+ { \
|
||||
+ perror ("lseek"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ result = dprintf (STDOUT_FILENO, __VA_ARGS__); \
|
||||
+ if (result < 0) \
|
||||
+ { \
|
||||
+ perror ("dprintf"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ result = fseek (stdout, 0, SEEK_END); \
|
||||
+ if (result < 0 && errno == ESPIPE) \
|
||||
+ result = 0; \
|
||||
+ if (result < 0) \
|
||||
+ perror ("fseek"); \
|
||||
+out: \
|
||||
+ result; \
|
||||
+})
|
423
SOURCES/glibc-RHEL-46725-4.patch
Normal file
423
SOURCES/glibc-RHEL-46725-4.patch
Normal file
@ -0,0 +1,423 @@
|
||||
commit 1dc5cdc3da19e10d47e50a5ea2ea3ce62ee2fa82
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted fprintf output specifiers
|
||||
|
||||
Wire fprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 2bc830597085678a..3a812073784fa3b6 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d
|
||||
+xprintf-funcs := p as d f
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-f-c.c b/stdio-common/tst-printf-format-f-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1db9e2b5f3bb2d32
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-char.c b/stdio-common/tst-printf-format-f-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a492f318620bc82e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-double.c b/stdio-common/tst-printf-format-f-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..906ef0b90b9e7d1d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-int.c b/stdio-common/tst-printf-format-f-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..92dc0c919771ae26
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-ldouble.c b/stdio-common/tst-printf-format-f-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0a0c88d64c873061
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-llong.c b/stdio-common/tst-printf-format-f-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ceb8d035faaf0a12
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-long.c b/stdio-common/tst-printf-format-f-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a4a5dca5ebd7b3a4
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-s.c b/stdio-common/tst-printf-format-f-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..da0e0f8bacab6992
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-short.c b/stdio-common/tst-printf-format-f-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3abd134d0aeeef87
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-uchar.c b/stdio-common/tst-printf-format-f-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f104cde37b322b60
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-uint.c b/stdio-common/tst-printf-format-f-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0e1fdb4b367032a2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-ullong.c b/stdio-common/tst-printf-format-f-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b4669fcbb7dd3282
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-ulong.c b/stdio-common/tst-printf-format-f-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3f4f900362a153b5
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f-ushort.c b/stdio-common/tst-printf-format-f-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d49c2371403e20a6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'fprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-f.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-f.h b/stdio-common/tst-printf-format-f.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..efb3283a032f44a7
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-f.h
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* Test feature wrapper for formatted 'fprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#define printf_under_test(...) \
|
||||
+({ \
|
||||
+ int result; \
|
||||
+ \
|
||||
+ result = fprintf (stdout, __VA_ARGS__); \
|
||||
+ if (result < 0) \
|
||||
+ perror ("fprintf"); \
|
||||
+ result; \
|
||||
+})
|
454
SOURCES/glibc-RHEL-46725-5.patch
Normal file
454
SOURCES/glibc-RHEL-46725-5.patch
Normal file
@ -0,0 +1,454 @@
|
||||
commit c683ac8520e8064e7be3a22922d80849271290ac
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted sprintf output specifiers
|
||||
|
||||
Wire sprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 3a812073784fa3b6..7522cd76cc26a3a5 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f
|
||||
+xprintf-funcs := p as d f s
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-s-c.c b/stdio-common/tst-printf-format-s-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..87dad077b9c05216
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-char.c b/stdio-common/tst-printf-format-s-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f67ac94a5dd70cf4
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-double.c b/stdio-common/tst-printf-format-s-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..16186b5dc55eabaf
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-int.c b/stdio-common/tst-printf-format-s-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2ed7b2df471cd96d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-ldouble.c b/stdio-common/tst-printf-format-s-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0362cc50f78ffdfa
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-llong.c b/stdio-common/tst-printf-format-s-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b49f84998a7e7ca2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-long.c b/stdio-common/tst-printf-format-s-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..49224d7f29d7e65c
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-s.c b/stdio-common/tst-printf-format-s-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3a400f8907895db0
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-short.c b/stdio-common/tst-printf-format-s-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c98a808cff51c52a
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-uchar.c b/stdio-common/tst-printf-format-s-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..befc36894975a9a1
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-uint.c b/stdio-common/tst-printf-format-s-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f3a4c49632a3be07
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-ullong.c b/stdio-common/tst-printf-format-s-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4ce559037921e01f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-ulong.c b/stdio-common/tst-printf-format-s-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..81f9eea893c194d2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s-ushort.c b/stdio-common/tst-printf-format-s-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4b1cca6e6cf6b342
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'sprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-s.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-s.h b/stdio-common/tst-printf-format-s.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..7d1e72cffb7b20fb
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-s.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/* Test feature wrapper for formatted 'sprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/next_to_fault.h>
|
||||
+
|
||||
+#define SPRINTF_BUFFER_SIZE 65536
|
||||
+
|
||||
+static struct support_next_to_fault ntf;
|
||||
+
|
||||
+#define PREPARE printf_under_test_init
|
||||
+static void
|
||||
+printf_under_test_init (int argc, char **argv)
|
||||
+{
|
||||
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((destructor))
|
||||
+printf_under_test_fini (void)
|
||||
+{
|
||||
+ support_next_to_fault_free (&ntf);
|
||||
+}
|
||||
+
|
||||
+#define printf_under_test(...) \
|
||||
+({ \
|
||||
+ __label__ out; \
|
||||
+ char *str = ntf.buffer; \
|
||||
+ int result; \
|
||||
+ \
|
||||
+ result = sprintf (str, __VA_ARGS__); \
|
||||
+ if (result < 0) \
|
||||
+ { \
|
||||
+ perror ("sprintf"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
|
||||
+ { \
|
||||
+ perror ("fwrite"); \
|
||||
+ result = -1; \
|
||||
+ } \
|
||||
+out: \
|
||||
+ result; \
|
||||
+})
|
454
SOURCES/glibc-RHEL-46725-6.patch
Normal file
454
SOURCES/glibc-RHEL-46725-6.patch
Normal file
@ -0,0 +1,454 @@
|
||||
commit 0b6379cb98590c28088f017ddcc0edb8ad7d0131
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted snprintf output specifiers
|
||||
|
||||
Wire snprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 7522cd76cc26a3a5..88b89ce13ffbadc4 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s
|
||||
+xprintf-funcs := p as d f s sn
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-sn-c.c b/stdio-common/tst-printf-format-sn-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..59f51d635bc46d28
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-char.c b/stdio-common/tst-printf-format-sn-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8b682dd2d52f04d2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-double.c b/stdio-common/tst-printf-format-sn-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4719a58d84bda809
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-int.c b/stdio-common/tst-printf-format-sn-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..94c42f246fc8ce49
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-ldouble.c b/stdio-common/tst-printf-format-sn-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..921f3ffe3b79a05d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-llong.c b/stdio-common/tst-printf-format-sn-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..013552791e087d0c
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-long.c b/stdio-common/tst-printf-format-sn-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..58c8912746c1108b
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-s.c b/stdio-common/tst-printf-format-sn-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..aa3f170c14790926
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-short.c b/stdio-common/tst-printf-format-sn-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f7baa1211d16e203
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-uchar.c b/stdio-common/tst-printf-format-sn-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6ae5f121bd76ab9d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-uint.c b/stdio-common/tst-printf-format-sn-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f0a0c3063f89781a
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-ullong.c b/stdio-common/tst-printf-format-sn-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0dc0a50c4f2362a2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-ulong.c b/stdio-common/tst-printf-format-sn-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..23ff5a27d7c25c34
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn-ushort.c b/stdio-common/tst-printf-format-sn-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1c5cffbeb414048e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'snprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-sn.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-sn.h b/stdio-common/tst-printf-format-sn.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..ec2645bf57da8bbb
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-sn.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/* Test feature wrapper for formatted 'snprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/next_to_fault.h>
|
||||
+
|
||||
+#define SPRINTF_BUFFER_SIZE 65536
|
||||
+
|
||||
+static struct support_next_to_fault ntf;
|
||||
+
|
||||
+#define PREPARE printf_under_test_init
|
||||
+static void
|
||||
+printf_under_test_init (int argc, char **argv)
|
||||
+{
|
||||
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
|
||||
+}
|
||||
+
|
||||
+static void __attribute__ ((destructor))
|
||||
+printf_under_test_fini (void)
|
||||
+{
|
||||
+ support_next_to_fault_free (&ntf);
|
||||
+}
|
||||
+
|
||||
+#define printf_under_test(...) \
|
||||
+({ \
|
||||
+ __label__ out; \
|
||||
+ char *str = ntf.buffer; \
|
||||
+ int result; \
|
||||
+ \
|
||||
+ result = snprintf (str, ntf.length, __VA_ARGS__); \
|
||||
+ if (result < 0) \
|
||||
+ { \
|
||||
+ perror ("snprintf"); \
|
||||
+ goto out; \
|
||||
+ } \
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
|
||||
+ { \
|
||||
+ perror ("fwrite"); \
|
||||
+ result = -1; \
|
||||
+ } \
|
||||
+out: \
|
||||
+ result; \
|
||||
+})
|
428
SOURCES/glibc-RHEL-46725-7.patch
Normal file
428
SOURCES/glibc-RHEL-46725-7.patch
Normal file
@ -0,0 +1,428 @@
|
||||
commit bad554d9b4f10988eb7fdb814fbaa5e89416d781
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vprintf output specifiers
|
||||
|
||||
Wire vprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 88b89ce13ffbadc4..fd34891ea439c684 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn
|
||||
+xprintf-funcs := p as d f s sn v
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-v-c.c b/stdio-common/tst-printf-format-v-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..94aa3042aaee6d97
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-char.c b/stdio-common/tst-printf-format-v-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c813d81e53956295
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-double.c b/stdio-common/tst-printf-format-v-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..90cc1704eb3da2f3
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-int.c b/stdio-common/tst-printf-format-v-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6529425b263975c8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-ldouble.c b/stdio-common/tst-printf-format-v-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..813f4a510dc833cc
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-llong.c b/stdio-common/tst-printf-format-v-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..270ad08bf5e948fd
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-long.c b/stdio-common/tst-printf-format-v-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2f5f653fecb25040
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-s.c b/stdio-common/tst-printf-format-v-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ebc253b3e83291f2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-short.c b/stdio-common/tst-printf-format-v-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..92a59d9fd3972f1e
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-uchar.c b/stdio-common/tst-printf-format-v-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..045ffd2864f8158f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-uint.c b/stdio-common/tst-printf-format-v-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..17b1ce3aa7780209
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-ullong.c b/stdio-common/tst-printf-format-v-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..590b04f339e01cf6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-ulong.c b/stdio-common/tst-printf-format-v-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6747677a42b38e37
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v-ushort.c b/stdio-common/tst-printf-format-v-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1e782715627f7b77
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-v.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-v.h b/stdio-common/tst-printf-format-v.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..711b290b59df8781
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-v.h
|
||||
@@ -0,0 +1,34 @@
|
||||
+/* Test feature wrapper for formatted 'vprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vprintf (fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ perror ("vprintf");
|
||||
+ return result;
|
||||
+}
|
454
SOURCES/glibc-RHEL-46725-8.patch
Normal file
454
SOURCES/glibc-RHEL-46725-8.patch
Normal file
@ -0,0 +1,454 @@
|
||||
commit 349670f8093d920d4d683472c88029f6901f7ae7
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vasprintf output specifiers
|
||||
|
||||
Wire vasprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Owing to mtrace logging these tests take amounts of time to complete
|
||||
similar to those of corresponding asprintf tests, so set timeouts for
|
||||
the tests accordingly, with a global default for all the vasprintf
|
||||
tests, and then individual higher settings for double and long double
|
||||
tests each.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index fd34891ea439c684..2675d7741fe496d4 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn v
|
||||
+xprintf-funcs := p as d f s sn v vas
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-vas-c.c b/stdio-common/tst-printf-format-vas-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f8cf814c8c3bc293
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-char.c b/stdio-common/tst-printf-format-vas-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..39c6e73977f3f32f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-double.c b/stdio-common/tst-printf-format-vas-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..25a21bb0adc2726f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-double.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Test for formatted 'vasprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define TIMEOUT (DEFAULT_TIMEOUT * 32)
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-int.c b/stdio-common/tst-printf-format-vas-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9cd70c8fcbae1c03
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-ldouble.c b/stdio-common/tst-printf-format-vas-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..60c3933fab1b9216
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-ldouble.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Test for formatted 'vasprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#define TIMEOUT (DEFAULT_TIMEOUT * 128)
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-llong.c b/stdio-common/tst-printf-format-vas-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5d5322b8b9dfe0a4
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-long.c b/stdio-common/tst-printf-format-vas-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d9651053f8f14dcd
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-s.c b/stdio-common/tst-printf-format-vas-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6d74ab83e3038b44
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-short.c b/stdio-common/tst-printf-format-vas-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a6d76a97055fbb89
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-uchar.c b/stdio-common/tst-printf-format-vas-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c3dee11b7d8092d9
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-uint.c b/stdio-common/tst-printf-format-vas-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e56e89374db69c3f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-ullong.c b/stdio-common/tst-printf-format-vas-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..05691bc3181c6d18
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-ulong.c b/stdio-common/tst-printf-format-vas-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..767d9cb6a6ac64a2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas-ushort.c b/stdio-common/tst-printf-format-vas-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..284d79f75364504f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vasprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vas.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vas.h b/stdio-common/tst-printf-format-vas.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..3e38e729ec97ceed
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vas.h
|
||||
@@ -0,0 +1,50 @@
|
||||
+/* Test feature wrapper for formatted 'vasprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+ char *str;
|
||||
+
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vasprintf (&str, fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ perror ("vasprintf");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
|
||||
+ {
|
||||
+ perror ("fwrite");
|
||||
+ result = -1;
|
||||
+ }
|
||||
+ free (str);
|
||||
+out:
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#ifndef TIMEOUT
|
||||
+# define TIMEOUT (DEFAULT_TIMEOUT * 12)
|
||||
+#endif
|
456
SOURCES/glibc-RHEL-46725-9.patch
Normal file
456
SOURCES/glibc-RHEL-46725-9.patch
Normal file
@ -0,0 +1,456 @@
|
||||
commit fae4eacae75e4f2767998aca703d6efaae2a747f
|
||||
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||
Date: Thu Nov 7 06:14:24 2024 +0000
|
||||
|
||||
stdio-common: Add tests for formatted vdprintf output specifiers
|
||||
|
||||
Wire vdprintf into test infrastructure for formatted printf output
|
||||
specifiers.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 2675d7741fe496d4..437acef216b04237 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -23,7 +23,7 @@ subdir := stdio-common
|
||||
include ../Makeconfig
|
||||
|
||||
# List of markers for printf family function tests.
|
||||
-xprintf-funcs := p as d f s sn v vas
|
||||
+xprintf-funcs := p as d f s sn v vas vd
|
||||
|
||||
# List of data types and formats for individual per-conversion printf tests.
|
||||
fmt-convs := double ldouble
|
||||
diff --git a/stdio-common/tst-printf-format-vd-c.c b/stdio-common/tst-printf-format-vd-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..209b1784896a0bfd
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-c.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for the 'c' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-c.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-char.c b/stdio-common/tst-printf-format-vd-char.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8286b6d5b227e83a
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-char.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for signed char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-char.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-double.c b/stdio-common/tst-printf-format-vd-double.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e89a2ca5983697ce
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-double.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-double.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-int.c b/stdio-common/tst-printf-format-vd-int.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..598a888b1c937361
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-int.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-int.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-ldouble.c b/stdio-common/tst-printf-format-vd-ldouble.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d3ada6ff0bcdd9c1
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-ldouble.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for long double conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-ldouble.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-llong.c b/stdio-common/tst-printf-format-vd-llong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ea6ea7b2157dc0c9
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-llong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-llong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-long.c b/stdio-common/tst-printf-format-vd-long.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4ee1cdacffb4fe77
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-long.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-long.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-s.c b/stdio-common/tst-printf-format-vd-s.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..df7cf9a6fbf04c9b
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-s.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for the 's' conversion.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-s.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-short.c b/stdio-common/tst-printf-format-vd-short.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..87128c8303b57cd8
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-short.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-short.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-uchar.c b/stdio-common/tst-printf-format-vd-uchar.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..90dea719471dcb30
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-uchar.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for unsigned char conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-uchar.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-uint.c b/stdio-common/tst-printf-format-vd-uint.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..feb95dc018ee20fe
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-uint.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for unsigned int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-uint.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-ullong.c b/stdio-common/tst-printf-format-vd-ullong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8f62fb0aeeaca3a3
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-ullong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for unsigned long long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-ullong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-ulong.c b/stdio-common/tst-printf-format-vd-ulong.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..59b2015cd33aaede
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-ulong.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for unsigned long int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-ulong.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd-ushort.c b/stdio-common/tst-printf-format-vd-ushort.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5d096502d9f44959
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd-ushort.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* Test for formatted 'vdprintf' output for unsigned short int conversions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "tst-printf-format-vd.h"
|
||||
+#include "tst-printf-format-skeleton-ushort.c"
|
||||
diff --git a/stdio-common/tst-printf-format-vd.h b/stdio-common/tst-printf-format-vd.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..d721edadc6f7786b
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-printf-format-vd.h
|
||||
@@ -0,0 +1,62 @@
|
||||
+/* Test feature wrapper for formatted 'vdprintf' output.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* We need to go through the POSIX-mandated dance to switch between
|
||||
+ handles on an open file description. */
|
||||
+
|
||||
+static int
|
||||
+printf_under_test (const char *restrict fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ int result;
|
||||
+
|
||||
+ result = fflush (stdout);
|
||||
+ if (result == EOF)
|
||||
+ {
|
||||
+ perror ("fflush");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ result = lseek (STDOUT_FILENO, 0, SEEK_END);
|
||||
+ if (result < 0 && errno == ESPIPE)
|
||||
+ result = 0;
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ perror ("lseek");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ va_start (ap, fmt);
|
||||
+ result = vdprintf (STDOUT_FILENO, fmt, ap);
|
||||
+ va_end (ap);
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ perror ("vdprintf");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ result = fseek (stdout, 0, SEEK_END);
|
||||
+ if (result < 0 && errno == ESPIPE)
|
||||
+ result = 0;
|
||||
+ if (result < 0)
|
||||
+ perror ("fseek");
|
||||
+out:
|
||||
+ return result;
|
||||
+}
|
287
SOURCES/glibc-RHEL-46728.patch
Normal file
287
SOURCES/glibc-RHEL-46728.patch
Normal file
@ -0,0 +1,287 @@
|
||||
From 4945ffc88a8ad49280bae64165683ddfd12b2390 Mon Sep 17 00:00:00 2001
|
||||
From: DJ Delorie <dj@redhat.com>
|
||||
Date: Wed, 7 Aug 2024 16:55:16 -0400
|
||||
Subject: fgets: more tests
|
||||
|
||||
Add more tests for unusual situations fgets() might see:
|
||||
|
||||
* zero size file
|
||||
* zero sized buffer
|
||||
* NULL buffer
|
||||
* NUL data
|
||||
* writable stream
|
||||
* closed stream
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 89871d0de8..03d597f8e6 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -209,6 +209,7 @@ tests := \
|
||||
tst-fdopen \
|
||||
tst-ferror \
|
||||
tst-fgets \
|
||||
+ tst-fgets2 \
|
||||
tst-fileno \
|
||||
tst-fmemopen \
|
||||
tst-fmemopen2 \
|
||||
diff --git a/stdio-common/tst-fgets2.c b/stdio-common/tst-fgets2.c
|
||||
new file mode 100644
|
||||
index 0000000000..5b78447ea9
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-fgets2.c
|
||||
@@ -0,0 +1,253 @@
|
||||
+/* Test for additional fgets error handling.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <libc-diag.h>
|
||||
+#include <stdio.h>
|
||||
+#include <error.h>
|
||||
+#include <errno.h>
|
||||
+#include <limits.h>
|
||||
+#include <mcheck.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+#include <support/support.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+/* This avoids compiler warnings about passing NULL where a valid
|
||||
+ pointer is expected. */
|
||||
+static void *volatile null = NULL;
|
||||
+
|
||||
+/* Implementation of our FILE stream backend. */
|
||||
+
|
||||
+static int bytes_read;
|
||||
+static int cookie_valid = 0;
|
||||
+struct Cookie {
|
||||
+ const char *buffer;
|
||||
+ int bufptr;
|
||||
+ int bufsz;
|
||||
+};
|
||||
+
|
||||
+#define VALIDATE_COOKIE() if (! cookie_valid) { \
|
||||
+ FAIL ("call to %s after file closed", __FUNCTION__); \
|
||||
+ return -1; \
|
||||
+ }
|
||||
+
|
||||
+static ssize_t
|
||||
+io_read (void *vcookie, char *buf, size_t size)
|
||||
+{
|
||||
+ struct Cookie *cookie = (struct Cookie *) vcookie;
|
||||
+
|
||||
+ VALIDATE_COOKIE ();
|
||||
+
|
||||
+ if (size > cookie->bufsz - cookie->bufptr)
|
||||
+ size = cookie->bufsz - cookie->bufptr;
|
||||
+
|
||||
+ memcpy (buf, cookie->buffer + cookie->bufptr, size);
|
||||
+ cookie->bufptr += size;
|
||||
+ bytes_read += size;
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+io_write (void *vcookie, const char *buf, size_t size)
|
||||
+{
|
||||
+ VALIDATE_COOKIE ();
|
||||
+ FAIL_EXIT1 ("io_write called");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+io_seek (void *vcookie, off64_t *position, int whence)
|
||||
+{
|
||||
+ VALIDATE_COOKIE ();
|
||||
+ FAIL_EXIT1 ("io_seek called");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+io_clean (void *vcookie)
|
||||
+{
|
||||
+ struct Cookie *cookie = (struct Cookie *) vcookie;
|
||||
+
|
||||
+ VALIDATE_COOKIE ();
|
||||
+
|
||||
+ cookie->buffer = NULL;
|
||||
+ cookie->bufsz = 0;
|
||||
+ cookie->bufptr = 0;
|
||||
+
|
||||
+ cookie_valid = 0;
|
||||
+ free (cookie);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+cookie_io_functions_t io_funcs = {
|
||||
+ .read = io_read,
|
||||
+ .write = io_write,
|
||||
+ .seek = io_seek,
|
||||
+ .close = io_clean
|
||||
+};
|
||||
+
|
||||
+FILE *
|
||||
+io_open (const char *buffer, int buflen, const char *mode, void **vcookie)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ struct Cookie *cookie;
|
||||
+
|
||||
+ cookie = (struct Cookie *) xcalloc (1, sizeof (struct Cookie));
|
||||
+ *vcookie = cookie;
|
||||
+ cookie_valid = 1;
|
||||
+
|
||||
+ cookie->buffer = buffer;
|
||||
+ cookie->bufsz = buflen;
|
||||
+ bytes_read = 0;
|
||||
+
|
||||
+ f = fopencookie (cookie, mode, io_funcs);
|
||||
+ if (f == NULL)
|
||||
+ FAIL_EXIT1 ("fopencookie failed");
|
||||
+
|
||||
+ clearerr (f);
|
||||
+ return f;
|
||||
+}
|
||||
+
|
||||
+/* The test cases. */
|
||||
+
|
||||
+#define my_open(s,l,m) io_open (s, l, m, (void *) &cookie)
|
||||
+
|
||||
+#define TEST_COMPARE_0x11(buf, len) \
|
||||
+ TEST_COMPARE_BLOB (buf + (len), sizeof (buf) - (len), \
|
||||
+ buf2, sizeof (buf) - (len));
|
||||
+
|
||||
+#define check_flags(f, expected_eof, expected_err) \
|
||||
+ { \
|
||||
+ if (expected_eof) \
|
||||
+ TEST_VERIFY (feof (f) != 0); \
|
||||
+ else \
|
||||
+ TEST_VERIFY (feof (f) == 0); \
|
||||
+ if (expected_err) \
|
||||
+ TEST_VERIFY (ferror (f) != 0); \
|
||||
+ else \
|
||||
+ TEST_VERIFY (ferror (f) == 0); \
|
||||
+ }
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ struct Cookie *cookie;
|
||||
+ char buf [10];
|
||||
+ char buf2 [10];
|
||||
+ char *returned_string;
|
||||
+
|
||||
+ memset (buf2, 0x11, sizeof (buf2));
|
||||
+
|
||||
+ printf ("testing base operation...\n");
|
||||
+ f = my_open ("hello\n", 6, "r");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == buf);
|
||||
+ TEST_COMPARE_BLOB (buf, bytes_read + 1, "hello\n\0", 7);
|
||||
+ TEST_COMPARE_0x11 (buf, bytes_read + 1);
|
||||
+ check_flags (f, 0, 0);
|
||||
+
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing zero size file...\n");
|
||||
+ f = my_open ("hello\n", 0, "r");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+ check_flags (f, 1, 0);
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing zero size buffer...\n");
|
||||
+ f = my_open ("hello\n", 6, "r");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, 0, f);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+ check_flags (f, 0, 0);
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing NULL buffer with empty stream...\n");
|
||||
+ f = my_open ("hello\n", 0, "r");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+
|
||||
+ returned_string = fgets (null, sizeof (buf), f);
|
||||
+
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+ check_flags (f, 1, 0);
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing embedded NUL...\n");
|
||||
+ f = my_open ("hel\0lo\n", 7, "r");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == buf);
|
||||
+ TEST_COMPARE_BLOB (buf, bytes_read + 1, "hel\0lo\n\0", 8);
|
||||
+ TEST_COMPARE_0x11 (buf, bytes_read + 1);
|
||||
+ check_flags (f, 0, 0);
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing writable stream...\n");
|
||||
+ f = my_open ("hel\0lo\n", 7, "w");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+ check_flags (f, 0, 1);
|
||||
+ fclose (f);
|
||||
+
|
||||
+ printf ("testing closed fd stream...\n");
|
||||
+ int fd = open ("/dev/null", O_RDONLY);
|
||||
+ f = fdopen (fd, "r");
|
||||
+ close (fd);
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+ check_flags (f, 0, 1);
|
||||
+ fclose (f);
|
||||
+
|
||||
+#ifdef IO_DEBUG
|
||||
+ /* These tests only pass if glibc is built with -DIO_DEBUG, but are
|
||||
+ included for reference. */
|
||||
+
|
||||
+ printf ("testing NULL descriptor...\n");
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, null);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+
|
||||
+ printf ("testing closed descriptor...\n");
|
||||
+ f = my_open ("hello\n", 7, "r");
|
||||
+ fclose (f);
|
||||
+ memset (buf, 0x11, sizeof (buf));
|
||||
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
|
||||
+ TEST_VERIFY (returned_string == NULL);
|
||||
+ TEST_VERIFY (bytes_read == 0);
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
171
SOURCES/glibc-RHEL-46733-1.patch
Normal file
171
SOURCES/glibc-RHEL-46733-1.patch
Normal file
@ -0,0 +1,171 @@
|
||||
Partial backport (libio/Makefile, stdio-common/Makefile only) of:
|
||||
|
||||
commit a7fe3e805d2ee128ac5f43b2a24201726d41cc04
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Wed Jun 19 11:48:05 2024 -0400
|
||||
|
||||
Fix conditionals on mtrace-based tests (bug 31892)
|
||||
|
||||
The conditionals for several mtrace-based tests in catgets, elf, libio,
|
||||
malloc, misc, nptl, posix, and stdio-common were incorrect leading to
|
||||
test failures when bootstrapping glibc without perl.
|
||||
|
||||
The correct conditional for mtrace-based tests requires three checks:
|
||||
first checking for run-built-tests, then build-shared, and lastly that
|
||||
PERL is not equal to "no" (missing perl).
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
Conflicts:
|
||||
stdio-common/Makefile
|
||||
(missing C2x tests tst-printf-binary, tst-printf-intn,
|
||||
tst-printf-oct, missing test tst-vfprintf-width-i18n
|
||||
in the downstream tree, but downstream backported
|
||||
tst-ungetc-leak-mem earlier)
|
||||
|
||||
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index 418102c4c0d8c25a..2ef144268af98f34 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -231,15 +231,28 @@ tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace \
|
||||
tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace \
|
||||
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||
|
||||
-generated += test-fmemopen.mtrace test-fmemopen.check
|
||||
-generated += tst-fdopen-seek-failure.mtrace tst-fdopen-seek-failure.check
|
||||
-generated += tst-fopenloc.mtrace tst-fopenloc.check
|
||||
-generated += tst-bz22415.mtrace tst-bz22415.check
|
||||
-
|
||||
aux := fileops genops stdfiles stdio strops
|
||||
|
||||
+ifeq ($(run-built-tests),yes)
|
||||
+ifeq ($(build-shared),yes)
|
||||
+ifneq ($(PERL),no)
|
||||
+generated += \
|
||||
+ test-fmemopen.check \
|
||||
+ test-fmemopen.mtrace \
|
||||
+ tst-bz22415.check \
|
||||
+ tst-bz22415.mtrace \
|
||||
+ tst-bz24228.check \
|
||||
+ tst-bz24228.mtrace \
|
||||
+ tst-fdopen-seek-failure.check \
|
||||
+ tst-fdopen-seek-failure.mtrace \
|
||||
+ tst-fopenloc.check \
|
||||
+ tst-fopenloc.mtrace \
|
||||
+ # generated
|
||||
+endif
|
||||
+endif
|
||||
+endif
|
||||
+
|
||||
ifeq ($(build-shared),yes)
|
||||
-generated += tst-bz24228.mtrace tst-bz24228.check
|
||||
aux += oldfileops oldstdfiles
|
||||
endif
|
||||
|
||||
@@ -250,16 +263,23 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += \
|
||||
- $(objpfx)test-fmemopen-mem.out \
|
||||
$(objpfx)test-freopen.out \
|
||||
- $(objpfx)tst-bz22415-mem.out \
|
||||
- $(objpfx)tst-fdopen-seek-failure-mem.out \
|
||||
# tests-special
|
||||
ifeq (yes,$(build-shared))
|
||||
# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
|
||||
# library is enabled since they depend on tst-fopenloc.out.
|
||||
-tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out \
|
||||
- $(objpfx)tst-bz24228-mem.out
|
||||
+tests-special += $(objpfx)tst-fopenloc-cmp.out
|
||||
+ifeq ($(build-shared),yes)
|
||||
+ifneq ($(PERL),no)
|
||||
+tests-special += \
|
||||
+ $(objpfx)test-fmemopen-mem.out \
|
||||
+ $(objpfx)tst-bz22415-mem.out \
|
||||
+ $(objpfx)tst-bz24228-mem.out \
|
||||
+ $(objpfx)tst-fdopen-seek-failure-mem.out \
|
||||
+ $(objpfx)tst-fopenloc-mem.out \
|
||||
+ # tests-special
|
||||
+endif
|
||||
+endif
|
||||
endif
|
||||
|
||||
tests += \
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 1eaea991dd63e20c..bc314af0617e1647 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -184,10 +184,6 @@ tests := \
|
||||
tst-perror \
|
||||
tst-popen \
|
||||
tst-popen2 \
|
||||
- tst-printf-bz18872 \
|
||||
- tst-printf-bz25691 \
|
||||
- tst-printf-fp-free \
|
||||
- tst-printf-fp-leak \
|
||||
tst-printf-round \
|
||||
tst-printfsz \
|
||||
tst-put-error \
|
||||
@@ -208,7 +204,6 @@ tests := \
|
||||
tst-unlockedio \
|
||||
tst-vfprintf-mbs-prec \
|
||||
tst-vfprintf-user-type \
|
||||
- tst-vfprintf-width-prec \
|
||||
tst-vfprintf-width-prec-alloc \
|
||||
tst-wc-printf \
|
||||
tstdiomisc \
|
||||
@@ -217,6 +212,20 @@ tests := \
|
||||
xbug \
|
||||
# tests
|
||||
|
||||
+ifeq ($(run-built-tests),yes)
|
||||
+ifeq (yes,$(build-shared))
|
||||
+ifneq ($(PERL),no)
|
||||
+tests += \
|
||||
+ tst-printf-bz18872 \
|
||||
+ tst-printf-bz25691 \
|
||||
+ tst-printf-fp-free \
|
||||
+ tst-printf-fp-leak \
|
||||
+ tst-vfprintf-width-prec \
|
||||
+ # tests
|
||||
+endif
|
||||
+endif
|
||||
+endif
|
||||
+
|
||||
test-srcs = \
|
||||
tst-printf \
|
||||
tst-printfsz-islongdouble \
|
||||
@@ -225,15 +234,20 @@ test-srcs = \
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += \
|
||||
- $(objpfx)tst-printf-bz18872-mem.out \
|
||||
- $(objpfx)tst-printf-bz25691-mem.out \
|
||||
- $(objpfx)tst-printf-fp-free-mem.out \
|
||||
- $(objpfx)tst-printf-fp-leak-mem.out \
|
||||
$(objpfx)tst-printf.out \
|
||||
$(objpfx)tst-printfsz-islongdouble.out \
|
||||
$(objpfx)tst-setvbuf1-cmp.out \
|
||||
$(objpfx)tst-unbputc.out \
|
||||
$(objpfx)tst-ungetc-leak-mem.out \
|
||||
+ # tests-special
|
||||
+
|
||||
+ifeq (yes,$(build-shared))
|
||||
+ifneq ($(PERL),no)
|
||||
+tests-special += \
|
||||
+ $(objpfx)tst-printf-bz18872-mem.out \
|
||||
+ $(objpfx)tst-printf-bz25691-mem.out \
|
||||
+ $(objpfx)tst-printf-fp-free-mem.out \
|
||||
+ $(objpfx)tst-printf-fp-leak-mem.out \
|
||||
$(objpfx)tst-vfprintf-width-prec-mem.out \
|
||||
# tests-special
|
||||
|
||||
@@ -253,6 +267,8 @@ generated += \
|
||||
tst-vfprintf-width-prec-mem.out \
|
||||
tst-vfprintf-width-prec.mtrace \
|
||||
# generated
|
||||
+endif
|
||||
+endif
|
||||
endif # $(run-built-tests)
|
||||
|
||||
tests-special += $(objpfx)tst-errno-manual.out
|
79
SOURCES/glibc-RHEL-46733-2.patch
Normal file
79
SOURCES/glibc-RHEL-46733-2.patch
Normal file
@ -0,0 +1,79 @@
|
||||
commit 3e4a01870ef9605ccf6475215a4b32aa86d5d206
|
||||
Author: Aaron Merey <amerey@redhat.com>
|
||||
Date: Thu Aug 29 12:02:25 2024 -0400
|
||||
|
||||
Test fclose on an unopened file.
|
||||
|
||||
Add new file libio/tst-fclosed-unopened.c that tests whether fclose on
|
||||
an unopened file returns EOF.
|
||||
|
||||
Calling fclose on unopened files normally causes a use-after-free bug,
|
||||
however the standard streams are an exception since they are not
|
||||
deallocated by fclose.
|
||||
|
||||
fclose returning EOF for unopened files is not part of the external
|
||||
contract but there are dependancies on this behaviour. For example,
|
||||
gnulib's close_stdout in lib/closeout.c.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Signed-off-by: Aaron Merey <amerey@redhat.com>
|
||||
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index 2ef144268af98f34..f0ecb6b775a543af 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -76,6 +76,7 @@ tests = \
|
||||
tst-eof \
|
||||
tst-ext \
|
||||
tst-ext2 \
|
||||
+ tst-fclose-unopened \
|
||||
tst-fdopen-seek-failure \
|
||||
tst-fgetc-after-eof \
|
||||
tst-fgetwc \
|
||||
diff --git a/libio/tst-fclose-unopened.c b/libio/tst-fclose-unopened.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1f1cad042d8d72bf
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-fclose-unopened.c
|
||||
@@ -0,0 +1,40 @@
|
||||
+/* Test using fclose on an unopened file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+/* Verify that fclose on an unopened file returns EOF. This is not part
|
||||
+ of the fclose external contract but there are dependancies on this
|
||||
+ behaviour. */
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ TEST_COMPARE (fclose (stdin), 0);
|
||||
+
|
||||
+ /* Attempt to close the unopened file and verify that EOF is returned.
|
||||
+ Calling fclose on a file twice normally causes a use-after-free bug,
|
||||
+ however the standard streams are an exception since they are not
|
||||
+ deallocated by fclose. */
|
||||
+ TEST_COMPARE (fclose (stdin), EOF);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
155
SOURCES/glibc-RHEL-46733-3.patch
Normal file
155
SOURCES/glibc-RHEL-46733-3.patch
Normal file
@ -0,0 +1,155 @@
|
||||
commit 35dc62de3d5d73a91d4ca8fa9799b510a34d170d
|
||||
Author: Aaron Merey <amerey@redhat.com>
|
||||
Date: Thu Sep 19 09:53:23 2024 -0400
|
||||
|
||||
Add another test for fclose on an unopened file
|
||||
|
||||
Add new file libio/tst-fclose-unopened2.c that tests whether fclose on an
|
||||
unopened file returns EOF.
|
||||
|
||||
This test differs from tst-fclose-unopened.c by ensuring the file's buffer
|
||||
is allocated prior to double-fclose. A comment in tst-fclose-unopened.c
|
||||
now clarifies that it is testing a file with an unallocated buffer.
|
||||
|
||||
Calling fclose on unopened files normally causes a use-after-free bug,
|
||||
however the standard streams are an exception since they are not
|
||||
deallocated by fclose.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index f0ecb6b775a543af..8b2d8aaae563788b 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -77,6 +77,7 @@ tests = \
|
||||
tst-ext \
|
||||
tst-ext2 \
|
||||
tst-fclose-unopened \
|
||||
+ tst-fclose-unopened2 \
|
||||
tst-fdopen-seek-failure \
|
||||
tst-fgetc-after-eof \
|
||||
tst-fgetwc \
|
||||
@@ -220,6 +221,9 @@ LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
|
||||
|
||||
tst_wprintf2-ARGS = "Some Text"
|
||||
|
||||
+tst-fclose-unopened2-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-fclose-unopened2.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||
test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace \
|
||||
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||
tst-fdopen-seek-failure-ENV = \
|
||||
@@ -244,6 +248,8 @@ generated += \
|
||||
tst-bz22415.mtrace \
|
||||
tst-bz24228.check \
|
||||
tst-bz24228.mtrace \
|
||||
+ tst-fclose-unopened2.check \
|
||||
+ tst-fclose-unopened2.mtrace \
|
||||
tst-fdopen-seek-failure.check \
|
||||
tst-fdopen-seek-failure.mtrace \
|
||||
tst-fopenloc.check \
|
||||
@@ -276,6 +282,7 @@ tests-special += \
|
||||
$(objpfx)test-fmemopen-mem.out \
|
||||
$(objpfx)tst-bz22415-mem.out \
|
||||
$(objpfx)tst-bz24228-mem.out \
|
||||
+ $(objpfx)tst-fclose-unopened2-mem.out \
|
||||
$(objpfx)tst-fdopen-seek-failure-mem.out \
|
||||
$(objpfx)tst-fopenloc-mem.out \
|
||||
# tests-special
|
||||
@@ -363,6 +370,11 @@ $(objpfx)test-fmemopen-mem.out: $(objpfx)test-fmemopen.out
|
||||
$(common-objpfx)malloc/mtrace $(objpfx)test-fmemopen.mtrace > $@; \
|
||||
$(evaluate-test)
|
||||
|
||||
+$(objpfx)tst-fclose-unopened2-mem.out: $(objpfx)tst-fclose-unopened2.out
|
||||
+ $(common-objpfx)malloc/mtrace \
|
||||
+ $(objpfx)tst-fclose-unopened2.mtrace > $@; \
|
||||
+ $(evaluate-test)
|
||||
+
|
||||
$(objpfx)tst-fdopen-seek-failure-mem.out: $(objpfx)tst-fdopen-seek-failure.out
|
||||
$(common-objpfx)malloc/mtrace \
|
||||
$(objpfx)tst-fdopen-seek-failure.mtrace > $@; \
|
||||
diff --git a/libio/tst-fclose-unopened.c b/libio/tst-fclose-unopened.c
|
||||
index 1f1cad042d8d72bf..4fed2ffdfe8cf9b4 100644
|
||||
--- a/libio/tst-fclose-unopened.c
|
||||
+++ b/libio/tst-fclose-unopened.c
|
||||
@@ -19,9 +19,11 @@
|
||||
#include <stdio.h>
|
||||
#include <support/check.h>
|
||||
|
||||
-/* Verify that fclose on an unopened file returns EOF. This is not part
|
||||
- of the fclose external contract but there are dependancies on this
|
||||
- behaviour. */
|
||||
+/* Verify that fclose on an unopened file returns EOF. This test uses
|
||||
+ a file with an unallocated buffer.
|
||||
+
|
||||
+ This is not part of the fclose external contract but there are
|
||||
+ dependencies on this behaviour. */
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
diff --git a/libio/tst-fclose-unopened2.c b/libio/tst-fclose-unopened2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1e99d9dc3d561b80
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-fclose-unopened2.c
|
||||
@@ -0,0 +1,51 @@
|
||||
+/* Test using fclose on an unopened file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <mcheck.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+/* Verify that fclose on an unopened file returns EOF. This test uses
|
||||
+ a file with an allocated buffer.
|
||||
+
|
||||
+ This is not part of the fclose external contract but there are
|
||||
+ dependencies on this behaviour. */
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+
|
||||
+ /* Input file tst-fclose-unopened2.input has 6 bytes plus newline. */
|
||||
+ char buf[6];
|
||||
+
|
||||
+ /* Read from the file to ensure its internal buffer is allocated. */
|
||||
+ TEST_COMPARE (fread (buf, 1, sizeof (buf), stdin), sizeof (buf));
|
||||
+
|
||||
+ TEST_COMPARE (fclose (stdin), 0);
|
||||
+
|
||||
+ /* Attempt to close the unopened file and verify that EOF is returned.
|
||||
+ Calling fclose on a file twice normally causes a use-after-free bug,
|
||||
+ however the standard streams are an exception since they are not
|
||||
+ deallocated by fclose. */
|
||||
+ TEST_COMPARE (fclose (stdin), EOF);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/libio/tst-fclose-unopened2.input b/libio/tst-fclose-unopened2.input
|
||||
new file mode 100644
|
||||
index 0000000000000000..399f9ba41aff870b
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-fclose-unopened2.input
|
||||
@@ -0,0 +1 @@
|
||||
+fclose
|
273
SOURCES/glibc-RHEL-46734.patch
Normal file
273
SOURCES/glibc-RHEL-46734.patch
Normal file
@ -0,0 +1,273 @@
|
||||
commit 1d72fa3cfa046f7293421a7e58f2a272474ea901
|
||||
Author: Sergey Kolosov <skolosov@redhat.com>
|
||||
Date: Wed Sep 25 15:51:23 2024 +0200
|
||||
|
||||
stdio-common: Add new test for fdopen
|
||||
|
||||
This commit adds fdopen test with all modes.
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index a6816f8bffbd21e0..8c94f0aea0049f56 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -163,6 +163,7 @@ tests := \
|
||||
tst-bz11319-fortify2 \
|
||||
tst-cookie \
|
||||
tst-fdopen \
|
||||
+ tst-fdopen2 \
|
||||
tst-ferror \
|
||||
tst-fgets \
|
||||
tst-fgets2 \
|
||||
diff --git a/stdio-common/tst-fdopen2.c b/stdio-common/tst-fdopen2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0c6625f25853aed5
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-fdopen2.c
|
||||
@@ -0,0 +1,246 @@
|
||||
+/* Test the fdopen function.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/temp_file.h>
|
||||
+
|
||||
+char *tmp_dir;
|
||||
+char *path_to_file;
|
||||
+
|
||||
+void
|
||||
+prepare_tmp_dir (void)
|
||||
+{
|
||||
+ tmp_dir = support_create_temp_directory ("tst-fdopen2");
|
||||
+ path_to_file = xasprintf ("%s/tst-fdopen2.txt", tmp_dir);
|
||||
+}
|
||||
+
|
||||
+/* open temp file descriptor with mode. */
|
||||
+int
|
||||
+open_tmp_fd (int mode)
|
||||
+{
|
||||
+ int fd = xopen (path_to_file, mode, 0644);
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* close and remove temp file with close. */
|
||||
+void
|
||||
+close_tmp_fd (int fd)
|
||||
+{
|
||||
+ xclose (fd);
|
||||
+ xunlink (path_to_file);
|
||||
+}
|
||||
+
|
||||
+/* close and remove temp file with fclose. */
|
||||
+void
|
||||
+close_tmp_fp (FILE *fp)
|
||||
+{
|
||||
+ fclose (fp);
|
||||
+ xunlink (path_to_file);
|
||||
+}
|
||||
+
|
||||
+/* test "w" fdopen mode. */
|
||||
+void
|
||||
+do_test_fdopen_w (void)
|
||||
+{
|
||||
+ int fd, ret;
|
||||
+ FILE *fp;
|
||||
+ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_TRUNC);
|
||||
+
|
||||
+ /* test mode mismatch. */
|
||||
+ fp = fdopen (fd, "r");
|
||||
+ if (fp != NULL || errno != EINVAL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, r) should fail with EINVAL: %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ fp = fdopen (fd, "w");
|
||||
+ if (fp == NULL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ const void *buf = "AAAA";
|
||||
+ ret = fwrite (buf, 1, 4, fp);
|
||||
+ if (ret != 4)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fwrite (): %m");
|
||||
+ }
|
||||
+
|
||||
+ unsigned char buf2[4];
|
||||
+ rewind (fp);
|
||||
+ clearerr (fp);
|
||||
+ /* fread should fail in "w" mode */
|
||||
+ ret = fread (buf2, 1, 4, fp);
|
||||
+ if (ret != 0 || ferror (fp) == 0)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fread should fail in \"w\" mode");
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+}
|
||||
+
|
||||
+/* test "r" fdopen mode. */
|
||||
+void
|
||||
+do_test_fdopen_r (void)
|
||||
+{
|
||||
+ int fd, ret;
|
||||
+ FILE *fp;
|
||||
+ fd = open_tmp_fd (O_RDONLY);
|
||||
+
|
||||
+ /* test mode mismatch. */
|
||||
+ fp = fdopen (fd, "w");
|
||||
+ if (fp != NULL || errno != EINVAL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, w) should fail with EINVAL: %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ fp = fdopen (fd, "r");
|
||||
+ if (fp == NULL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ const void *buf = "BBBB";
|
||||
+ /* fwrite should fail in "r" mode. */
|
||||
+ ret = fwrite (buf, 1, 4, fp);
|
||||
+ if (ret != 0 || ferror (fp) == 0)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fwrite should fail in \"r\" mode");
|
||||
+ }
|
||||
+
|
||||
+ unsigned char buf2[4];
|
||||
+ ret = fread (buf2, 1, 4, fp);
|
||||
+ if (ret != 4)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fread (): %m");
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+}
|
||||
+
|
||||
+/* test "a" fdopen mode. */
|
||||
+void
|
||||
+do_test_fdopen_a (void)
|
||||
+{
|
||||
+ int fd, ret;
|
||||
+ FILE *fp;
|
||||
+ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_APPEND);
|
||||
+
|
||||
+ /* test mode mismatch. */
|
||||
+ fp = fdopen (fd, "r+");
|
||||
+ if (fp != NULL || errno != EINVAL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, \"r+\") should fail with EINVAL: %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ fp = fdopen (fd, "a");
|
||||
+ if (fp == NULL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
|
||||
+ }
|
||||
+
|
||||
+ const void *buf = "CCCC";
|
||||
+ ret = fwrite (buf, 1, 4, fp);
|
||||
+ if (ret != 4)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fwrite (): %m");
|
||||
+ }
|
||||
+
|
||||
+ /* fread should fail in "a" mode. */
|
||||
+ unsigned char buf2[4];
|
||||
+ clearerr (fp);
|
||||
+ ret = fread (buf2, 1, 4, fp);
|
||||
+ if (ret != 0 || ferror (fp) == 0)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fread should fail \"a\" mode");
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+do_test_fdopen_mode (int mode, const char *fmode)
|
||||
+{
|
||||
+ int fd, ret;
|
||||
+ FILE *fp;
|
||||
+ fd = open_tmp_fd (mode);
|
||||
+
|
||||
+ fp = fdopen (fd, fmode);
|
||||
+ if (fp == NULL)
|
||||
+ {
|
||||
+ close_tmp_fd (fd);
|
||||
+ FAIL_EXIT1 ("fdopen (%d, %s): %m", fd, fmode);
|
||||
+ }
|
||||
+
|
||||
+ const void *buf = "EEEE";
|
||||
+ ret = fwrite (buf, 1, 4, fp);
|
||||
+ if (ret != 4)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fwrite () in mode:%s returns %d: %m", fmode, ret);
|
||||
+ }
|
||||
+
|
||||
+ rewind (fp);
|
||||
+ unsigned char buf2[4];
|
||||
+ ret = fread (buf2, 1, 4, fp);
|
||||
+ if (ret != 4)
|
||||
+ {
|
||||
+ close_tmp_fp (fp);
|
||||
+ FAIL_EXIT1 ("fread () in mode:%s returns %d: %m", fmode, ret);
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+
|
||||
+ prepare_tmp_dir ();
|
||||
+
|
||||
+ do_test_fdopen_w ();
|
||||
+ do_test_fdopen_r ();
|
||||
+ do_test_fdopen_a ();
|
||||
+
|
||||
+ /* test r+ w+ a+ fdopen modes. */
|
||||
+ do_test_fdopen_mode (O_RDWR, "r+");
|
||||
+ do_test_fdopen_mode (O_RDWR | O_CREAT | O_TRUNC, "w+");
|
||||
+ do_test_fdopen_mode (O_RDWR | O_CREAT | O_APPEND, "a+");
|
||||
+ xunlink (path_to_file);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
167
SOURCES/glibc-RHEL-46735.patch
Normal file
167
SOURCES/glibc-RHEL-46735.patch
Normal file
@ -0,0 +1,167 @@
|
||||
commit d14c977c65aac7db35bb59380ef99d6582c4f930
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Sep 24 14:06:22 2024 +0000
|
||||
|
||||
Add tests of fread
|
||||
|
||||
There seem to be no glibc tests specifically for the fread function.
|
||||
Add basic tests of that function.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Conflicts:
|
||||
stdio-common/Makefile
|
||||
(usual tests conflict)
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 8c94f0aea0049f56..1eaea991dd63e20c 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -174,6 +174,7 @@ tests := \
|
||||
tst-fmemopen4 \
|
||||
tst-fphex \
|
||||
tst-fphex-wide \
|
||||
+ tst-fread \
|
||||
tst-fseek \
|
||||
tst-fwrite \
|
||||
tst-gets \
|
||||
diff --git a/stdio-common/tst-fread.c b/stdio-common/tst-fread.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4d9a7895f66a7980
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-fread.c
|
||||
@@ -0,0 +1,134 @@
|
||||
+/* Test fread.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-fread");
|
||||
+ char *file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ add_temp_file (file1);
|
||||
+ FILE *fp;
|
||||
+ size_t ret;
|
||||
+ char buf[1024];
|
||||
+
|
||||
+ verbose_printf ("test single-byte reads\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 1, 2, fp);
|
||||
+ TEST_COMPARE (ret, 2);
|
||||
+ TEST_COMPARE (buf[0], 'f');
|
||||
+ TEST_COMPARE (buf[1], 'i');
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 2);
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 1, 3, fp);
|
||||
+ TEST_COMPARE (ret, 3);
|
||||
+ TEST_COMPARE (buf[0], 'l');
|
||||
+ TEST_COMPARE (buf[1], 'e');
|
||||
+ TEST_COMPARE (buf[2], '1');
|
||||
+ TEST_COMPARE (ftell (fp), 5);
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 1, 1, fp);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE (!!feof (fp), 1);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 5);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("test single-byte reads, EOF part way through\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 1, sizeof buf, fp);
|
||||
+ TEST_COMPARE (ret, 5);
|
||||
+ TEST_COMPARE (buf[0], 'f');
|
||||
+ TEST_COMPARE (buf[1], 'i');
|
||||
+ TEST_COMPARE (buf[2], 'l');
|
||||
+ TEST_COMPARE (buf[3], 'e');
|
||||
+ TEST_COMPARE (buf[4], '1');
|
||||
+ TEST_COMPARE (!!feof (fp), 1);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 5);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("test multi-byte reads\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 2, 2, fp);
|
||||
+ TEST_COMPARE (ret, 2);
|
||||
+ TEST_COMPARE (buf[0], 'f');
|
||||
+ TEST_COMPARE (buf[1], 'i');
|
||||
+ TEST_COMPARE (buf[2], 'l');
|
||||
+ TEST_COMPARE (buf[3], 'e');
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 4);
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 3, 3, fp);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ /* The bytes written for a partial element read are unspecified. */
|
||||
+ TEST_COMPARE (!!feof (fp), 1);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 5);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("test read error\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ xclose (fileno (fp));
|
||||
+ memset (buf, 0, sizeof buf);
|
||||
+ ret = fread (buf, 1, sizeof buf, fp);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ TEST_COMPARE (!!ferror (fp), 1);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ verbose_printf ("test zero size\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ ret = fread (buf, 0, SIZE_MAX, fp);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 0);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("test zero items\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ ret = fread (buf, SIZE_MAX, 0, fp);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE (feof (fp), 0);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ TEST_COMPARE (ftell (fp), 0);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
67
SOURCES/glibc-RHEL-46736-1.patch
Normal file
67
SOURCES/glibc-RHEL-46736-1.patch
Normal file
@ -0,0 +1,67 @@
|
||||
commit e3fdbe9f39747206b9c3fbb0219f29fd5b35d020
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Apr 8 17:36:07 2021 -0300
|
||||
|
||||
support: Add xmkfifo
|
||||
|
||||
Wrapper support mkfifo.
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 25e8bbefd78c2268..0273c0f6306720c9 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -137,6 +137,7 @@ libsupport-routines = \
|
||||
xmemstream \
|
||||
xmkdir \
|
||||
xmkdirp \
|
||||
+ xmkfifo \
|
||||
xmmap \
|
||||
xmprotect \
|
||||
xmunmap \
|
||||
diff --git a/support/xmkfifo.c b/support/xmkfifo.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a8e196dbc209a47d
|
||||
--- /dev/null
|
||||
+++ b/support/xmkfifo.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* mkfifo with error checking.
|
||||
+ Copyright (C) 2022 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+void
|
||||
+xmkfifo (const char *pathname, mode_t mode)
|
||||
+{
|
||||
+ int r = mkfifo (pathname, mode);
|
||||
+ if (r < 0)
|
||||
+ FAIL_EXIT1 ("mkfifo (%s, 0%o): %m", pathname, mode);
|
||||
+}
|
||||
diff --git a/support/xunistd.h b/support/xunistd.h
|
||||
index a25ecf1cf38ef328..94b1e1eb1b1e8253 100644
|
||||
--- a/support/xunistd.h
|
||||
+++ b/support/xunistd.h
|
||||
@@ -61,6 +61,7 @@ void xsymlink (const char *target, const char *linkpath);
|
||||
void xchdir (const char *path);
|
||||
void xfchmod (int fd, mode_t mode);
|
||||
void xchmod (const char *pathname, mode_t mode);
|
||||
+void xmkfifo (const char *pathname, mode_t mode);
|
||||
|
||||
/* Equivalent of "mkdir -p". */
|
||||
void xmkdirp (const char *, mode_t);
|
30
SOURCES/glibc-RHEL-46736-10.patch
Normal file
30
SOURCES/glibc-RHEL-46736-10.patch
Normal file
@ -0,0 +1,30 @@
|
||||
commit 6948ee4edf0c57c556f8d5f394d9191216d05780
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat Sep 28 21:06:11 2024 +0200
|
||||
|
||||
stdio-common: Fix memory leak in tst-freopen4* tests on UNSUPPORTED
|
||||
|
||||
The temp_dir allocation leaks if support_can_chroot returns false.
|
||||
|
||||
diff --git a/stdio-common/tst-freopen4-main.c b/stdio-common/tst-freopen4-main.c
|
||||
index e169442cf4df2e9d..7284677a97e10af6 100644
|
||||
--- a/stdio-common/tst-freopen4-main.c
|
||||
+++ b/stdio-common/tst-freopen4-main.c
|
||||
@@ -33,7 +33,7 @@ int
|
||||
do_test (void)
|
||||
{
|
||||
mtrace ();
|
||||
- char *temp_dir = support_create_temp_directory ("tst-freopen4");
|
||||
+ char *temp_dir;
|
||||
FILE *fp;
|
||||
int ret;
|
||||
|
||||
@@ -45,6 +45,8 @@ do_test (void)
|
||||
support_become_root ();
|
||||
if (!support_can_chroot ())
|
||||
return EXIT_UNSUPPORTED;
|
||||
+
|
||||
+ temp_dir = support_create_temp_directory ("tst-freopen4");
|
||||
xchroot (temp_dir);
|
||||
|
||||
/* Test freopen with NULL, renamed file. This verifies that
|
216
SOURCES/glibc-RHEL-46736-11.patch
Normal file
216
SOURCES/glibc-RHEL-46736-11.patch
Normal file
@ -0,0 +1,216 @@
|
||||
commit 42c810c2cf3554afbdd60885b7da6bb4e702466f
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Mon Oct 7 19:44:25 2024 +0000
|
||||
|
||||
Add freopen special-case tests: thread cancellation
|
||||
|
||||
Add tests of freopen adding or removing "c" (non-cancelling I/O) from
|
||||
the mode string (so completing my planned tests of freopen with
|
||||
different features used in the mode strings). Note that it's in the
|
||||
nature of the uncertain time at which cancellation might act (possibly
|
||||
during freopen, possibly during subsequent reads) that these can leak
|
||||
memory or file descriptors, so these do not include leak tests.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index c920f55ed2119900..09d3622823203f74 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -180,10 +180,12 @@ tests := \
|
||||
tst-freopen4 \
|
||||
tst-freopen5 \
|
||||
tst-freopen6 \
|
||||
+ tst-freopen7 \
|
||||
tst-freopen64-2 \
|
||||
tst-freopen64-3 \
|
||||
tst-freopen64-4 \
|
||||
tst-freopen64-6 \
|
||||
+ tst-freopen64-7 \
|
||||
tst-fseek \
|
||||
tst-fwrite \
|
||||
tst-getline \
|
||||
@@ -480,3 +482,6 @@ $(objpfx)tst-setvbuf1-cmp.out: tst-setvbuf1.expect $(objpfx)tst-setvbuf1.out
|
||||
|
||||
$(objpfx)tst-printf-round: $(libm)
|
||||
$(objpfx)tst-scanf-round: $(libm)
|
||||
+
|
||||
+$(objpfx)tst-freopen7: $(shared-thread-library)
|
||||
+$(objpfx)tst-freopen64-7: $(shared-thread-library)
|
||||
diff --git a/stdio-common/tst-freopen64-7.c b/stdio-common/tst-freopen64-7.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f34c2805210079b9
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen64-7.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen64
|
||||
+#include <tst-freopen7-main.c>
|
||||
diff --git a/stdio-common/tst-freopen7-main.c b/stdio-common/tst-freopen7-main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..965e0b4adce750cc
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen7-main.c
|
||||
@@ -0,0 +1,155 @@
|
||||
+/* Test freopen cancellation handling.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <mcheck.h>
|
||||
+#include <pthread.h>
|
||||
+#include <semaphore.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <wchar.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+char *file1, *file2, *file3, *fifo;
|
||||
+
|
||||
+sem_t sem;
|
||||
+
|
||||
+void *
|
||||
+test_rc_to_r (void *p)
|
||||
+{
|
||||
+ int ret;
|
||||
+ FILE *fp, *fp2;
|
||||
+ ret = sem_post (&sem);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ fp = xfopen (file1, "rc");
|
||||
+ for (int i = 0; i < 1000000; i++)
|
||||
+ {
|
||||
+ fgetc (fp);
|
||||
+ fseek (fp, 0, SEEK_SET);
|
||||
+ }
|
||||
+ fp2 = xfopen (file3, "wc");
|
||||
+ fputs ("rc_to_r got to freopen", fp2);
|
||||
+ xfclose (fp2);
|
||||
+ /* Cancellation should occur at some point from here onwards
|
||||
+ (possibly leaking memory and file descriptors associated with the
|
||||
+ FILE). */
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ fgetc (fp);
|
||||
+ fseek (fp, 0, SEEK_SET);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+test_r_to_rc (void *p)
|
||||
+{
|
||||
+ int ret;
|
||||
+ FILE *fp;
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (fifo, "rc", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = sem_post (&sem);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ /* No cancellation should occur for I/O on fifo. */
|
||||
+ ret = fgetc (fp);
|
||||
+ /* At this point, the other thread has called pthread_cancel and
|
||||
+ then written a byte to the fifo, so this thread is cancelled at
|
||||
+ the next cancellation point. */
|
||||
+ TEST_VERIFY (ret == 'x');
|
||||
+ xfclose (fp);
|
||||
+ fp = xfopen (file3, "wc");
|
||||
+ fputs ("r_to_rc got to fclose", fp);
|
||||
+ xfclose (fp);
|
||||
+ pthread_testcancel ();
|
||||
+ FAIL_EXIT1 ("test_r_to_rc not cancelled\n");
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen-cancel");
|
||||
+ file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ add_temp_file (file1);
|
||||
+ file2 = xasprintf ("%s/file2", temp_dir);
|
||||
+ support_write_file_string (file2, "file2");
|
||||
+ add_temp_file (file2);
|
||||
+ file3 = xasprintf ("%s/file3", temp_dir);
|
||||
+ support_write_file_string (file3, "file3");
|
||||
+ add_temp_file (file3);
|
||||
+ fifo = xasprintf ("%s/fifo", temp_dir);
|
||||
+ xmkfifo (fifo, 0666);
|
||||
+ add_temp_file (fifo);
|
||||
+ int ret;
|
||||
+ pthread_t thr;
|
||||
+ void *retval;
|
||||
+
|
||||
+ /* Test changing to/from c (cancellation disabled). */
|
||||
+
|
||||
+ verbose_printf ("Testing rc -> r\n");
|
||||
+ ret = sem_init (&sem, 0, 0);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ thr = xpthread_create (NULL, test_rc_to_r, NULL);
|
||||
+ ret = sem_wait (&sem);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ xpthread_cancel (thr);
|
||||
+ ret = pthread_join (thr, &retval);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_VERIFY (retval == PTHREAD_CANCELED);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file3, "rc_to_r got to freopen");
|
||||
+
|
||||
+ verbose_printf ("Testing r -> rc\n");
|
||||
+ ret = sem_init (&sem, 0, 0);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ thr = xpthread_create (NULL, test_r_to_rc, NULL);
|
||||
+ FILE *fp = xfopen (fifo, "w");
|
||||
+ ret = sem_wait (&sem);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ /* This call happens while, or before, the other thread is waiting
|
||||
+ to read a character from the fifo. It thus verifies that
|
||||
+ cancellation does not occur from the fgetc call in that thread
|
||||
+ (it should instead occur only in pthread_testcancel call),
|
||||
+ because the expected string is only written to file3 after that
|
||||
+ thread closes the fifo. */
|
||||
+ xpthread_cancel (thr);
|
||||
+ fputc ('x', fp);
|
||||
+ xfclose (fp);
|
||||
+ ret = pthread_join (thr, &retval);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_VERIFY (retval == PTHREAD_CANCELED);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file3, "r_to_rc got to fclose");
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ free (file2);
|
||||
+ free (file3);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen7.c b/stdio-common/tst-freopen7.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..03d0de798e3d2616
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen7.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen
|
||||
+#include <tst-freopen7-main.c>
|
168
SOURCES/glibc-RHEL-46736-2.patch
Normal file
168
SOURCES/glibc-RHEL-46736-2.patch
Normal file
@ -0,0 +1,168 @@
|
||||
commit da55fae9e277a0c138d4395fee505e5d2f8b2b84
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Tue May 23 08:34:56 2023 -0400
|
||||
|
||||
support: Reformat Makefile.
|
||||
|
||||
Add list end markers.
|
||||
Sort text using scripts/sort-makefile-lines.py.
|
||||
|
||||
No code generation changes observed in non-test binary artifacts.
|
||||
No regressions on x86_64 and i686.
|
||||
|
||||
Conflicts:
|
||||
support/Makefile
|
||||
(different backport order)
|
||||
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 0273c0f6306720c9..17a4157563f9ecd6 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -41,7 +41,7 @@ libsupport-routines = \
|
||||
resolv_response_context_free \
|
||||
resolv_test \
|
||||
set_fortify_handler \
|
||||
- support_stack_alloc \
|
||||
+ support-open-dev-null-range \
|
||||
support_become_root \
|
||||
support_can_chroot \
|
||||
support_capture_subprocess \
|
||||
@@ -65,12 +65,11 @@ libsupport-routines = \
|
||||
support_fuse \
|
||||
support_isolate_in_subprocess \
|
||||
support_need_proc \
|
||||
+ support_openpty \
|
||||
support_path_support_time64 \
|
||||
+ support_paths \
|
||||
support_process_state \
|
||||
support_ptrace \
|
||||
- support-open-dev-null-range \
|
||||
- support_openpty \
|
||||
- support_paths \
|
||||
support_quote_blob \
|
||||
support_quote_blob_wide \
|
||||
support_quote_string \
|
||||
@@ -84,6 +83,8 @@ libsupport-routines = \
|
||||
support_shared_allocate \
|
||||
support_small_stack_thread_attribute \
|
||||
support_socket_so_timestamp_time64 \
|
||||
+ support_stack_alloc \
|
||||
+ support_stack_alloc \
|
||||
support_stat_nanoseconds \
|
||||
support_subprocess \
|
||||
support_test_compare_blob \
|
||||
@@ -96,11 +97,11 @@ libsupport-routines = \
|
||||
support_write_file_string \
|
||||
temp_file \
|
||||
timespec \
|
||||
- timespec-time64 \
|
||||
timespec-add \
|
||||
timespec-add-time64 \
|
||||
timespec-sub \
|
||||
timespec-sub-time64 \
|
||||
+ timespec-time64 \
|
||||
write_message \
|
||||
xaccept \
|
||||
xaccept4 \
|
||||
@@ -108,6 +109,8 @@ libsupport-routines = \
|
||||
xbind \
|
||||
xcalloc \
|
||||
xchdir \
|
||||
+ xchmod \
|
||||
+ xchmod \
|
||||
xchroot \
|
||||
xclock_gettime \
|
||||
xclock_gettime_time64 \
|
||||
@@ -116,7 +119,6 @@ libsupport-routines = \
|
||||
xclone \
|
||||
xclose \
|
||||
xclosedir \
|
||||
- xchmod \
|
||||
xconnect \
|
||||
xcopy_file_range \
|
||||
xdlfcn \
|
||||
@@ -147,11 +149,17 @@ libsupport-routines = \
|
||||
xpipe \
|
||||
xpoll \
|
||||
xposix_memalign \
|
||||
+ xposix_spawn \
|
||||
+ xposix_spawn \
|
||||
+ xposix_spawn_file_actions_addclose \
|
||||
+ xposix_spawn_file_actions_addclose \
|
||||
+ xposix_spawn_file_actions_adddup2 \
|
||||
+ xposix_spawn_file_actions_adddup2 \
|
||||
xpthread_attr_destroy \
|
||||
xpthread_attr_init \
|
||||
+ xpthread_attr_setaffinity_np \
|
||||
xpthread_attr_setdetachstate \
|
||||
xpthread_attr_setguardsize \
|
||||
- xpthread_attr_setaffinity_np \
|
||||
xpthread_attr_setstack \
|
||||
xpthread_attr_setstacksize \
|
||||
xpthread_barrier_destroy \
|
||||
@@ -162,8 +170,8 @@ libsupport-routines = \
|
||||
xpthread_barrierattr_setpshared \
|
||||
xpthread_cancel \
|
||||
xpthread_check_return \
|
||||
- xpthread_cond_wait \
|
||||
xpthread_cond_signal \
|
||||
+ xpthread_cond_wait \
|
||||
xpthread_create \
|
||||
xpthread_detach \
|
||||
xpthread_join \
|
||||
@@ -182,8 +190,8 @@ libsupport-routines = \
|
||||
xpthread_mutexattr_setrobust \
|
||||
xpthread_mutexattr_settype \
|
||||
xpthread_once \
|
||||
- xpthread_rwlock_init \
|
||||
xpthread_rwlock_destroy \
|
||||
+ xpthread_rwlock_init \
|
||||
xpthread_rwlock_rdlock \
|
||||
xpthread_rwlock_unlock \
|
||||
xpthread_rwlock_wrlock \
|
||||
@@ -204,9 +212,6 @@ libsupport-routines = \
|
||||
xsigstack \
|
||||
xsocket \
|
||||
xstatx \
|
||||
- xposix_spawn \
|
||||
- xposix_spawn_file_actions_addclose \
|
||||
- xposix_spawn_file_actions_adddup2 \
|
||||
xstrdup \
|
||||
xstrndup \
|
||||
xsymlink \
|
||||
@@ -215,6 +220,7 @@ libsupport-routines = \
|
||||
xuselocale \
|
||||
xwaitpid \
|
||||
xwrite \
|
||||
+ # libsupport-routines
|
||||
|
||||
libsupport-static-only-routines := $(libsupport-routines)
|
||||
# Only build one variant of the library.
|
||||
@@ -278,8 +284,16 @@ LDLIBS-test-container = $(libsupport)
|
||||
others += test-container
|
||||
others-noinstall += test-container
|
||||
|
||||
-others += shell-container echo-container true-container
|
||||
-others-noinstall += shell-container echo-container true-container
|
||||
+others += \
|
||||
+ echo-container \
|
||||
+ shell-container \
|
||||
+ true-container \
|
||||
+ # others
|
||||
+others-noinstall += \
|
||||
+ echo-container \
|
||||
+ shell-container \
|
||||
+ true-container \
|
||||
+ # others-noinstall
|
||||
|
||||
others += $(LINKS_DSO_PROGRAM)
|
||||
others-noinstall += $(LINKS_DSO_PROGRAM)
|
||||
@@ -317,6 +331,7 @@ tests = \
|
||||
tst-xdirent \
|
||||
tst-xreadlink \
|
||||
tst-xsigstack \
|
||||
+ # tests
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special = \
|
261
SOURCES/glibc-RHEL-46736-3.patch
Normal file
261
SOURCES/glibc-RHEL-46736-3.patch
Normal file
@ -0,0 +1,261 @@
|
||||
commit 96d0bf98cafd0b63721f369ca21ec64590551d47
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Sep 3 13:53:01 2024 +0000
|
||||
|
||||
Add support/ code for checking file contents
|
||||
|
||||
For use in freopen tests, add various support/ helper interfaces for
|
||||
use in checking file contents.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 38ad266a0dec8e36..e70322cea06f137b 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -48,6 +48,8 @@ libsupport-routines = \
|
||||
support_check_stat_fd \
|
||||
support_check_stat_path \
|
||||
support_chroot \
|
||||
+ support_compare_file_bytes \
|
||||
+ support_compare_file_string \
|
||||
support_copy_file \
|
||||
support_copy_file_range \
|
||||
support_create_timer \
|
||||
@@ -64,6 +66,8 @@ libsupport-routines = \
|
||||
support_fuse \
|
||||
support_isolate_in_subprocess \
|
||||
support_need_proc \
|
||||
+ support_open_and_compare_file_bytes \
|
||||
+ support_open_and_compare_file_string \
|
||||
support_openpty \
|
||||
support_path_support_time64 \
|
||||
support_paths \
|
||||
diff --git a/support/file_contents.h b/support/file_contents.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..9b2d750aae8a885a
|
||||
--- /dev/null
|
||||
+++ b/support/file_contents.h
|
||||
@@ -0,0 +1,63 @@
|
||||
+/* Functionality for checking file contents.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef SUPPORT_FILE_CONTENTS_H
|
||||
+#define SUPPORT_FILE_CONTENTS_H
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+__BEGIN_DECLS
|
||||
+
|
||||
+/* Check that an already-open file has exactly the given bytes,
|
||||
+ starting at the current location in the file. The file position
|
||||
+ indicator is updated to point after the bytes compared. Return 0
|
||||
+ if equal, 1 otherwise or on read error. */
|
||||
+int support_compare_file_bytes (FILE *fp, const char *contents, size_t length);
|
||||
+
|
||||
+/* Check that an already-open file has exactly the given string as
|
||||
+ contents, starting at the current offset. The file position
|
||||
+ indicator is updated to point after the bytes compared. Return 0
|
||||
+ if equal, 1 otherwise or on read error. */
|
||||
+int support_compare_file_string (FILE *fp, const char *contents);
|
||||
+
|
||||
+/* Check that a not-currently-open file has exactly the given bytes.
|
||||
+ Return 0 if equal, 1 otherwise or on read error. */
|
||||
+int support_open_and_compare_file_bytes (const char *file,
|
||||
+ const char *contents,
|
||||
+ size_t length);
|
||||
+
|
||||
+/* Check that a not-currently-open file has exactly the given string
|
||||
+ as contents, starting at the current offset. Return 0 if equal, 1
|
||||
+ otherwise or on read error. */
|
||||
+int support_open_and_compare_file_string (const char *file,
|
||||
+ const char *contents);
|
||||
+
|
||||
+/* Compare bytes read from an open file with the given string. The
|
||||
+ file position indicator is updated to point after the bytes
|
||||
+ compared. */
|
||||
+#define TEST_COMPARE_FILE_STRING(FP, CONTENTS) \
|
||||
+ TEST_COMPARE (support_compare_file_string (FP, CONTENTS), 0)
|
||||
+
|
||||
+/* Read a file and compare bytes read from it with the given string. */
|
||||
+#define TEST_OPEN_AND_COMPARE_FILE_STRING(FILE, CONTENTS) \
|
||||
+ TEST_COMPARE (support_open_and_compare_file_string (FILE, CONTENTS), 0)
|
||||
+
|
||||
+__END_DECLS
|
||||
+
|
||||
+#endif /* SUPPORT_FILE_CONTENTS_H */
|
||||
diff --git a/support/support_compare_file_bytes.c b/support/support_compare_file_bytes.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e261e1da8f7b02b2
|
||||
--- /dev/null
|
||||
+++ b/support/support_compare_file_bytes.c
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* Compare bytes from an open file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include <support/file_contents.h>
|
||||
+
|
||||
+/* Check that an already-open file has exactly the given bytes,
|
||||
+ starting at the current offset. */
|
||||
+
|
||||
+int
|
||||
+support_compare_file_bytes (FILE *fp, const char *contents, size_t length)
|
||||
+{
|
||||
+ int c;
|
||||
+ while (length > 0)
|
||||
+ {
|
||||
+ c = getc (fp);
|
||||
+ if (c == EOF || (unsigned char) c != (unsigned char) contents[0])
|
||||
+ return 1;
|
||||
+ contents++;
|
||||
+ length--;
|
||||
+ }
|
||||
+ c = getc (fp);
|
||||
+ if (c != EOF || ferror (fp))
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/support/support_compare_file_string.c b/support/support_compare_file_string.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..04513c3af197037d
|
||||
--- /dev/null
|
||||
+++ b/support/support_compare_file_string.c
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* Compare string from an open file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <support/file_contents.h>
|
||||
+
|
||||
+int
|
||||
+support_compare_file_string (FILE *fp, const char *contents)
|
||||
+{
|
||||
+ return support_compare_file_bytes (fp, contents, strlen (contents));
|
||||
+}
|
||||
diff --git a/support/support_open_and_compare_file_bytes.c b/support/support_open_and_compare_file_bytes.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f804ed8e460d82f0
|
||||
--- /dev/null
|
||||
+++ b/support/support_open_and_compare_file_bytes.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* Compare bytes from a file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+/* Check that a not-currently-open file has exactly the given
|
||||
+ bytes. */
|
||||
+
|
||||
+int
|
||||
+support_open_and_compare_file_bytes (const char *file, const char *contents,
|
||||
+ size_t length)
|
||||
+{
|
||||
+ FILE *fp = xfopen (file, "r");
|
||||
+ int ret = support_compare_file_bytes (fp, contents, length);
|
||||
+ xfclose (fp);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/support/support_open_and_compare_file_string.c b/support/support_open_and_compare_file_string.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2b596d4c88b697f2
|
||||
--- /dev/null
|
||||
+++ b/support/support_open_and_compare_file_string.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* Compare string from a file.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+/* Check that a not-currently-open file has exactly the given string
|
||||
+ as contents, starting at the current offset. */
|
||||
+
|
||||
+int
|
||||
+support_open_and_compare_file_string (const char *file, const char *contents)
|
||||
+{
|
||||
+ return support_open_and_compare_file_bytes (file, contents,
|
||||
+ strlen (contents));
|
||||
+}
|
739
SOURCES/glibc-RHEL-46736-4.patch
Normal file
739
SOURCES/glibc-RHEL-46736-4.patch
Normal file
@ -0,0 +1,739 @@
|
||||
commit ed4bb289cf739f537deb735eaa01be531df084b9
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Sep 4 16:32:21 2024 +0000
|
||||
|
||||
Add more thorough tests of freopen
|
||||
|
||||
freopen is rather minimally tested in libio/tst-freopen and
|
||||
libio/test-freopen. Add some more thorough tests, covering different
|
||||
cases for change of mode in particular. The tests are run for both
|
||||
freopen and freopen64 (given that those functions have two separate
|
||||
copies of much of the code, so any bug fix directly in the freopen
|
||||
code would probably need applying in both places).
|
||||
|
||||
Note that there are two parts of the tests disabled because of bugs
|
||||
discovered through running the tests, with bug numbers given in
|
||||
comments. I expect to address those separately. The tests also don't
|
||||
cover changes to cancellation ("c" in mode); I think that will better
|
||||
be handled through a separate test. Also to handle separately:
|
||||
testing on stdin / stdout / stderr; documenting lack of support for
|
||||
streams opened with popen / fmemopen / open_memstream / fopencookie;
|
||||
maybe also a chroot test without /proc; maybe also more thorough tests
|
||||
for large file handling on 32-bit systems (freopen64).
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Conflicts:
|
||||
stdio-common/Makefile
|
||||
(tst-fread already backported)
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index ea8598bbe3a6dfdd..5eddc4bfbf4e7fb9 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -175,6 +175,10 @@ tests := \
|
||||
tst-fphex \
|
||||
tst-fphex-wide \
|
||||
tst-fread \
|
||||
+ tst-freopen2 \
|
||||
+ tst-freopen3 \
|
||||
+ tst-freopen64-2 \
|
||||
+ tst-freopen64-3 \
|
||||
tst-fseek \
|
||||
tst-fwrite \
|
||||
tst-getline \
|
||||
@@ -246,6 +250,8 @@ tests-special += \
|
||||
ifeq (yes,$(build-shared))
|
||||
ifneq ($(PERL),no)
|
||||
tests-special += \
|
||||
+ $(objpfx)tst-freopen2-mem.out \
|
||||
+ $(objpfx)tst-freopen64-2-mem.out \
|
||||
$(objpfx)tst-getline-enomem-mem.out \
|
||||
$(objpfx)tst-getline-mem.out \
|
||||
$(objpfx)tst-printf-bz18872-mem.out \
|
||||
@@ -256,6 +262,10 @@ tests-special += \
|
||||
# tests-special
|
||||
|
||||
generated += \
|
||||
+ tst-freopen2-mem.out \
|
||||
+ tst-freopen2.mtrace \
|
||||
+ tst-freopen64-2-mem.out \
|
||||
+ tst-freopen64-2.mtrace \
|
||||
tst-getline-enomem-mem.out \
|
||||
tst-getline-enomem.mtrace \
|
||||
tst-getline-mem.out \
|
||||
@@ -328,6 +338,12 @@ tst-getline-ENV = \
|
||||
tst-getline-enomem-ENV = \
|
||||
MALLOC_TRACE=$(objpfx)tst-getline-enomem.mtrace \
|
||||
LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen2-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen2.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen64-2-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen64-2.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
|
||||
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
|
||||
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
|
||||
diff --git a/stdio-common/tst-freopen2-main.c b/stdio-common/tst-freopen2-main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..22b21afebf709563
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen2-main.c
|
||||
@@ -0,0 +1,526 @@
|
||||
+/* Test freopen.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <mcheck.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <wchar.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/descriptors.h>
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+#define START_TEST(DESC) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ fds = support_descriptors_list (); \
|
||||
+ verbose_printf (DESC); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define END_TEST \
|
||||
+ do \
|
||||
+ { \
|
||||
+ support_descriptors_check (fds); \
|
||||
+ support_descriptors_free (fds); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+ struct support_descriptors *fds;
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen2");
|
||||
+ char *file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ add_temp_file (file1);
|
||||
+ char *file2 = xasprintf ("%s/file2", temp_dir);
|
||||
+ support_write_file_string (file2, "file2");
|
||||
+ add_temp_file (file2);
|
||||
+ char *file3 = xasprintf ("%s/file3", temp_dir);
|
||||
+ char *file4 = xasprintf ("%s/file4", temp_dir);
|
||||
+ char *file1a = xasprintf ("%s/file1a", temp_dir);
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+ wint_t wc;
|
||||
+
|
||||
+ /* Test each pair of old and new modes from r w a. */
|
||||
+
|
||||
+ START_TEST ("Testing r -> r\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "file2");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> w\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("File2new", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "file1");
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> a\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "a", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("3", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new3");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w -> r\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "File2new3");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w -> w\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("next", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "");
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w -> a\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file2, "a", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("4", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next4");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing a -> r\n");
|
||||
+ fp = xfopen (file1, "a");
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "next4");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing a -> w\n");
|
||||
+ fp = xfopen (file1, "a");
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("another", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing a -> a\n");
|
||||
+ fp = xfopen (file1, "a");
|
||||
+ fp = FREOPEN (file2, "a", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("5", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another5");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test for file originally opened with fopen64. */
|
||||
+ START_TEST ("Testing fopen64 a -> a\n");
|
||||
+ fp = fopen64 (file1, "a");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ fp = FREOPEN (file2, "a", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("64", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another564");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test calling freopen more than once on the same FILE *. */
|
||||
+
|
||||
+ START_TEST ("Testing r -> w -> r\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("freopen-twice", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice");
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> w -> r (exactly one freopen64)\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = OTHER_FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("freopen-twice64", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice64");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test changing to/from b (binary, no-op). */
|
||||
+
|
||||
+ START_TEST ("Testing rb -> r\n");
|
||||
+ fp = xfopen (file1, "rb");
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> rb\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "rb", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test changing to/from + (read-and-write). */
|
||||
+
|
||||
+ START_TEST ("Testing r -> w+\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "w+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("latest", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "latest");
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latest");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w -> a+\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file2, "a+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("suffix", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latestsuffix");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing a -> r+\n");
|
||||
+ fp = xfopen (file1, "a");
|
||||
+ fp = FREOPEN (file2, "r+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ ret = fputs ("new", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "newestsuffix");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r+ -> w\n");
|
||||
+ fp = xfopen (file1, "r+");
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("plusto", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ errno = 0;
|
||||
+ TEST_COMPARE (fgetc (fp), EOF);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ clearerr (fp);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plusto");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w+ -> a\n");
|
||||
+ fp = xfopen (file1, "w+");
|
||||
+ fp = FREOPEN (file2, "a", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("more", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ errno = 0;
|
||||
+ TEST_COMPARE (fgetc (fp), EOF);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ clearerr (fp);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing a+ -> r\n");
|
||||
+ fp = xfopen (file1, "a+");
|
||||
+ fp = FREOPEN (file2, "rr", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
+ ret = fputs ("2", fp);
|
||||
+ TEST_COMPARE (ret, EOF);
|
||||
+ clearerr (fp);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test changing to/from e (FD_CLOEXEC). */
|
||||
+
|
||||
+ START_TEST ("Testing re -> r\n");
|
||||
+ fp = xfopen (file1, "re");
|
||||
+ ret = fcntl (fileno (fp), F_GETFD);
|
||||
+ TEST_VERIFY (ret != -1);
|
||||
+ TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fcntl (fileno (fp), F_GETFD);
|
||||
+ TEST_VERIFY (ret != -1);
|
||||
+#if 0 /* Fails to clear FD_CLOEXEC (bug 32134). */
|
||||
+ TEST_COMPARE (ret & FD_CLOEXEC, 0);
|
||||
+#endif
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> re\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ ret = fcntl (fileno (fp), F_GETFD);
|
||||
+ TEST_VERIFY (ret != -1);
|
||||
+ TEST_COMPARE (ret & FD_CLOEXEC, 0);
|
||||
+ fp = FREOPEN (file2, "re", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fcntl (fileno (fp), F_GETFD);
|
||||
+ TEST_VERIFY (ret != -1);
|
||||
+ TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test changing to/from m (mmap) (a no-op as far as testing
|
||||
+ semantics is concerned). */
|
||||
+
|
||||
+ START_TEST ("Testing rm -> r\n");
|
||||
+ fp = xfopen (file1, "rm");
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing r -> rm\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fp = FREOPEN (file2, "rm", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test changing to/from x (O_EXCL). */
|
||||
+
|
||||
+ START_TEST ("Testing wx -> w\n");
|
||||
+ fp = xfopen (file3, "wx");
|
||||
+ add_temp_file (file3);
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ ret = fputs ("wxtow", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "wxtow");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("Testing w -> wx (file does not exist)\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file4, "wx", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ add_temp_file (file4);
|
||||
+ ret = fputs ("wtowx", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ xfclose (fp);
|
||||
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file4, "wtowx");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test with ,ccs=CHARSET. */
|
||||
+
|
||||
+ START_TEST ("testing w,ccs=utf-8 -> r\n");
|
||||
+ fp = xfopen (file1, "w,ccs=utf-8");
|
||||
+ ret = fputws (L"\xc0\xc1", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "wxtow");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("testing w,ccs=iso-8859-1 -> r,ccs=utf-8\n");
|
||||
+ fp = xfopen (file2, "w,ccs=iso-8859-1");
|
||||
+ ret = fputws (L"\xc0\xc1", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+#if 0 /* Doesn't work (bug 23675). */
|
||||
+ fp = FREOPEN (file1, "r,ccs=utf-8", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+#else /* Works instead. */
|
||||
+ xfclose (fp);
|
||||
+ fp = xfopen (file1, "r,ccs=utf-8");
|
||||
+#endif
|
||||
+ wc = fgetwc (fp);
|
||||
+ TEST_COMPARE (wc, (wint_t) 0xc0);
|
||||
+ wc = fgetwc (fp);
|
||||
+ TEST_COMPARE (wc, (wint_t) 0xc1);
|
||||
+ wc = fgetwc (fp);
|
||||
+ TEST_COMPARE (wc, WEOF);
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("testing r,ccs=utf-8 -> r\n");
|
||||
+ fp = xfopen (file1, "r,ccs=utf-8");
|
||||
+ fp = FREOPEN (file1, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test that errors closing the old file are ignored. */
|
||||
+
|
||||
+ START_TEST ("testing errors closing old file ignored\n");
|
||||
+ fp = xfopen ("/dev/full", "w");
|
||||
+ fputc ('x', fp);
|
||||
+ fp = FREOPEN (file1, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test that error / EOF state from the old file are cleared. */
|
||||
+
|
||||
+ START_TEST ("testing error state from old file cleared\n");
|
||||
+ fp = xfopen ("/dev/full", "w");
|
||||
+ fputc ('x', fp);
|
||||
+ fflush (fp);
|
||||
+ TEST_VERIFY (ferror (fp));
|
||||
+ TEST_VERIFY (!feof (fp));
|
||||
+ fp = FREOPEN (file2, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_VERIFY (!ferror (fp));
|
||||
+ TEST_VERIFY (!feof (fp));
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ START_TEST ("testing EOF state from old file cleared\n");
|
||||
+ fp = xfopen ("/dev/null", "r");
|
||||
+ fgetc (fp);
|
||||
+ TEST_VERIFY (!ferror (fp));
|
||||
+ TEST_VERIFY (feof (fp));
|
||||
+ fp = FREOPEN (file2, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_VERIFY (!ferror (fp));
|
||||
+ TEST_VERIFY (!feof (fp));
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test freopen with NULL, same mode (should flush content and reset
|
||||
+ file offset). */
|
||||
+
|
||||
+ START_TEST ("testing freopen with NULL, same mode\n");
|
||||
+ fp = xfopen (file1, "r+");
|
||||
+ ret = fputs ("same mode", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ fp = FREOPEN (NULL, "r+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "same mode");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test freopen with NULL, different mode. */
|
||||
+
|
||||
+ START_TEST ("testing freopen with NULL, different mode\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ ret = fputs ("different mode", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ fp = FREOPEN (NULL, "r", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "different mode");
|
||||
+ xfclose (fp);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test freopen with NULL, renamed file. This verifies that
|
||||
+ reopening succeeds (and resets the file position indicator to
|
||||
+ start of file) even when the original path could no longer be
|
||||
+ opened. */
|
||||
+
|
||||
+ START_TEST ("testing freopen with NULL, renamed file\n");
|
||||
+ fp = xfopen (file1, "r+");
|
||||
+ ret = fputs ("file has been renamed", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = rename (file1, file1a);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ fp = FREOPEN (NULL, "r+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "file has been renamed");
|
||||
+ xfclose (fp);
|
||||
+ ret = rename (file1a, file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test freopen with NULL, deleted file. This verifies that
|
||||
+ reopening succeeds (and resets the file position indicator to
|
||||
+ start of file) even when the original path could no longer be
|
||||
+ opened. */
|
||||
+
|
||||
+ START_TEST ("testing freopen with NULL, deleted file\n");
|
||||
+ fp = xfopen (file1, "r+");
|
||||
+ ret = fputs ("file has now been deleted", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = remove (file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ fp = FREOPEN (NULL, "r+", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "file has now been deleted");
|
||||
+ xfclose (fp);
|
||||
+ /* Recreate the file so it is present when expected for temporary
|
||||
+ file deletion. */
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ END_TEST;
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ free (file2);
|
||||
+ free (file3);
|
||||
+ free (file4);
|
||||
+ free (file1a);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen2.c b/stdio-common/tst-freopen2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..11ec7a9783b7caa3
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen2.c
|
||||
@@ -0,0 +1,3 @@
|
||||
+#define FREOPEN freopen
|
||||
+#define OTHER_FREOPEN freopen64
|
||||
+#include <tst-freopen2-main.c>
|
||||
diff --git a/stdio-common/tst-freopen3-main.c b/stdio-common/tst-freopen3-main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5107e1f98e189e4b
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen3-main.c
|
||||
@@ -0,0 +1,90 @@
|
||||
+/* Test freopen failure.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/descriptors.h>
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+#define START_TEST(DESC) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ fds = support_descriptors_list (); \
|
||||
+ verbose_printf (DESC); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define END_TEST \
|
||||
+ do \
|
||||
+ { \
|
||||
+ support_descriptors_check (fds); \
|
||||
+ support_descriptors_free (fds); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct support_descriptors *fds;
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen3");
|
||||
+ char *file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ add_temp_file (file1);
|
||||
+ char *file2 = xasprintf ("%s/file2", temp_dir);
|
||||
+ support_write_file_string (file2, "file2");
|
||||
+ add_temp_file (file2);
|
||||
+ char *file_nodir = xasprintf ("%s/nodir/file", temp_dir);
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+ int fd;
|
||||
+
|
||||
+ START_TEST ("Testing w -> wx (file exists)\n");
|
||||
+ fp = xfopen (file1, "w");
|
||||
+ fp = FREOPEN (file2, "wx", fp);
|
||||
+ TEST_VERIFY (fp == NULL);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* Test old file is closed even when opening the new file fails. */
|
||||
+
|
||||
+ START_TEST ("testing r -> r (opening new file fails)\n");
|
||||
+ fp = xfopen (file1, "r");
|
||||
+ fd = fileno (fp);
|
||||
+ fp = FREOPEN (file_nodir, "r", fp);
|
||||
+ TEST_VERIFY (fp == NULL);
|
||||
+ errno = 0;
|
||||
+ ret = fcntl (fd, F_GETFL);
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ free (file2);
|
||||
+ free (file_nodir);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen3.c b/stdio-common/tst-freopen3.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5041b6b2332c8af1
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen3.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen
|
||||
+#include <tst-freopen3-main.c>
|
||||
diff --git a/stdio-common/tst-freopen64-2.c b/stdio-common/tst-freopen64-2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..88fdc64d8c6548f5
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen64-2.c
|
||||
@@ -0,0 +1,3 @@
|
||||
+#define FREOPEN freopen64
|
||||
+#define OTHER_FREOPEN freopen
|
||||
+#include <tst-freopen2-main.c>
|
||||
diff --git a/stdio-common/tst-freopen64-3.c b/stdio-common/tst-freopen64-3.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b91b6d2c033a1a79
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen64-3.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen64
|
||||
+#include <tst-freopen3-main.c>
|
69
SOURCES/glibc-RHEL-46736-5.patch
Normal file
69
SOURCES/glibc-RHEL-46736-5.patch
Normal file
@ -0,0 +1,69 @@
|
||||
commit f512634ddef242ef0ff025ddeba64ce51035040f
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Thu Sep 5 11:15:29 2024 +0000
|
||||
|
||||
Clear flags2 flags set from mode in freopen (bug 32134)
|
||||
|
||||
As reported in bug 32134, freopen does not clear the flags set in
|
||||
fp->_flags2 by the "e", "m" or "c" mode characters. Clear these so
|
||||
that they can be set or not as appropriate from the mode string passed
|
||||
to freopen. The relevant test for "e" in tst-freopen2-main.c is
|
||||
enabled accordingly; "c" is expected to be covered in a separately
|
||||
written test (and while tst-freopen2-main.c does include transitions
|
||||
to and from "m", that's not really a semantic flag intended to result
|
||||
in behaving in an observably different way).
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/libio/freopen.c b/libio/freopen.c
|
||||
index c947a5aecfde3c80..bed034d89441f200 100644
|
||||
--- a/libio/freopen.c
|
||||
+++ b/libio/freopen.c
|
||||
@@ -63,6 +63,9 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
up here. */
|
||||
_IO_old_file_close_it (fp);
|
||||
_IO_JUMPS_FUNC_UPDATE (fp, &_IO_old_file_jumps);
|
||||
+ fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
+ | _IO_FLAGS2_NOTCANCEL
|
||||
+ | _IO_FLAGS2_CLOEXEC);
|
||||
result = _IO_old_file_fopen (fp, gfilename, mode);
|
||||
}
|
||||
else
|
||||
@@ -72,6 +75,9 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
|
||||
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
|
||||
fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
|
||||
+ fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
+ | _IO_FLAGS2_NOTCANCEL
|
||||
+ | _IO_FLAGS2_CLOEXEC);
|
||||
result = _IO_file_fopen (fp, gfilename, mode, 1);
|
||||
if (result != NULL)
|
||||
result = __fopen_maybe_mmap (result);
|
||||
diff --git a/libio/freopen64.c b/libio/freopen64.c
|
||||
index fb02c201bd83c401..9a314c65c1d8a5a4 100644
|
||||
--- a/libio/freopen64.c
|
||||
+++ b/libio/freopen64.c
|
||||
@@ -56,6 +56,9 @@ freopen64 (const char *filename, const char *mode, FILE *fp)
|
||||
_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
|
||||
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
|
||||
fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
|
||||
+ fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
+ | _IO_FLAGS2_NOTCANCEL
|
||||
+ | _IO_FLAGS2_CLOEXEC);
|
||||
result = _IO_file_fopen (fp, gfilename, mode, 0);
|
||||
fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
|
||||
if (result != NULL)
|
||||
diff --git a/stdio-common/tst-freopen2-main.c b/stdio-common/tst-freopen2-main.c
|
||||
index 22b21afebf709563..5dad41c76b02e6de 100644
|
||||
--- a/stdio-common/tst-freopen2-main.c
|
||||
+++ b/stdio-common/tst-freopen2-main.c
|
||||
@@ -308,9 +308,7 @@ do_test (void)
|
||||
TEST_VERIFY_EXIT (fp != NULL);
|
||||
ret = fcntl (fileno (fp), F_GETFD);
|
||||
TEST_VERIFY (ret != -1);
|
||||
-#if 0 /* Fails to clear FD_CLOEXEC (bug 32134). */
|
||||
TEST_COMPARE (ret & FD_CLOEXEC, 0);
|
||||
-#endif
|
||||
TEST_COMPARE_FILE_STRING (fp, "plustomore");
|
||||
xfclose (fp);
|
||||
END_TEST;
|
119
SOURCES/glibc-RHEL-46736-6.patch
Normal file
119
SOURCES/glibc-RHEL-46736-6.patch
Normal file
@ -0,0 +1,119 @@
|
||||
commit 9c0d6f7a1046aba111e25e34ec07242853e859dc
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Thu Sep 5 11:16:59 2024 +0000
|
||||
|
||||
Fix memory leak on freopen error return (bug 32140)
|
||||
|
||||
As reported in bug 32140, freopen leaks the FILE object when it
|
||||
returns NULL: there is no valid use of the FILE * pointer (including
|
||||
passing to freopen again or to fclose) after such an error return, so
|
||||
the underlying object should be freed. Add code to free it.
|
||||
|
||||
Note 1: while I think it's clear from the relevant standards that the
|
||||
object should be freed and the FILE * can't be used after the call in
|
||||
this case (the stream is closed, which ends the lifetime of the FILE),
|
||||
it's entirely possible that some existing code does in fact try to use
|
||||
the existing FILE * in some way and could be broken by this change.
|
||||
(Though the most common case for freopen may be stdin / stdout /
|
||||
stderr, which _IO_deallocate_file explicitly checks for and does not
|
||||
deallocate.)
|
||||
|
||||
Note 2: the deallocation is only done in the _IO_IS_FILEBUF case.
|
||||
Other kinds of streams bypass all the freopen logic handling closing
|
||||
the file, meaning a call to _IO_deallocate_file would neither be safe
|
||||
(the FILE might still be linked into the list of all open FILEs) nor
|
||||
sufficient (other internal memory allocations associated with the file
|
||||
would not have been freed). I think the validity of freopen for any
|
||||
other kind of stream will need clarifying with the Austin Group, but
|
||||
if it is valid in any such case (where "valid" means "not undefined
|
||||
behavior so required to close the stream" rather than "required to
|
||||
successfully associate the stream with the new file in cases where
|
||||
fopen would work"), more significant changes would be needed to ensure
|
||||
the stream gets fully closed.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/libio/freopen.c b/libio/freopen.c
|
||||
index bed034d89441f200..03f8961a61b12e80 100644
|
||||
--- a/libio/freopen.c
|
||||
+++ b/libio/freopen.c
|
||||
@@ -114,5 +114,7 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
|
||||
end:
|
||||
_IO_release_lock (fp);
|
||||
+ if (result == NULL && (fp->_flags & _IO_IS_FILEBUF) != 0)
|
||||
+ _IO_deallocate_file (fp);
|
||||
return result;
|
||||
}
|
||||
diff --git a/libio/freopen64.c b/libio/freopen64.c
|
||||
index 9a314c65c1d8a5a4..abcbd80a5bd92e69 100644
|
||||
--- a/libio/freopen64.c
|
||||
+++ b/libio/freopen64.c
|
||||
@@ -94,5 +94,7 @@ freopen64 (const char *filename, const char *mode, FILE *fp)
|
||||
|
||||
end:
|
||||
_IO_release_lock (fp);
|
||||
+ if (result == NULL && (fp->_flags & _IO_IS_FILEBUF) != 0)
|
||||
+ _IO_deallocate_file (fp);
|
||||
return result;
|
||||
}
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 5eddc4bfbf4e7fb9..bd3c785537ba0330 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -251,7 +251,9 @@ ifeq (yes,$(build-shared))
|
||||
ifneq ($(PERL),no)
|
||||
tests-special += \
|
||||
$(objpfx)tst-freopen2-mem.out \
|
||||
+ $(objpfx)tst-freopen3-mem.out \
|
||||
$(objpfx)tst-freopen64-2-mem.out \
|
||||
+ $(objpfx)tst-freopen64-3-mem.out \
|
||||
$(objpfx)tst-getline-enomem-mem.out \
|
||||
$(objpfx)tst-getline-mem.out \
|
||||
$(objpfx)tst-printf-bz18872-mem.out \
|
||||
@@ -264,8 +266,12 @@ tests-special += \
|
||||
generated += \
|
||||
tst-freopen2-mem.out \
|
||||
tst-freopen2.mtrace \
|
||||
+ tst-freopen3-mem.out \
|
||||
+ tst-freopen3.mtrace \
|
||||
tst-freopen64-2-mem.out \
|
||||
tst-freopen64-2.mtrace \
|
||||
+ tst-freopen64-3-mem.out \
|
||||
+ tst-freopen64-3.mtrace \
|
||||
tst-getline-enomem-mem.out \
|
||||
tst-getline-enomem.mtrace \
|
||||
tst-getline-mem.out \
|
||||
@@ -344,6 +350,12 @@ tst-freopen2-ENV = \
|
||||
tst-freopen64-2-ENV = \
|
||||
MALLOC_TRACE=$(objpfx)tst-freopen64-2.mtrace \
|
||||
LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen3-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen3.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen64-3-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen64-3.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
|
||||
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
|
||||
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
|
||||
diff --git a/stdio-common/tst-freopen3-main.c b/stdio-common/tst-freopen3-main.c
|
||||
index 5107e1f98e189e4b..990a6e5921843793 100644
|
||||
--- a/stdio-common/tst-freopen3-main.c
|
||||
+++ b/stdio-common/tst-freopen3-main.c
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
+#include <mcheck.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -48,6 +49,7 @@
|
||||
int
|
||||
do_test (void)
|
||||
{
|
||||
+ mtrace ();
|
||||
struct support_descriptors *fds;
|
||||
char *temp_dir = support_create_temp_directory ("tst-freopen3");
|
||||
char *file1 = xasprintf ("%s/file1", temp_dir);
|
86
SOURCES/glibc-RHEL-46736-7.patch
Normal file
86
SOURCES/glibc-RHEL-46736-7.patch
Normal file
@ -0,0 +1,86 @@
|
||||
commit e44ca1c085b3bd41266c882ea1cb0fd436231635
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Thu Sep 5 20:08:10 2024 +0000
|
||||
|
||||
Fix freopen handling of ,ccs= (bug 23675)
|
||||
|
||||
As reported in bug 23675 and shown up in the recently added tests of
|
||||
different cases of freopen (relevant part of the test currently
|
||||
conditioned under #if 0 to avoid a failure resulting from this bug),
|
||||
freopen wrongly forces the stream to unoriented even when a mode with
|
||||
,ccs= is specified, though such a mode is supposed to result in a
|
||||
wide-oriented stream. Move the clearing of _mode to before the actual
|
||||
reopening occurs, so that the main fopen implementation can leave a
|
||||
wide-oriented stream in the ,ccs= case.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/libio/freopen.c b/libio/freopen.c
|
||||
index 03f8961a61b12e80..d71a4cfffdc35280 100644
|
||||
--- a/libio/freopen.c
|
||||
+++ b/libio/freopen.c
|
||||
@@ -66,6 +66,7 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
| _IO_FLAGS2_NOTCANCEL
|
||||
| _IO_FLAGS2_CLOEXEC);
|
||||
+ fp->_mode = 0;
|
||||
result = _IO_old_file_fopen (fp, gfilename, mode);
|
||||
}
|
||||
else
|
||||
@@ -78,6 +79,7 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
| _IO_FLAGS2_NOTCANCEL
|
||||
| _IO_FLAGS2_CLOEXEC);
|
||||
+ fp->_mode = 0;
|
||||
result = _IO_file_fopen (fp, gfilename, mode, 1);
|
||||
if (result != NULL)
|
||||
result = __fopen_maybe_mmap (result);
|
||||
@@ -85,9 +87,6 @@ freopen (const char *filename, const char *mode, FILE *fp)
|
||||
fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
|
||||
if (result != NULL)
|
||||
{
|
||||
- /* unbound stream orientation */
|
||||
- result->_mode = 0;
|
||||
-
|
||||
if (fd != -1 && _IO_fileno (result) != fd)
|
||||
{
|
||||
/* At this point we have both file descriptors already allocated,
|
||||
diff --git a/libio/freopen64.c b/libio/freopen64.c
|
||||
index abcbd80a5bd92e69..64af2c5f7c80a3e9 100644
|
||||
--- a/libio/freopen64.c
|
||||
+++ b/libio/freopen64.c
|
||||
@@ -59,15 +59,13 @@ freopen64 (const char *filename, const char *mode, FILE *fp)
|
||||
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
|
||||
| _IO_FLAGS2_NOTCANCEL
|
||||
| _IO_FLAGS2_CLOEXEC);
|
||||
+ fp->_mode = 0;
|
||||
result = _IO_file_fopen (fp, gfilename, mode, 0);
|
||||
fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
|
||||
if (result != NULL)
|
||||
result = __fopen_maybe_mmap (result);
|
||||
if (result != NULL)
|
||||
{
|
||||
- /* unbound stream orientation */
|
||||
- result->_mode = 0;
|
||||
-
|
||||
if (fd != -1 && _IO_fileno (result) != fd)
|
||||
{
|
||||
/* At this point we have both file descriptors already allocated,
|
||||
diff --git a/stdio-common/tst-freopen2-main.c b/stdio-common/tst-freopen2-main.c
|
||||
index 5dad41c76b02e6de..74c3125fca697fe3 100644
|
||||
--- a/stdio-common/tst-freopen2-main.c
|
||||
+++ b/stdio-common/tst-freopen2-main.c
|
||||
@@ -386,13 +386,8 @@ do_test (void)
|
||||
fp = xfopen (file2, "w,ccs=iso-8859-1");
|
||||
ret = fputws (L"\xc0\xc1", fp);
|
||||
TEST_VERIFY (ret >= 0);
|
||||
-#if 0 /* Doesn't work (bug 23675). */
|
||||
fp = FREOPEN (file1, "r,ccs=utf-8", fp);
|
||||
TEST_VERIFY_EXIT (fp != NULL);
|
||||
-#else /* Works instead. */
|
||||
- xfclose (fp);
|
||||
- fp = xfopen (file1, "r,ccs=utf-8");
|
||||
-#endif
|
||||
wc = fgetwc (fp);
|
||||
TEST_COMPARE (wc, (wint_t) 0xc0);
|
||||
wc = fgetwc (fp);
|
33
SOURCES/glibc-RHEL-46736-8.patch
Normal file
33
SOURCES/glibc-RHEL-46736-8.patch
Normal file
@ -0,0 +1,33 @@
|
||||
commit a2509a8bc955988f01f389a1cf74db3a9da42409
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 6 20:38:23 2024 +0000
|
||||
|
||||
Document limitations on streams passed to freopen
|
||||
|
||||
As recently discussed, document that freopen does not work with
|
||||
streams opened with functions such as popen, fmemopen, open_memstream
|
||||
or fopencookie. I've filed
|
||||
<https://austingroupbugs.net/view.php?id=1855> to clarify this issue
|
||||
in POSIX.
|
||||
|
||||
Tested with "make info" and "make html".
|
||||
|
||||
diff --git a/manual/stdio.texi b/manual/stdio.texi
|
||||
index 60ab7e7a5d505bb6..a2d9292a787b9fa3 100644
|
||||
--- a/manual/stdio.texi
|
||||
+++ b/manual/stdio.texi
|
||||
@@ -330,6 +330,14 @@ this ability, so using @code{freopen} is more portable.
|
||||
When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
|
||||
32 bit machine this function is in fact @code{freopen64} since the LFS
|
||||
interface replaces transparently the old interface.
|
||||
+
|
||||
+@Theglibc{} only supports use of @code{freopen} on streams opened with
|
||||
+@code{fopen} or @code{fopen64} and on the original values of the
|
||||
+standard streams @code{stdin}, @code{stdout}, and @code{stderr}; such
|
||||
+a stream may be reopened multiple times with @code{freopen}. If it is
|
||||
+called on another kind of stream (opened with functions such as
|
||||
+@code{popen}, @code{fmemopen}, @code{open_memstream}, and
|
||||
+@code{fopencookie}), @code{freopen} fails and returns a null pointer.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
|
495
SOURCES/glibc-RHEL-46736-9.patch
Normal file
495
SOURCES/glibc-RHEL-46736-9.patch
Normal file
@ -0,0 +1,495 @@
|
||||
commit e0f3bf10acf4aab27752847828bfecd3fce41190
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:26:31 2024 +0000
|
||||
|
||||
Add freopen special-case tests: chroot, EFBIG, stdin/stdout/stderr
|
||||
|
||||
Add tests of special cases for freopen that were omitted from the more
|
||||
general tests of different modes and similar issues. The special
|
||||
cases in the three tests here are logically unconnected, it was simply
|
||||
convenient to put these tests in one patch.
|
||||
|
||||
* Test freopen with a NULL path to the new file, in a chroot. Rather
|
||||
than asserting that this fails (logically, failure in this case is
|
||||
an implementation detail; it's not required for freopen to rely on
|
||||
/proc), verify that either it fails (without memory leaks) or that
|
||||
it succeeds and behaves as expected on success. There is no check
|
||||
for file descriptor leaks because the machinery for that also
|
||||
depends on /proc, so can't be used in a chroot.
|
||||
|
||||
* Test that freopen and freopen64 are genuinely different in
|
||||
configurations with 32-bit off_t by checking for an EFBIG trying to
|
||||
write past 2GB in a file opened with freopen in such a configuration
|
||||
but no error with 64-bit off_t or when opening with freopen64.
|
||||
|
||||
* Test freopen of stdin, stdout and stderr.
|
||||
|
||||
Tested for x86_64 and x86.
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index bd3c785537ba0330..c920f55ed2119900 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -177,8 +177,13 @@ tests := \
|
||||
tst-fread \
|
||||
tst-freopen2 \
|
||||
tst-freopen3 \
|
||||
+ tst-freopen4 \
|
||||
+ tst-freopen5 \
|
||||
+ tst-freopen6 \
|
||||
tst-freopen64-2 \
|
||||
tst-freopen64-3 \
|
||||
+ tst-freopen64-4 \
|
||||
+ tst-freopen64-6 \
|
||||
tst-fseek \
|
||||
tst-fwrite \
|
||||
tst-getline \
|
||||
@@ -252,8 +257,13 @@ ifneq ($(PERL),no)
|
||||
tests-special += \
|
||||
$(objpfx)tst-freopen2-mem.out \
|
||||
$(objpfx)tst-freopen3-mem.out \
|
||||
+ $(objpfx)tst-freopen4-mem.out \
|
||||
+ $(objpfx)tst-freopen5-mem.out \
|
||||
+ $(objpfx)tst-freopen6-mem.out \
|
||||
$(objpfx)tst-freopen64-2-mem.out \
|
||||
$(objpfx)tst-freopen64-3-mem.out \
|
||||
+ $(objpfx)tst-freopen64-4-mem.out \
|
||||
+ $(objpfx)tst-freopen64-6-mem.out \
|
||||
$(objpfx)tst-getline-enomem-mem.out \
|
||||
$(objpfx)tst-getline-mem.out \
|
||||
$(objpfx)tst-printf-bz18872-mem.out \
|
||||
@@ -268,10 +278,20 @@ generated += \
|
||||
tst-freopen2.mtrace \
|
||||
tst-freopen3-mem.out \
|
||||
tst-freopen3.mtrace \
|
||||
+ tst-freopen4-mem.out \
|
||||
+ tst-freopen4.mtrace \
|
||||
+ tst-freopen5-mem.out \
|
||||
+ tst-freopen5.mtrace \
|
||||
+ tst-freopen6-mem.out \
|
||||
+ tst-freopen6.mtrace \
|
||||
tst-freopen64-2-mem.out \
|
||||
tst-freopen64-2.mtrace \
|
||||
tst-freopen64-3-mem.out \
|
||||
tst-freopen64-3.mtrace \
|
||||
+ tst-freopen64-4-mem.out \
|
||||
+ tst-freopen64-4.mtrace \
|
||||
+ tst-freopen64-6-mem.out \
|
||||
+ tst-freopen64-6.mtrace \
|
||||
tst-getline-enomem-mem.out \
|
||||
tst-getline-enomem.mtrace \
|
||||
tst-getline-mem.out \
|
||||
@@ -356,6 +376,21 @@ tst-freopen3-ENV = \
|
||||
tst-freopen64-3-ENV = \
|
||||
MALLOC_TRACE=$(objpfx)tst-freopen64-3.mtrace \
|
||||
LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen4-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen4.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen64-4-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen64-4.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen5-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen5.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen6-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen6.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
+tst-freopen64-6-ENV = \
|
||||
+ MALLOC_TRACE=$(objpfx)tst-freopen64-6.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||
|
||||
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
|
||||
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
|
||||
diff --git a/stdio-common/tst-freopen4-main.c b/stdio-common/tst-freopen4-main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e169442cf4df2e9d
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen4-main.c
|
||||
@@ -0,0 +1,100 @@
|
||||
+/* Test freopen in chroot.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <mcheck.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/namespace.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen4");
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* These chroot tests verify that either reopening a renamed or
|
||||
+ deleted file works even in the absence of /proc, or that it fails
|
||||
+ (without memory leaks); thus, for example, such reopening does
|
||||
+ not crash in the absence of /proc. */
|
||||
+
|
||||
+ support_become_root ();
|
||||
+ if (!support_can_chroot ())
|
||||
+ return EXIT_UNSUPPORTED;
|
||||
+ xchroot (temp_dir);
|
||||
+
|
||||
+ /* Test freopen with NULL, renamed file. This verifies that
|
||||
+ reopening succeeds (and resets the file position indicator to
|
||||
+ start of file) even when the original path could no longer be
|
||||
+ opened, or fails without a memory leak. (It is not possible to
|
||||
+ use <support/descriptors.h> to test for file descriptor leaks
|
||||
+ here, because that also depends on /proc.) */
|
||||
+
|
||||
+ verbose_printf ("testing freopen with NULL, renamed file\n");
|
||||
+ fp = xfopen ("/file1", "w+");
|
||||
+ ret = fputs ("file has been renamed", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = rename ("/file1", "/file1a");
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ fp = FREOPEN (NULL, "r+", fp);
|
||||
+ if (fp != NULL)
|
||||
+ {
|
||||
+ puts ("freopen of renamed file succeeded");
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "file has been renamed");
|
||||
+ xfclose (fp);
|
||||
+ }
|
||||
+ else
|
||||
+ puts ("freopen of renamed file failed (OK)");
|
||||
+ ret = rename ("/file1a", "/file1");
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+
|
||||
+ /* Test freopen with NULL, deleted file. This verifies that
|
||||
+ reopening succeeds (and resets the file position indicator to
|
||||
+ start of file) even when the original path could no longer be
|
||||
+ opened, or fails without a memory leak. */
|
||||
+
|
||||
+ verbose_printf ("testing freopen with NULL, deleted file\n");
|
||||
+ fp = xfopen ("/file1", "r+");
|
||||
+ ret = fputs ("file has now been deleted", fp);
|
||||
+ TEST_VERIFY (ret >= 0);
|
||||
+ ret = remove ("/file1");
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ fp = FREOPEN (NULL, "r+", fp);
|
||||
+ if (fp != NULL)
|
||||
+ {
|
||||
+ puts ("freopen of deleted file succeeded");
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "file has now been deleted");
|
||||
+ xfclose (fp);
|
||||
+ }
|
||||
+ else
|
||||
+ puts ("freopen of deleted file failed (OK)");
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen4.c b/stdio-common/tst-freopen4.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f39ec0d21730879f
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen4.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen
|
||||
+#include <tst-freopen4-main.c>
|
||||
diff --git a/stdio-common/tst-freopen5.c b/stdio-common/tst-freopen5.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f32626bccfe5c10a
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen5.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/* Test freopen and freopen64 with large offsets.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <mcheck.h>
|
||||
+#include <stdio.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/xstdio.h>
|
||||
+
|
||||
+#define START_TEST(DESC) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ fds = support_descriptors_list (); \
|
||||
+ verbose_printf (DESC); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define END_TEST \
|
||||
+ do \
|
||||
+ { \
|
||||
+ support_descriptors_check (fds); \
|
||||
+ support_descriptors_free (fds); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+ struct support_descriptors *fds;
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen5");
|
||||
+ /* This file is removed at the end of each test rather than left
|
||||
+ around between tests to avoid problems with subsequent tests
|
||||
+ reopening it as a large (2GB + 1 byte) file. */
|
||||
+ char *file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+
|
||||
+ /* fopen with freopen64: large offsets OK. */
|
||||
+ START_TEST ("testing fopen with freopen64\n");
|
||||
+ fp = fopen ("/dev/null", "r");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ fp = freopen64 (file1, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ setbuf (fp, NULL);
|
||||
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ ret = fputc ('x', fp);
|
||||
+ TEST_COMPARE (ret, 'x');
|
||||
+ xfclose (fp);
|
||||
+ ret = remove (file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* fopen64 with freopen64: large offsets OK. */
|
||||
+ START_TEST ("testing fopen64 with freopen64\n");
|
||||
+ fp = fopen64 ("/dev/null", "r");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ fp = freopen64 (file1, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ setbuf (fp, NULL);
|
||||
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ ret = fputc ('x', fp);
|
||||
+ TEST_COMPARE (ret, 'x');
|
||||
+ xfclose (fp);
|
||||
+ ret = remove (file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* fopen with freopen: large offsets not OK on 32-bit systems. */
|
||||
+ START_TEST ("testing fopen with freopen\n");
|
||||
+ fp = fopen ("/dev/null", "r");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ fp = freopen (file1, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ setbuf (fp, NULL);
|
||||
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ errno = 0;
|
||||
+ ret = fputc ('x', fp);
|
||||
+ if (sizeof (off_t) == 4)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, EOF);
|
||||
+ TEST_COMPARE (errno, EFBIG);
|
||||
+ }
|
||||
+ else
|
||||
+ TEST_COMPARE (ret, 'x');
|
||||
+ fclose (fp);
|
||||
+ ret = remove (file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ /* fopen64 with freopen: large offsets not OK on 32-bit systems. */
|
||||
+ START_TEST ("testing fopen64 with freopen\n");
|
||||
+ fp = fopen64 ("/dev/null", "r");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ fp = freopen (file1, "w", fp);
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ setbuf (fp, NULL);
|
||||
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ errno = 0;
|
||||
+ ret = fputc ('x', fp);
|
||||
+ if (sizeof (off_t) == 4)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, EOF);
|
||||
+ TEST_COMPARE (errno, EFBIG);
|
||||
+ }
|
||||
+ else
|
||||
+ TEST_COMPARE (ret, 'x');
|
||||
+ fclose (fp);
|
||||
+ ret = remove (file1);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ END_TEST;
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen6-main.c b/stdio-common/tst-freopen6-main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f493f42fd7486b72
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen6-main.c
|
||||
@@ -0,0 +1,98 @@
|
||||
+/* Test freopen of stdin / stdout / stderr.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <mcheck.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/file_contents.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+ char *temp_dir = support_create_temp_directory ("tst-freopen6");
|
||||
+ char *file1 = xasprintf ("%s/file1", temp_dir);
|
||||
+ support_write_file_string (file1, "file1");
|
||||
+ add_temp_file (file1);
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+
|
||||
+ verbose_printf ("Testing reopening stdin\n");
|
||||
+ fp = FREOPEN (file1, "r", stdin);
|
||||
+ TEST_VERIFY_EXIT (fp == stdin);
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, 'f');
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, 'i');
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, 'l');
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, 'e');
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, '1');
|
||||
+ ret = getchar ();
|
||||
+ TEST_COMPARE (ret, EOF);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("Testing reopening stderr\n");
|
||||
+ fp = FREOPEN (file1, "w+", stderr);
|
||||
+ TEST_VERIFY_EXIT (fp == stderr);
|
||||
+ errno = EINVAL;
|
||||
+ perror ("test");
|
||||
+ ret = fseek (fp, 0, SEEK_SET);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_COMPARE_FILE_STRING (fp, "test: Invalid argument\n");
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ verbose_printf ("Testing reopening stdout\n");
|
||||
+ /* Defer checks until the old stdout has been restored to make it
|
||||
+ more likely any errors are written to the old stdout (rather than
|
||||
+ the temporary file used for the redirected stdout). */
|
||||
+ int old_stdout = dup (STDOUT_FILENO);
|
||||
+ TEST_VERIFY_EXIT (old_stdout != -1);
|
||||
+ int ret_fseek = 0;
|
||||
+ int ret_compare = 0;
|
||||
+ fp = FREOPEN (file1, "w+", stdout);
|
||||
+ int fp_eq_stdout = fp == stdout;
|
||||
+ if (fp != NULL)
|
||||
+ {
|
||||
+ printf ("reopened\n");
|
||||
+ ret_fseek = fseek (fp, 0, SEEK_SET);
|
||||
+ ret_compare = support_compare_file_string (fp, "reopened\n");
|
||||
+ }
|
||||
+ xfclose (fp);
|
||||
+ stdout = fdopen (old_stdout, "w");
|
||||
+ TEST_VERIFY (fp_eq_stdout);
|
||||
+ TEST_COMPARE (ret_fseek, 0);
|
||||
+ TEST_COMPARE (ret_compare, 0);
|
||||
+ xfclose (stdout);
|
||||
+
|
||||
+ free (temp_dir);
|
||||
+ free (file1);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/stdio-common/tst-freopen6.c b/stdio-common/tst-freopen6.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8fd6957b54fa9bc2
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen6.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen
|
||||
+#include <tst-freopen6-main.c>
|
||||
diff --git a/stdio-common/tst-freopen64-4.c b/stdio-common/tst-freopen64-4.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1411be2bfa0105c1
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen64-4.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen64
|
||||
+#include <tst-freopen4-main.c>
|
||||
diff --git a/stdio-common/tst-freopen64-6.c b/stdio-common/tst-freopen64-6.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3ec509a36c2471f6
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-freopen64-6.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define FREOPEN freopen64
|
||||
+#include <tst-freopen6-main.c>
|
34
SOURCES/glibc-RHEL-46738-1.patch
Normal file
34
SOURCES/glibc-RHEL-46738-1.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 53fcdf5f743aa9b02972eec658e66f96d6a63386 Mon Sep 17 00:00:00 2001
|
||||
From: Alejandro Colomar <alx@kernel.org>
|
||||
Date: Sat, 16 Nov 2024 16:51:31 +0100
|
||||
Subject: Silence most -Wzero-as-null-pointer-constant diagnostics
|
||||
|
||||
Replace 0 by NULL and {0} by {}.
|
||||
|
||||
Omit a few cases that aren't so trivial to fix.
|
||||
|
||||
Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
|
||||
Link: <https://software.codidact.com/posts/292718/292759#answer-292759>
|
||||
Signed-off-by: Alejandro Colomar <alx@kernel.org>
|
||||
|
||||
Conflicts
|
||||
All except libioP.h
|
||||
Removed - unneeded, wouldn't apply
|
||||
|
||||
diff --git a/libio/libioP.h b/libio/libioP.h
|
||||
index a83a411fdf..34bf91fcd8 100644
|
||||
--- a/libio/libioP.h
|
||||
+++ b/libio/libioP.h
|
||||
@@ -915,9 +915,10 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
|
||||
# else
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \
|
||||
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\
|
||||
- NULL, WDP, 0 }
|
||||
+ NULL, WDP, NULL }
|
||||
# endif
|
||||
#else
|
||||
# ifdef _IO_USE_OLD_IO_FILE
|
52
SOURCES/glibc-RHEL-46738-2.patch
Normal file
52
SOURCES/glibc-RHEL-46738-2.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From bd0ea9ff7e8d5f7d54112dfa96d541c3c60e36ae Mon Sep 17 00:00:00 2001
|
||||
From: Alejandro Colomar <alx@kernel.org>
|
||||
Date: Tue, 17 Dec 2024 00:22:19 +0100
|
||||
Subject: libio: Use NULL instead of 0 as a null pointer constant
|
||||
|
||||
This was missed in a recent global change.
|
||||
|
||||
Fixes: 53fcdf5f743a (2024-11-25, "Silence most -Wzero-as-null-pointer-constant diagnostics")
|
||||
Reported-by: "Maciej W. Rozycki" <macro@redhat.com>
|
||||
Cc: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Cc: Bruno Haible <bruno@clisp.org>
|
||||
Cc: Martin Uecker <uecker@tugraz.at>
|
||||
Cc: Xi Ruoyao <xry111@xry111.site>
|
||||
Cc: Florian Weimer <fweimer@redhat.com>
|
||||
Cc: Joseph Myers <josmyers@redhat.com>
|
||||
Signed-off-by: Alejandro Colomar <alx@kernel.org>
|
||||
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
|
||||
|
||||
diff --git a/libio/libioP.h b/libio/libioP.h
|
||||
index 34bf91fcd8..70e2bdfc9d 100644
|
||||
--- a/libio/libioP.h
|
||||
+++ b/libio/libioP.h
|
||||
@@ -910,7 +910,8 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
|
||||
# ifdef _IO_USE_OLD_IO_FILE
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \
|
||||
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
|
||||
# else
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
@@ -924,14 +925,16 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
|
||||
# ifdef _IO_USE_OLD_IO_FILE
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \
|
||||
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
0, _IO_pos_BAD }
|
||||
# else
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \
|
||||
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \
|
||||
- NULL, WDP, 0 }
|
||||
+ NULL, WDP, NULL }
|
||||
# endif
|
||||
#endif
|
||||
|
21
SOURCES/glibc-RHEL-46738-3.patch
Normal file
21
SOURCES/glibc-RHEL-46738-3.patch
Normal file
@ -0,0 +1,21 @@
|
||||
From cfdd9e7aa45cdc575df237e2d2eee3219a06829b Mon Sep 17 00:00:00 2001
|
||||
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Tue, 17 Dec 2024 17:36:36 -0500
|
||||
Subject: libio: Fix last NULL-as-0 issue in libioP.h
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
|
||||
|
||||
diff --git a/libio/libioP.h b/libio/libioP.h
|
||||
index 70e2bdfc9d..ad45579e13 100644
|
||||
--- a/libio/libioP.h
|
||||
+++ b/libio/libioP.h
|
||||
@@ -933,7 +933,7 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
- 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \
|
||||
+ 0, _IO_pos_BAD, 0, 0, { 0 }, NULL, _IO_pos_BAD, \
|
||||
NULL, WDP, NULL }
|
||||
# endif
|
||||
#endif
|
405
SOURCES/glibc-RHEL-46738-4.patch
Normal file
405
SOURCES/glibc-RHEL-46738-4.patch
Normal file
@ -0,0 +1,405 @@
|
||||
From ae5062201d7e9d18fe88bff4bc71088374c394fb Mon Sep 17 00:00:00 2001
|
||||
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Thu, 7 Nov 2024 11:16:04 -0500
|
||||
Subject: ungetc: Guarantee single char pushback
|
||||
|
||||
The C standard requires that ungetc guarantees at least one pushback,
|
||||
but the malloc call to allocate the pushback buffer could fail, thus
|
||||
violating that requirement. Fix this by adding a single byte pushback
|
||||
buffer in the FILE struct that the pushback can fall back to if malloc
|
||||
fails.
|
||||
|
||||
The side-effect is that if the initial malloc fails and the 1-byte
|
||||
fallback buffer is used, future resizing (if it succeeds) will be
|
||||
2-bytes, 4-bytes and so on, which is suboptimal but it's after a malloc
|
||||
failure, so maybe even desirable.
|
||||
|
||||
A future optimization here could be to have the pushback code use the
|
||||
single byte buffer first and only fall back to malloc for subsequent
|
||||
calls.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
libio/bits/types/struct_FILE.h
|
||||
libio/fileops.c
|
||||
libio/genops.c
|
||||
libio/libioP.h
|
||||
libio/oldfileops.c
|
||||
libio/wfileops.c
|
||||
stdio-common/Makefile
|
||||
Copyright year conflicts in all files
|
||||
Rebase for altered context and line numbers
|
||||
|
||||
diff -rupN a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h
|
||||
--- a/libio/bits/types/struct_FILE.h 2021-08-01 21:33:43.000000000 -0400
|
||||
+++ b/libio/bits/types/struct_FILE.h 2024-12-19 00:34:04.289351714 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -70,7 +71,9 @@ struct _IO_FILE
|
||||
struct _IO_FILE *_chain;
|
||||
|
||||
int _fileno;
|
||||
- int _flags2;
|
||||
+ int _flags2:24;
|
||||
+ /* Fallback buffer to use when malloc fails to allocate one. */
|
||||
+ char _short_backupbuf[1];
|
||||
__off_t _old_offset; /* This used to be _offset but it's too small. */
|
||||
|
||||
/* 1+column number of pbase(); 0 is unknown. */
|
||||
diff -rupN a/libio/fileops.c b/libio/fileops.c
|
||||
--- a/libio/fileops.c 2021-08-01 21:33:43.000000000 -0400
|
||||
+++ b/libio/fileops.c 2024-12-19 00:34:04.294351763 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Per Bothner <bothner@cygnus.com>.
|
||||
|
||||
@@ -480,7 +481,7 @@ _IO_new_file_underflow (FILE *fp)
|
||||
/* Maybe we already have a push back pointer. */
|
||||
if (fp->_IO_save_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
@@ -932,7 +933,7 @@ _IO_new_file_seekoff (FILE *fp, off64_t
|
||||
/* It could be that we already have a pushback buffer. */
|
||||
if (fp->_IO_read_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_read_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_read_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
@@ -1282,7 +1283,7 @@ _IO_file_xsgetn (FILE *fp, void *data, s
|
||||
/* Maybe we already have a push back pointer. */
|
||||
if (fp->_IO_save_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
diff -rupN a/libio/genops.c b/libio/genops.c
|
||||
--- a/libio/genops.c 2024-12-18 23:17:35.150703172 -0500
|
||||
+++ b/libio/genops.c 2024-12-19 00:34:04.300351821 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -187,7 +188,7 @@ _IO_free_backup_area (FILE *fp)
|
||||
{
|
||||
if (_IO_in_backup (fp))
|
||||
_IO_switch_to_main_get_area (fp); /* Just in case. */
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_IO_save_base = NULL;
|
||||
fp->_IO_save_end = NULL;
|
||||
fp->_IO_backup_base = NULL;
|
||||
@@ -235,7 +236,7 @@ save_for_backup (FILE *fp, char *end_p)
|
||||
memcpy (new_buffer + avail,
|
||||
fp->_IO_read_base + least_mark,
|
||||
needed_size);
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_IO_save_base = new_buffer;
|
||||
fp->_IO_save_end = new_buffer + avail + needed_size;
|
||||
}
|
||||
@@ -611,7 +612,7 @@ _IO_default_finish (FILE *fp, int dummy)
|
||||
|
||||
if (fp->_IO_save_base)
|
||||
{
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_IO_save_base = NULL;
|
||||
}
|
||||
|
||||
@@ -996,11 +997,14 @@ _IO_default_pbackfail (FILE *fp, int c)
|
||||
else if (!_IO_have_backup (fp))
|
||||
{
|
||||
/* No backup buffer: allocate one. */
|
||||
- /* Use nshort buffer, if unused? (probably not) FIXME */
|
||||
int backup_size = 128;
|
||||
char *bbuf = (char *) malloc (backup_size);
|
||||
if (bbuf == NULL)
|
||||
- return EOF;
|
||||
+ {
|
||||
+ /* Guarantee a 1-char pushback. */
|
||||
+ bbuf = fp->_short_backupbuf;
|
||||
+ backup_size = 1;
|
||||
+ }
|
||||
fp->_IO_save_base = bbuf;
|
||||
fp->_IO_save_end = fp->_IO_save_base + backup_size;
|
||||
fp->_IO_backup_base = fp->_IO_save_end;
|
||||
@@ -1020,7 +1024,7 @@ _IO_default_pbackfail (FILE *fp, int c)
|
||||
return EOF;
|
||||
memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
|
||||
old_size);
|
||||
- free (fp->_IO_read_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_read_base);
|
||||
_IO_setg (fp, new_buf, new_buf + (new_size - old_size),
|
||||
new_buf + new_size);
|
||||
fp->_IO_backup_base = fp->_IO_read_ptr;
|
||||
diff -rupN a/libio/libioP.h b/libio/libioP.h
|
||||
--- a/libio/libioP.h 2024-12-18 23:17:36.823719449 -0500
|
||||
+++ b/libio/libioP.h 2024-12-19 00:34:04.305351870 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -809,30 +810,30 @@ extern int _IO_vscanf (const char *, va_
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
- NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
- 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, 0, { 0 }, \
|
||||
+ _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
|
||||
# else
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
- NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
- 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\
|
||||
- NULL, WDP, NULL }
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, 0, { 0 }, \
|
||||
+ _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, \
|
||||
+ _IO_pos_BAD, NULL, WDP, NULL }
|
||||
# endif
|
||||
#else
|
||||
# ifdef _IO_USE_OLD_IO_FILE
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
- NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
- 0, _IO_pos_BAD }
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, 0, { 0 }, \
|
||||
+ _IO_pos_BAD }
|
||||
# else
|
||||
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
|
||||
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
- NULL, NULL, (FILE *) CHAIN, FD, \
|
||||
- 0, _IO_pos_BAD, 0, 0, { 0 }, NULL, _IO_pos_BAD, \
|
||||
- NULL, WDP, NULL }
|
||||
+ NULL, NULL, (FILE *) CHAIN, FD, 0, { 0 }, \
|
||||
+ _IO_pos_BAD, 0, 0, { 0 }, NULL, \
|
||||
+ _IO_pos_BAD, NULL, WDP, NULL }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -951,6 +952,15 @@ IO_validate_vtable (const struct _IO_jum
|
||||
return vtable;
|
||||
}
|
||||
|
||||
+/* In case of an allocation failure, we resort to using the fixed buffer
|
||||
+ _SHORT_BACKUPBUF. Free PTR unless it points to that buffer. */
|
||||
+static __always_inline void
|
||||
+_IO_free_backup_buf (FILE *fp, char *ptr)
|
||||
+{
|
||||
+ if (ptr != fp->_short_backupbuf)
|
||||
+ free (ptr);
|
||||
+}
|
||||
+
|
||||
/* Character set conversion. */
|
||||
|
||||
enum __codecvt_result
|
||||
diff -rupN a/libio/oldfileops.c b/libio/oldfileops.c
|
||||
--- a/libio/oldfileops.c 2021-08-01 21:33:43.000000000 -0400
|
||||
+++ b/libio/oldfileops.c 2024-12-19 00:34:04.311351928 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Per Bothner <bothner@cygnus.com>.
|
||||
|
||||
@@ -310,7 +311,7 @@ _IO_old_file_underflow (FILE *fp)
|
||||
/* Maybe we already have a push back pointer. */
|
||||
if (fp->_IO_save_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
@@ -463,7 +464,7 @@ _IO_old_file_seekoff (FILE *fp, off64_t
|
||||
/* It could be that we already have a pushback buffer. */
|
||||
if (fp->_IO_read_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_read_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_read_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
diff -rupN a/libio/wfileops.c b/libio/wfileops.c
|
||||
--- a/libio/wfileops.c 2024-12-18 23:17:34.277694679 -0500
|
||||
+++ b/libio/wfileops.c 2024-12-19 00:34:04.316351977 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>.
|
||||
Based on the single byte version by Per Bothner <bothner@cygnus.com>.
|
||||
@@ -177,7 +178,7 @@ _IO_wfile_underflow (FILE *fp)
|
||||
/* Maybe we already have a push back pointer. */
|
||||
if (fp->_IO_save_base != NULL)
|
||||
{
|
||||
- free (fp->_IO_save_base);
|
||||
+ _IO_free_backup_buf (fp, fp->_IO_save_base);
|
||||
fp->_flags &= ~_IO_IN_BACKUP;
|
||||
}
|
||||
_IO_doallocbuf (fp);
|
||||
diff -rupN a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
--- a/stdio-common/Makefile 2024-12-18 23:17:36.527716569 -0500
|
||||
+++ b/stdio-common/Makefile 2024-12-19 00:34:04.320352016 -0500
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
+# Copyright The GNU Toolchain Authors.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -242,6 +243,7 @@ tests := \
|
||||
tst-tmpnam \
|
||||
tst-ungetc \
|
||||
tst-ungetc-leak \
|
||||
+ tst-ungetc-nomem \
|
||||
tst-unlockedio \
|
||||
tst-vfprintf-mbs-prec \
|
||||
tst-vfprintf-user-type \
|
||||
diff -rupN a/stdio-common/tst-ungetc-nomem.c b/stdio-common/tst-ungetc-nomem.c
|
||||
--- a/stdio-common/tst-ungetc-nomem.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ b/stdio-common/tst-ungetc-nomem.c 2024-12-19 00:34:04.324352055 -0500
|
||||
@@ -0,0 +1,121 @@
|
||||
+/* Test ungetc behavior with malloc failures.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
+ 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+static volatile bool fail = false;
|
||||
+
|
||||
+/* Induce a malloc failure whenever FAIL is set; we use the __LIBC_MALLOC entry
|
||||
+ point to avoid the other alternative, which is RTLD_NEXT. */
|
||||
+void *
|
||||
+malloc (size_t sz)
|
||||
+{
|
||||
+ if (fail)
|
||||
+ return NULL;
|
||||
+
|
||||
+ static void *(*real_malloc) (size_t);
|
||||
+
|
||||
+ if (real_malloc == NULL)
|
||||
+ real_malloc = dlsym (RTLD_NEXT, "malloc");
|
||||
+
|
||||
+ return real_malloc (sz);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *filename = NULL;
|
||||
+ struct stat props = {};
|
||||
+ size_t bufsz = 0;
|
||||
+
|
||||
+ create_temp_file ("tst-ungetc-nomem.", &filename);
|
||||
+ if (stat (filename, &props) != 0)
|
||||
+ FAIL_EXIT1 ("Could not get file status: %m\n");
|
||||
+
|
||||
+ FILE *fp = fopen (filename, "w");
|
||||
+
|
||||
+ /* The libio buffer sizes are the same as block size. This is to ensure that
|
||||
+ the test runs at the read underflow boundary as well. */
|
||||
+ bufsz = props.st_blksize + 2;
|
||||
+
|
||||
+ char *buf = xmalloc (bufsz);
|
||||
+ memset (buf, 'a', bufsz);
|
||||
+
|
||||
+ if (fwrite (buf, sizeof (char), bufsz, fp) != bufsz)
|
||||
+ FAIL_EXIT1 ("fwrite failed: %m\n");
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ /* Begin test. */
|
||||
+ fp = xfopen (filename, "r");
|
||||
+
|
||||
+ while (!feof (fp))
|
||||
+ {
|
||||
+ /* Reset the pushback buffer state. */
|
||||
+ fseek (fp, 0, SEEK_CUR);
|
||||
+
|
||||
+ fail = true;
|
||||
+ /* 1: First ungetc should always succeed, as the standard requires. */
|
||||
+ TEST_COMPARE (ungetc ('b', fp), 'b');
|
||||
+
|
||||
+ /* 2: This will result in resizing, which should fail. */
|
||||
+ TEST_COMPARE (ungetc ('c', fp), EOF);
|
||||
+
|
||||
+ /* 3: Now allow the resizing, which should immediately fill up the buffer
|
||||
+ too, since this allocates only double the current buffer, i.e.
|
||||
+ 2-bytes. */
|
||||
+ fail = false;
|
||||
+ TEST_COMPARE (ungetc ('d', fp), 'd');
|
||||
+
|
||||
+ /* 4: And fail again because this again forces an alloc, which fails. */
|
||||
+ fail = true;
|
||||
+ TEST_COMPARE (ungetc ('e', fp), EOF);
|
||||
+
|
||||
+ /* 5: Enable allocations again so that we now get a 4-byte buffer. Now
|
||||
+ both calls should work. */
|
||||
+ fail = false;
|
||||
+ TEST_COMPARE (ungetc ('f', fp), 'f');
|
||||
+ fail = true;
|
||||
+ TEST_COMPARE (ungetc ('g', fp), 'g');
|
||||
+
|
||||
+ /* Drain out the x's. */
|
||||
+ TEST_COMPARE (fgetc (fp), 'g');
|
||||
+ TEST_COMPARE (fgetc (fp), 'f');
|
||||
+ TEST_COMPARE (fgetc (fp), 'd');
|
||||
+
|
||||
+ /* Finally, drain out the first char we had pushed back, followed by one
|
||||
+ more char from the stream, if present. */
|
||||
+ TEST_COMPARE (fgetc (fp), 'b');
|
||||
+ char c = fgetc (fp);
|
||||
+ if (!feof (fp))
|
||||
+ TEST_COMPARE (c, 'a');
|
||||
+ }
|
||||
+
|
||||
+ /* Final sanity check before we're done. */
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
26
SOURCES/glibc-RHEL-46738-5.patch
Normal file
26
SOURCES/glibc-RHEL-46738-5.patch
Normal file
@ -0,0 +1,26 @@
|
||||
Downstream-only patch to restore the extern ABI for functions
|
||||
like fprintf that use the FILE * type. Rebuilds of applications
|
||||
receive ABI change reports because of this installed header change
|
||||
(indirect subtype change in libabigail terms), and given that
|
||||
this part of struct _IO_FILE is strictly internal, there is no
|
||||
need to expose this change to installed headers.
|
||||
|
||||
diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h
|
||||
index 0e73f89f813ef3b8..f7f756a701ce0e93 100644
|
||||
--- a/libio/bits/types/struct_FILE.h
|
||||
+++ b/libio/bits/types/struct_FILE.h
|
||||
@@ -71,9 +71,14 @@ struct _IO_FILE
|
||||
struct _IO_FILE *_chain;
|
||||
|
||||
int _fileno;
|
||||
+#ifdef _LIBC
|
||||
int _flags2:24;
|
||||
/* Fallback buffer to use when malloc fails to allocate one. */
|
||||
char _short_backupbuf[1];
|
||||
+#else
|
||||
+ /* Legacy ABI for ABI checking outside of glibc. */
|
||||
+ int _flags2;
|
||||
+#endif
|
||||
__off_t _old_offset; /* This used to be _offset but it's too small. */
|
||||
|
||||
/* 1+column number of pbase(); 0 is unknown. */
|
49
SOURCES/glibc-RHEL-46739-1.patch
Normal file
49
SOURCES/glibc-RHEL-46739-1.patch
Normal file
@ -0,0 +1,49 @@
|
||||
commit 207d64feb26279e152c50744e3c37e68491aca99
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Aug 14 17:15:46 2024 +0000
|
||||
|
||||
Test errno setting on strtod overflow in tst-strtod-round
|
||||
|
||||
We have no tests that errno is set to ERANGE on overflow of
|
||||
strtod-family functions (we do have some tests for underflow, in
|
||||
tst-strtod-underflow). Add such tests to tst-strtod-round.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod-round-skeleton.c b/stdlib/tst-strtod-round-skeleton.c
|
||||
index f60b9a00e9e8d262..1ff1977112bda7a8 100644
|
||||
--- a/stdlib/tst-strtod-round-skeleton.c
|
||||
+++ b/stdlib/tst-strtod-round-skeleton.c
|
||||
@@ -21,6 +21,7 @@
|
||||
declared in the headers. */
|
||||
#define _LIBC_TEST 1
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
+#include <errno.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@@ -205,7 +206,9 @@ struct test {
|
||||
#define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
{ \
|
||||
feclearexcept (FE_ALL_EXCEPT); \
|
||||
+ errno = 0; \
|
||||
FTYPE f = STRTO (FSUF) (s, NULL); \
|
||||
+ int new_errno = errno; \
|
||||
if (f != expected->FSUF \
|
||||
|| (copysign ## CSUF) (1.0 ## LSUF, f) \
|
||||
!= (copysign ## CSUF) (1.0 ## LSUF, expected->FSUF)) \
|
||||
@@ -254,6 +257,14 @@ struct test {
|
||||
printf ("ignoring this exception error\n"); \
|
||||
} \
|
||||
} \
|
||||
+ if (overflow->FSUF && new_errno != ERANGE) \
|
||||
+ { \
|
||||
+ printf (FNPFXS "to" #FSUF \
|
||||
+ " (" STRM ") left errno == %d," \
|
||||
+ " not %d (ERANGE)\n", \
|
||||
+ s, new_errno, ERANGE); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
} \
|
||||
}
|
||||
|
38
SOURCES/glibc-RHEL-46739-10.patch
Normal file
38
SOURCES/glibc-RHEL-46739-10.patch
Normal file
@ -0,0 +1,38 @@
|
||||
commit 378039ca578c2ea93095a1e710d96f58c68a3997
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:24:45 2024 +0000
|
||||
|
||||
Add tests of more strtod special cases
|
||||
|
||||
There is very little test coverage of inputs to strtod-family
|
||||
functions that don't contain anything that can be parsed as a number
|
||||
(one test of ".y" in tst-strtod2), and none that I can see of skipping
|
||||
initial whitespace. Add some tests of these things to tst-strtod2.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index c84bd792c1a3f511..d00bc13323c50622 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -31,6 +31,20 @@ struct test_strto ## FSUF \
|
||||
{ "0x1px", 1.0 ## LSUF, 3 }, \
|
||||
{ "0x1p+x", 1.0 ## LSUF, 3 }, \
|
||||
{ "0x1p-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "", 0.0 ## LSUF, 0 }, \
|
||||
+ { ".", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-.", 0.0 ## LSUF, 0 }, \
|
||||
+ { ".e", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t.", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-.", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t\f\r\n\v1", 1.0 ## LSUF, 7 }, \
|
||||
+ { " \t\f\r\n\v-1.5e2", -150.0 ## LSUF, 12 }, \
|
||||
{ "INFx", INFINITY, 3 }, \
|
||||
{ "infx", INFINITY, 3 }, \
|
||||
{ "INFINITx", INFINITY, 3 }, \
|
439
SOURCES/glibc-RHEL-46739-11.patch
Normal file
439
SOURCES/glibc-RHEL-46739-11.patch
Normal file
@ -0,0 +1,439 @@
|
||||
commit 94ca2c0894f0e1b62625c369cc598a2b9236622c
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:25:32 2024 +0000
|
||||
|
||||
Make tst-strtod-underflow type-generic
|
||||
|
||||
The test tst-strtod-underflow covers various edge cases close to the
|
||||
underflow threshold for strtod (especially cases where underflow on
|
||||
architectures with after-rounding tininess detection depends on the
|
||||
rounding mode). Make it use the type-generic machinery, with
|
||||
corresponding test inputs for each supported floating-point format, so
|
||||
that other functions in the strtod family are tested for underflow
|
||||
edge cases as well.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod-underflow.c b/stdlib/tst-strtod-underflow.c
|
||||
index 294f88de439fb3e7..094a70bbbe53e70b 100644
|
||||
--- a/stdlib/tst-strtod-underflow.c
|
||||
+++ b/stdlib/tst-strtod-underflow.c
|
||||
@@ -17,6 +17,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* Defining _LIBC_TEST ensures long double math functions are
|
||||
+ declared in the headers. */
|
||||
+#define _LIBC_TEST 1
|
||||
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#include <errno.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
@@ -25,6 +29,60 @@
|
||||
#include <stdlib.h>
|
||||
#include <tininess.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* Logic for selecting between tests for different formats is as in
|
||||
+ tst-strtod-skeleton.c, but here it is selecting string inputs with
|
||||
+ different underflow properties, rather than generated test
|
||||
+ data. */
|
||||
+
|
||||
+#define _CONCAT(a, b) a ## b
|
||||
+#define CONCAT(a, b) _CONCAT (a, b)
|
||||
+
|
||||
+#define MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+ const char *s_ ## FSUF;
|
||||
+
|
||||
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
+# define CHOOSE_ld(f,d,...) d
|
||||
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
|
||||
+# define CHOOSE_ld(f,d,ld64i,...) ld64i
|
||||
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16382
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,...) ld64m
|
||||
+#elif LDBL_MANT_DIG == 106 && LDBL_MAX_EXP == 1024
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,...) ld106
|
||||
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+#else
|
||||
+# error "unknown long double format"
|
||||
+#endif
|
||||
+
|
||||
+#define CHOOSE_f(f,...) f
|
||||
+#define CHOOSE_f32(f,...) f
|
||||
+#define CHOOSE_d(f,d,...) d
|
||||
+#define CHOOSE_f64(f,d,...) d
|
||||
+#define CHOOSE_f32x(f,d,...) d
|
||||
+#define CHOOSE_f128(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+
|
||||
+#if __HAVE_FLOAT64X
|
||||
+# if FLT64X_MANT_DIG == 113 && FLT64X_MAX_EXP == 16384
|
||||
+# define CHOOSE_f64x(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+# elif (FLT64X_MANT_DIG == 64 \
|
||||
+ && FLT64X_MAX_EXP == 16384 \
|
||||
+ && FLT64X_MIN_EXP == -16381)
|
||||
+# define CHOOSE_f64x(f,d,ld64i,...) ld64i
|
||||
+# else
|
||||
+# error "unknown _Float64x format"
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
+#define _XNTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...) \
|
||||
+ CHOOSE_ ## FSUF (__VA_ARGS__),
|
||||
+#define XNTRY(...) \
|
||||
+ GEN_TEST_STRTOD_FOREACH (_XNTRY, __VA_ARGS__)
|
||||
+
|
||||
+#define TEST(f, d, ld64i, ld64m, ld106, ld113, u) \
|
||||
+ { XNTRY(f, d, ld64i, ld64m, ld106, ld113) u }
|
||||
+
|
||||
enum underflow_case
|
||||
{
|
||||
/* Result is exact or outside the subnormal range. */
|
||||
@@ -55,38 +113,194 @@ enum underflow_case
|
||||
|
||||
struct test
|
||||
{
|
||||
- const char *s;
|
||||
+ GEN_TEST_STRTOD_FOREACH (MEMBER)
|
||||
enum underflow_case c;
|
||||
};
|
||||
|
||||
static const struct test tests[] =
|
||||
{
|
||||
- { "0x1p-1022", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1022", UNDERFLOW_NONE },
|
||||
- { "0x0p-10000000000000000000000000", UNDERFLOW_NONE },
|
||||
- { "-0x0p-10000000000000000000000000", UNDERFLOW_NONE },
|
||||
- { "0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS },
|
||||
- { "0x1.000000000000000000001p-1022", UNDERFLOW_NONE },
|
||||
- { "-0x1.000000000000000000001p-1022", UNDERFLOW_NONE },
|
||||
- { "0x1p-1075", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1p-1075", UNDERFLOW_ALWAYS },
|
||||
- { "0x1p-1023", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1023", UNDERFLOW_NONE },
|
||||
- { "0x1p-1074", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1074", UNDERFLOW_NONE },
|
||||
- { "0x1.ffffffffffffep-1023", UNDERFLOW_NONE },
|
||||
- { "-0x1.ffffffffffffep-1023", UNDERFLOW_NONE },
|
||||
- { "0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS },
|
||||
- { "0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_UPWARD },
|
||||
- { "-0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_DOWNWARD },
|
||||
- { "0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_UPWARD },
|
||||
- { "-0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_DOWNWARD },
|
||||
- { "0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO },
|
||||
- { "-0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_UPWARD_ZERO },
|
||||
- { "0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO },
|
||||
- { "-0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_UPWARD_ZERO },
|
||||
+ TEST ("0x1p-126",
|
||||
+ "0x1p-1022",
|
||||
+ "0x1p-16382",
|
||||
+ "0x1p-16383",
|
||||
+ "0x1p-969",
|
||||
+ "0x1p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-126",
|
||||
+ "-0x1p-1022",
|
||||
+ "-0x1p-16382",
|
||||
+ "-0x1p-16383",
|
||||
+ "-0x1p-969",
|
||||
+ "-0x1p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1.000000000000000000001p-126",
|
||||
+ "0x1.000000000000000000001p-1022",
|
||||
+ "0x1.000000000000000000001p-16382",
|
||||
+ "0x1.000000000000000000001p-16383",
|
||||
+ "0x1.000000000000000000001p-969",
|
||||
+ "0x1.00000000000000000000000000000000000000001p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1.000000000000000000001p-126",
|
||||
+ "-0x1.000000000000000000001p-1022",
|
||||
+ "-0x1.000000000000000000001p-16382",
|
||||
+ "-0x1.000000000000000000001p-16383",
|
||||
+ "-0x1.000000000000000000001p-969",
|
||||
+ "-0x1.00000000000000000000000000000000000000001p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-150",
|
||||
+ "0x1p-1075",
|
||||
+ "0x1p-16446",
|
||||
+ "0x1p-16447",
|
||||
+ "0x1p-1075",
|
||||
+ "0x1p-16495",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1p-150",
|
||||
+ "-0x1p-1075",
|
||||
+ "-0x1p-16446",
|
||||
+ "-0x1p-16447",
|
||||
+ "-0x1p-1075",
|
||||
+ "-0x1p-16495",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1p-127",
|
||||
+ "0x1p-1023",
|
||||
+ "0x1p-16383",
|
||||
+ "0x1p-16384",
|
||||
+ "0x1p-970",
|
||||
+ "0x1p-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-127",
|
||||
+ "-0x1p-1023",
|
||||
+ "-0x1p-16383",
|
||||
+ "-0x1p-16384",
|
||||
+ "-0x1p-970",
|
||||
+ "-0x1p-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-149",
|
||||
+ "0x1p-1074",
|
||||
+ "0x1p-16445",
|
||||
+ "0x1p-16446",
|
||||
+ "0x1p-1074",
|
||||
+ "0x1p-16494",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-149",
|
||||
+ "-0x1p-1074",
|
||||
+ "-0x1p-16445",
|
||||
+ "-0x1p-16446",
|
||||
+ "-0x1p-1074",
|
||||
+ "-0x1p-16494",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1.fffffcp-127",
|
||||
+ "0x1.ffffffffffffep-1023",
|
||||
+ "0x1.fffffffffffffffcp-16383",
|
||||
+ "0x1.fffffffffffffffcp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffp-970",
|
||||
+ "0x1.fffffffffffffffffffffffffffep-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1.fffffcp-127",
|
||||
+ "-0x1.ffffffffffffep-1023",
|
||||
+ "-0x1.fffffffffffffffcp-16383",
|
||||
+ "-0x1.fffffffffffffffcp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffp-970",
|
||||
+ "-0x1.fffffffffffffffffffffffffffep-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1.fffffep-127",
|
||||
+ "0x1.fffffffffffffp-1023",
|
||||
+ "0x1.fffffffffffffffep-16383",
|
||||
+ "0x1.fffffffffffffffep-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffff8p-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1.fffffep-127",
|
||||
+ "-0x1.fffffffffffffp-1023",
|
||||
+ "-0x1.fffffffffffffffep-16383",
|
||||
+ "-0x1.fffffffffffffffep-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffff8p-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1.fffffe0001p-127",
|
||||
+ "0x1.fffffffffffff0001p-1023",
|
||||
+ "0x1.fffffffffffffffe0001p-16383",
|
||||
+ "0x1.fffffffffffffffe0001p-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffff80001p-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff0001p-16383",
|
||||
+ UNDERFLOW_EXCEPT_UPWARD),
|
||||
+ TEST ("-0x1.fffffe0001p-127",
|
||||
+ "-0x1.fffffffffffff0001p-1023",
|
||||
+ "-0x1.fffffffffffffffe0001p-16383",
|
||||
+ "-0x1.fffffffffffffffe0001p-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffff80001p-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff0001p-16383",
|
||||
+ UNDERFLOW_EXCEPT_DOWNWARD),
|
||||
+ TEST ("0x1.fffffeffffp-127",
|
||||
+ "0x1.fffffffffffff7fffp-1023",
|
||||
+ "0x1.fffffffffffffffeffffp-16383",
|
||||
+ "0x1.fffffffffffffffeffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffbffffp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff7fffp-16383",
|
||||
+ UNDERFLOW_EXCEPT_UPWARD),
|
||||
+ TEST ("-0x1.fffffeffffp-127",
|
||||
+ "-0x1.fffffffffffff7fffp-1023",
|
||||
+ "-0x1.fffffffffffffffeffffp-16383",
|
||||
+ "-0x1.fffffffffffffffeffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffbffffp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff7fffp-16383",
|
||||
+ UNDERFLOW_EXCEPT_DOWNWARD),
|
||||
+ TEST ("0x1.ffffffp-127",
|
||||
+ "0x1.fffffffffffff8p-1023",
|
||||
+ "0x1.ffffffffffffffffp-16383",
|
||||
+ "0x1.ffffffffffffffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffcp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff8p-16383",
|
||||
+ UNDERFLOW_ONLY_DOWNWARD_ZERO),
|
||||
+ TEST ("-0x1.ffffffp-127",
|
||||
+ "-0x1.fffffffffffff8p-1023",
|
||||
+ "-0x1.ffffffffffffffffp-16383",
|
||||
+ "-0x1.ffffffffffffffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffcp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff8p-16383",
|
||||
+ UNDERFLOW_ONLY_UPWARD_ZERO),
|
||||
+ TEST ("0x1.ffffffffffp-127",
|
||||
+ "0x1.fffffffffffffffffp-1023",
|
||||
+ "0x1.ffffffffffffffffffffp-16383",
|
||||
+ "0x1.ffffffffffffffffffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffffffp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ONLY_DOWNWARD_ZERO),
|
||||
+ TEST ("-0x1.ffffffffffp-127",
|
||||
+ "-0x1.fffffffffffffffffp-1023",
|
||||
+ "-0x1.ffffffffffffffffffffp-16383",
|
||||
+ "-0x1.ffffffffffffffffffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffffp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ONLY_UPWARD_ZERO),
|
||||
};
|
||||
|
||||
/* Return whether to expect underflow from a particular testcase, in a
|
||||
@@ -133,39 +347,62 @@ static bool support_underflow_exception = false;
|
||||
volatile double d = DBL_MIN;
|
||||
volatile double dd;
|
||||
|
||||
-static int
|
||||
-test_in_one_mode (const char *s, enum underflow_case c, int rm,
|
||||
- const char *mode_name)
|
||||
+static bool
|
||||
+test_got_fe_underflow (void)
|
||||
{
|
||||
- int result = 0;
|
||||
- feclearexcept (FE_ALL_EXCEPT);
|
||||
- errno = 0;
|
||||
- double d = strtod (s, NULL);
|
||||
- int got_errno = errno;
|
||||
#ifdef FE_UNDERFLOW
|
||||
- bool got_fe_underflow = fetestexcept (FE_UNDERFLOW) != 0;
|
||||
+ return fetestexcept (FE_UNDERFLOW) != 0;
|
||||
#else
|
||||
- bool got_fe_underflow = false;
|
||||
+ return false;
|
||||
#endif
|
||||
- printf ("strtod (%s) (%s) returned %a, errno = %d, %sunderflow exception\n",
|
||||
- s, mode_name, d, got_errno, got_fe_underflow ? "" : "no ");
|
||||
- bool this_expect_underflow = expect_underflow (c, rm);
|
||||
- if (got_errno != 0 && got_errno != ERANGE)
|
||||
- {
|
||||
- puts ("FAIL: errno neither 0 nor ERANGE");
|
||||
- result = 1;
|
||||
- }
|
||||
- else if (this_expect_underflow != (errno == ERANGE))
|
||||
- {
|
||||
- puts ("FAIL: underflow from errno differs from expectations");
|
||||
- result = 1;
|
||||
- }
|
||||
- if (support_underflow_exception && got_fe_underflow != this_expect_underflow)
|
||||
- {
|
||||
- puts ("FAIL: underflow from exceptions differs from expectations");
|
||||
- result = 1;
|
||||
- }
|
||||
- return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static int \
|
||||
+test_strto ## FSUF (int i, int rm, const char *mode_name) \
|
||||
+{ \
|
||||
+ const char *s = tests[i].s_ ## FSUF; \
|
||||
+ enum underflow_case c = tests[i].c; \
|
||||
+ int result = 0; \
|
||||
+ feclearexcept (FE_ALL_EXCEPT); \
|
||||
+ errno = 0; \
|
||||
+ FTYPE d = strto ## FSUF (s, NULL); \
|
||||
+ int got_errno = errno; \
|
||||
+ bool got_fe_underflow = test_got_fe_underflow (); \
|
||||
+ char buf[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf, sizeof (buf), "%a", d); \
|
||||
+ printf ("strto" #FSUF \
|
||||
+ " (%s) (%s) returned %s, errno = %d, " \
|
||||
+ "%sunderflow exception\n", \
|
||||
+ s, mode_name, buf, got_errno, \
|
||||
+ got_fe_underflow ? "" : "no "); \
|
||||
+ bool this_expect_underflow = expect_underflow (c, rm); \
|
||||
+ if (got_errno != 0 && got_errno != ERANGE) \
|
||||
+ { \
|
||||
+ puts ("FAIL: errno neither 0 nor ERANGE"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ else if (this_expect_underflow != (errno == ERANGE)) \
|
||||
+ { \
|
||||
+ puts ("FAIL: underflow from errno differs from expectations"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ if (support_underflow_exception \
|
||||
+ && got_fe_underflow != this_expect_underflow) \
|
||||
+ { \
|
||||
+ puts ("FAIL: underflow from exceptions " \
|
||||
+ "differs from expectations"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ return result; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
+
|
||||
+static int
|
||||
+test_in_one_mode (size_t i, int rm, const char *mode_name)
|
||||
+{
|
||||
+ return STRTOD_TEST_FOREACH (test_strto, i, rm, mode_name);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -191,12 +428,12 @@ do_test (void)
|
||||
#endif
|
||||
for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, fe_tonearest,
|
||||
+ result |= test_in_one_mode (i, fe_tonearest,
|
||||
"default rounding mode");
|
||||
#ifdef FE_DOWNWARD
|
||||
if (!fesetround (FE_DOWNWARD))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_DOWNWARD,
|
||||
+ result |= test_in_one_mode (i, FE_DOWNWARD,
|
||||
"FE_DOWNWARD");
|
||||
fesetround (save_round_mode);
|
||||
}
|
||||
@@ -204,7 +441,7 @@ do_test (void)
|
||||
#ifdef FE_TOWARDZERO
|
||||
if (!fesetround (FE_TOWARDZERO))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_TOWARDZERO,
|
||||
+ result |= test_in_one_mode (i, FE_TOWARDZERO,
|
||||
"FE_TOWARDZERO");
|
||||
fesetround (save_round_mode);
|
||||
}
|
||||
@@ -212,7 +449,7 @@ do_test (void)
|
||||
#ifdef FE_UPWARD
|
||||
if (!fesetround (FE_UPWARD))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_UPWARD,
|
||||
+ result |= test_in_one_mode (i, FE_UPWARD,
|
||||
"FE_UPWARD");
|
||||
fesetround (save_round_mode);
|
||||
}
|
16723
SOURCES/glibc-RHEL-46739-2.patch
Normal file
16723
SOURCES/glibc-RHEL-46739-2.patch
Normal file
File diff suppressed because it is too large
Load Diff
445
SOURCES/glibc-RHEL-46739-3.patch
Normal file
445
SOURCES/glibc-RHEL-46739-3.patch
Normal file
@ -0,0 +1,445 @@
|
||||
commit 457622c2fa8f9f7435822d5287a437bc8be8090d
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Aug 27 12:41:02 2024 +0000
|
||||
|
||||
Fix strtod subnormal rounding (bug 30220)
|
||||
|
||||
As reported in bug 30220, the implementation of strtod-family
|
||||
functions has a bug in the following case: the input string would,
|
||||
with infinite exponent range, take one more bit to represent than is
|
||||
available in the normal precision of the return type; the value
|
||||
represented is in the subnormal range; and there are no nonzero bits
|
||||
in the value, below those that can be represented in subnormal
|
||||
precision, other than the least significant bit and possibly the
|
||||
0.5ulp bit. In this case, round_and_return ends up discarding the
|
||||
least significant bit.
|
||||
|
||||
Fix by saving that bit to merge into more_bits (it can't be merged in
|
||||
at the time it's computed, because more_bits mustn't include this bit
|
||||
in the case of after-rounding tininess detection checking if the
|
||||
result is still subnormal when rounded to normal precision, so merging
|
||||
this bit into more_bits needs to take place after that check).
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
|
||||
index 5a54d99ae8663641..49b88e9a86be8441 100644
|
||||
--- a/stdlib/strtod_l.c
|
||||
+++ b/stdlib/strtod_l.c
|
||||
@@ -223,6 +223,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
|
||||
|
||||
mp_size_t shift = MIN_EXP - 1 - exponent;
|
||||
bool is_tiny = true;
|
||||
+ bool old_half_bit = (round_limb & (((mp_limb_t) 1) << round_bit)) != 0;
|
||||
|
||||
more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
|
||||
if (shift == MANT_DIG)
|
||||
@@ -293,6 +294,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
|
||||
round_bit = shift - 1;
|
||||
(void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift);
|
||||
}
|
||||
+ more_bits |= old_half_bit;
|
||||
/* This is a hook for the m68k long double format, where the
|
||||
exponent bias is the same for normalized and denormalized
|
||||
numbers. */
|
||||
diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data
|
||||
index 84ab705709b24b6c..9489fbcc9ce7eee2 100644
|
||||
--- a/stdlib/tst-strtod-round-data
|
||||
+++ b/stdlib/tst-strtod-round-data
|
||||
@@ -265,3 +265,15 @@
|
||||
1.000000000000000000000000000000000385185988877447170611195588516985463707620329643077639047987759113311767578125
|
||||
1.0000000000000000000000000000000001925929944387235853055977942584927318538101648215388195239938795566558837890625
|
||||
1.00000000000000000000000000000000009629649721936179265279889712924636592690508241076940976199693977832794189453125
|
||||
+0x30000002222225p-1077
|
||||
+0x0.7fffffffffffeap-1022
|
||||
+0x0.7fffffffffffe9p-1022
|
||||
+0x0.7ffffd4p-126
|
||||
+0x0.7ffffffffffffffd4p-16382
|
||||
+0x0.7ffffffffffffffd4p-16383
|
||||
+0x0.7ffffffffffffffffffffffffffeap-16382
|
||||
+0x0.7000004p-126
|
||||
+0x0.70000000000002p-1022
|
||||
+0x0.70000000000000004p-16382
|
||||
+0x0.70000000000000004p-16383
|
||||
+0x0.70000000000000000000000000002p-16382
|
||||
diff --git a/stdlib/tst-strtod-round-data.h b/stdlib/tst-strtod-round-data.h
|
||||
index 13e62dd2b0588a16..ed50eb2537bc175c 100644
|
||||
--- a/stdlib/tst-strtod-round-data.h
|
||||
+++ b/stdlib/tst-strtod-round-data.h
|
||||
@@ -15437,4 +15437,376 @@ static const struct test tests[] = {
|
||||
0x1p+0, false, false,
|
||||
0x1p+0, false, false,
|
||||
0x1.0000000000000000000000000001p+0, false, false),
|
||||
+ TEST ("0x30000002222225p-1077",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false),
|
||||
+ TEST ("0x0.7fffffffffffeap-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false),
|
||||
+ TEST ("0x0.7fffffffffffe9p-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false),
|
||||
+ TEST ("0x0.7ffffd4p-126",
|
||||
+ false,
|
||||
+ 0x1.fffffp-128, false, true,
|
||||
+ 0x1.fffff8p-128, false, true,
|
||||
+ 0x1.fffffp-128, false, true,
|
||||
+ 0x1.fffff8p-128, false, true,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffd4p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffp-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffp-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffd4p-16383",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0x1p-16384, false, true,
|
||||
+ false,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffffcp-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffffcp-16388, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffffffffffffffeap-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffcp-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffcp-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffffcp-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffffcp-16384, false, true),
|
||||
+ TEST ("0x0.7000004p-126",
|
||||
+ false,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.c00008p-128, false, true,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false),
|
||||
+ TEST ("0x0.70000000000002p-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.c000000000004p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.c000000000004p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false),
|
||||
+ TEST ("0x0.70000000000000004p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000008p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000004p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false),
|
||||
+ TEST ("0x0.70000000000000004p-16383",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xe.000000000000008p-16388, false, true,
|
||||
+ false,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xe.000000000000004p-16388, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false),
|
||||
+ TEST ("0x0.70000000000000000000000000002p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000008p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000004p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000000000000000004p-16384, false, true),
|
||||
};
|
598
SOURCES/glibc-RHEL-46739-4.patch
Normal file
598
SOURCES/glibc-RHEL-46739-4.patch
Normal file
@ -0,0 +1,598 @@
|
||||
commit 3fc063dee01da4f80920a14b7db637c8501d6fd4
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Aug 27 20:41:54 2024 +0000
|
||||
|
||||
Make __strtod_internal tests type-generic
|
||||
|
||||
Some of the strtod tests use type-generic machinery in tst-strtod.h to
|
||||
test the strto* functions for all floating types, while others only
|
||||
test double even when the tests are in fact meaningful for all
|
||||
floating types.
|
||||
|
||||
Convert the tests of the internal __strtod_internal interface to cover
|
||||
all floating types. I haven't tried to convert them to use newer test
|
||||
interfaces in other ways, just made the changes necessary to use the
|
||||
type-generic machinery. As an internal interface, there are no
|
||||
aliases for different types with the same ABI (however,
|
||||
__strtold_internal is defined even if long double has the same ABI as
|
||||
double), so macros used by the type-generic testing code are redefined
|
||||
as needed to avoid expecting such aliases to be present.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Conflicts:
|
||||
stdlib/tst-strtod4.c
|
||||
(69239bd7a216007692470aa9d5f3658024638742 missing downstream)
|
||||
|
||||
diff --git a/stdlib/tst-strtod1i.c b/stdlib/tst-strtod1i.c
|
||||
index 98fc5d527fe1edd9..32fc8b9e1f08ace9 100644
|
||||
--- a/stdlib/tst-strtod1i.c
|
||||
+++ b/stdlib/tst-strtod1i.c
|
||||
@@ -25,60 +25,91 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
-/* Perform a few tests in a locale with thousands separators. */
|
||||
-static int
|
||||
-do_test (void)
|
||||
-{
|
||||
- static const struct
|
||||
- {
|
||||
- const char *loc;
|
||||
- const char *str;
|
||||
- double exp;
|
||||
- ptrdiff_t nread;
|
||||
- } tests[] =
|
||||
- {
|
||||
- { "de_DE.UTF-8", "1,5", 1.5, 3 },
|
||||
- { "de_DE.UTF-8", "1.5", 1.0, 1 },
|
||||
- { "de_DE.UTF-8", "1.500", 1500.0, 5 },
|
||||
- { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65, 26 }
|
||||
- };
|
||||
-#define ntests (sizeof (tests) / sizeof (tests[0]))
|
||||
- size_t n;
|
||||
- int result = 0;
|
||||
-
|
||||
- puts ("\nLocale tests");
|
||||
+#include "tst-strtod.h"
|
||||
|
||||
- for (n = 0; n < ntests; ++n)
|
||||
- {
|
||||
- double d;
|
||||
- char *endp;
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
|
||||
- if (setlocale (LC_ALL, tests[n].loc) == NULL)
|
||||
- {
|
||||
- printf ("cannot set locale %s\n", tests[n].loc);
|
||||
- result = 1;
|
||||
- continue;
|
||||
- }
|
||||
+#define ntests (sizeof (tests) / sizeof (tests[0]))
|
||||
|
||||
- d = __strtod_internal (tests[n].str, &endp, 1);
|
||||
- if (d != tests[n].exp)
|
||||
- {
|
||||
- printf ("strtod(\"%s\") returns %g and not %g\n",
|
||||
- tests[n].str, d, tests[n].exp);
|
||||
- result = 1;
|
||||
- }
|
||||
- else if (endp - tests[n].str != tests[n].nread)
|
||||
- {
|
||||
- printf ("strtod(\"%s\") read %td bytes and not %td\n",
|
||||
- tests[n].str, endp - tests[n].str, tests[n].nread);
|
||||
- result = 1;
|
||||
- }
|
||||
- }
|
||||
+/* Perform a few tests in a locale with thousands separators. */
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ static const struct \
|
||||
+ { \
|
||||
+ const char *loc; \
|
||||
+ const char *str; \
|
||||
+ FTYPE exp; \
|
||||
+ ptrdiff_t nread; \
|
||||
+ } tests[] = \
|
||||
+ { \
|
||||
+ { "de_DE.UTF-8", "1,5", 1.5 ## LSUF, 3 }, \
|
||||
+ { "de_DE.UTF-8", "1.5", 1.0 ## LSUF, 1 }, \
|
||||
+ { "de_DE.UTF-8", "1.500", 1500.0 ## LSUF, 5 }, \
|
||||
+ { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65 ## LSUF, 26 } \
|
||||
+ }; \
|
||||
+ size_t n; \
|
||||
+ int result = 0; \
|
||||
+ \
|
||||
+ puts ("\nLocale tests"); \
|
||||
+ \
|
||||
+ for (n = 0; n < ntests; ++n) \
|
||||
+ { \
|
||||
+ FTYPE d; \
|
||||
+ char *endp; \
|
||||
+ \
|
||||
+ if (setlocale (LC_ALL, tests[n].loc) == NULL) \
|
||||
+ { \
|
||||
+ printf ("cannot set locale %s\n", tests[n].loc); \
|
||||
+ result = 1; \
|
||||
+ continue; \
|
||||
+ } \
|
||||
+ \
|
||||
+ d = __strto ## FSUF ## _internal (tests[n].str, &endp, 1); \
|
||||
+ if (d != tests[n].exp) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", d); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", tests[n].exp); \
|
||||
+ printf ("strto" # FSUF "(\"%s\") returns %s and not %s\n", \
|
||||
+ tests[n].str, buf1, buf2); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ else if (endp - tests[n].str != tests[n].nread) \
|
||||
+ { \
|
||||
+ printf ("strto" # FSUF "(\"%s\") read %td bytes and not %td\n", \
|
||||
+ tests[n].str, endp - tests[n].str, tests[n].nread); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (result == 0) \
|
||||
+ puts ("all OK"); \
|
||||
+ \
|
||||
+ return result ? EXIT_FAILURE : EXIT_SUCCESS; \
|
||||
+}
|
||||
|
||||
- if (result == 0)
|
||||
- puts ("all OK");
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
- return result ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
diff --git a/stdlib/tst-strtod3.c b/stdlib/tst-strtod3.c
|
||||
index 23abec1896896276..0d662d8be83a7525 100644
|
||||
--- a/stdlib/tst-strtod3.c
|
||||
+++ b/stdlib/tst-strtod3.c
|
||||
@@ -3,19 +3,73 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- const char *out;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "000,,,e1", ",,,e1", 0.0 },
|
||||
- { "000e1", "", 0.0 },
|
||||
- { "000,1e1", ",1e1", 0.0 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ const char *out; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "000,,,e1", ",,,e1", 0.0 ## LSUF }, \
|
||||
+ { "000e1", "", 0.0 ## LSUF }, \
|
||||
+ { "000,1e1", ",1e1", 0.0 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, 1); \
|
||||
+ \
|
||||
+ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \
|
||||
+ i, ep, tests_strto ## FSUF[i].out); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -26,29 +80,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, 1);
|
||||
-
|
||||
- if (strcmp (ep, tests[i].out) != 0)
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"%s\"\n",
|
||||
- i, ep, tests[i].out);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected)
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod4.c b/stdlib/tst-strtod4.c
|
||||
index aae9835d82d38b4e..cd86f8c1f13a39e4 100644
|
||||
--- a/stdlib/tst-strtod4.c
|
||||
+++ b/stdlib/tst-strtod4.c
|
||||
@@ -3,20 +3,74 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
+
|
||||
#define NNBSP "\xe2\x80\xaf"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- const char *out;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "000"NNBSP"000"NNBSP"000", "", 0.0 },
|
||||
- { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ const char *out; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "000"NNBSP"000"NNBSP"000", "", 0.0 ## LSUF }, \
|
||||
+ { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, 1); \
|
||||
+ \
|
||||
+ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \
|
||||
+ i, ep, tests_strto ## FSUF[i].out); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -27,29 +81,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, 1);
|
||||
-
|
||||
- if (strcmp (ep, tests[i].out) != 0)
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"%s\"\n",
|
||||
- i, ep, tests[i].out);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected)
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod5i.c b/stdlib/tst-strtod5i.c
|
||||
index ba3e78d5f2933586..0ddae2b94765de39 100644
|
||||
--- a/stdlib/tst-strtod5i.c
|
||||
+++ b/stdlib/tst-strtod5i.c
|
||||
@@ -16,52 +16,112 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* Defining _LIBC_TEST ensures long double math functions are
|
||||
+ declared in the headers. */
|
||||
+#define _LIBC_TEST 1
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
+
|
||||
#define NNBSP "\xe2\x80\xaf"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- int group;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "0", 0, 0.0 },
|
||||
- { "000", 0, 0.0 },
|
||||
- { "-0", 0, -0.0 },
|
||||
- { "-000", 0, -0.0 },
|
||||
- { "0,", 0, 0.0 },
|
||||
- { "-0,", 0, -0.0 },
|
||||
- { "0,0", 0, 0.0 },
|
||||
- { "-0,0", 0, -0.0 },
|
||||
- { "0e-10", 0, 0.0 },
|
||||
- { "-0e-10", 0, -0.0 },
|
||||
- { "0,e-10", 0, 0.0 },
|
||||
- { "-0,e-10", 0, -0.0 },
|
||||
- { "0,0e-10", 0, 0.0 },
|
||||
- { "-0,0e-10", 0, -0.0 },
|
||||
- { "0e-1000000", 0, 0.0 },
|
||||
- { "-0e-1000000", 0, -0.0 },
|
||||
- { "0,0e-1000000", 0, 0.0 },
|
||||
- { "-0,0e-1000000", 0, -0.0 },
|
||||
- { "0", 1, 0.0 },
|
||||
- { "000", 1, 0.0 },
|
||||
- { "-0", 1, -0.0 },
|
||||
- { "-000", 1, -0.0 },
|
||||
- { "0e-10", 1, 0.0 },
|
||||
- { "-0e-10", 1, -0.0 },
|
||||
- { "0e-1000000", 1, 0.0 },
|
||||
- { "-0e-1000000", 1, -0.0 },
|
||||
- { "000"NNBSP"000"NNBSP"000", 1, 0.0 },
|
||||
- { "-000"NNBSP"000"NNBSP"000", 1, -0.0 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ int group; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "0", 0, 0.0 ## LSUF }, \
|
||||
+ { "000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0", 0, -0.0 ## LSUF }, \
|
||||
+ { "-000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0", 0, -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0e-1000000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-1000000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0", 1, 0.0 ## LSUF }, \
|
||||
+ { "000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0", 1, -0.0 ## LSUF }, \
|
||||
+ { "-000", 1, -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", 1, -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", 1, -0.0 ## LSUF }, \
|
||||
+ { "000"NNBSP"000"NNBSP"000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-000"NNBSP"000"NNBSP"000", 1, -0.0 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, \
|
||||
+ tests_strto ## FSUF[i].group); \
|
||||
+ \
|
||||
+ if (*ep != '\0') \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected \
|
||||
+ || (copysign ## CSUF (10.0 ## LSUF, r) \
|
||||
+ != copysign ## CSUF (10.0 ## LSUF, \
|
||||
+ tests_strto ## FSUF[i].expected))) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -72,29 +132,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, tests[i].group);
|
||||
-
|
||||
- if (*ep != '\0')
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected
|
||||
- || copysign (10.0, r) != copysign (10.0, tests[i].expected))
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
140
SOURCES/glibc-RHEL-46739-5.patch
Normal file
140
SOURCES/glibc-RHEL-46739-5.patch
Normal file
@ -0,0 +1,140 @@
|
||||
commit be77d5ae417236883c02d3d67c0716e3f669fa41
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Sep 4 13:20:18 2024 +0000
|
||||
|
||||
Improve NaN payload testing
|
||||
|
||||
There are two separate sets of tests of NaN payloads in glibc:
|
||||
|
||||
* libm-test-{get,set}payload* verify that getpayload, setpayload,
|
||||
setpayloadsig and __builtin_nan functions are consistent in their
|
||||
payload handling.
|
||||
|
||||
* test-nan-payload verifies that strtod-family functions and the
|
||||
not-built-in nan functions are consistent in their payload handling.
|
||||
|
||||
Nothing, however, connects the two sets of functions (i.e., verifies
|
||||
that strtod / nan are consistent with getpayload / setpayload /
|
||||
__builtin_nan).
|
||||
|
||||
Improve test-nan-payload to check actual payload value with getpayload
|
||||
rather than just verifying that the strtod and nan functions produce
|
||||
the same NaN. Also check that the NaNs produced aren't signaling and
|
||||
extend the tests to cover _FloatN / _FloatNx.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c
|
||||
index 88fd727e63b2fda2..0ee5432d40a3f997 100644
|
||||
--- a/math/test-nan-payload.c
|
||||
+++ b/math/test-nan-payload.c
|
||||
@@ -16,6 +16,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#define _LIBC_TEST 1
|
||||
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
@@ -31,7 +33,7 @@
|
||||
#define CHECK_IS_NAN(TYPE, A) \
|
||||
do \
|
||||
{ \
|
||||
- if (isnan (A)) \
|
||||
+ if (isnan (A) && !issignaling (A)) \
|
||||
puts ("PASS: " #TYPE " " #A); \
|
||||
else \
|
||||
{ \
|
||||
@@ -41,6 +43,19 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
+#define CHECK_PAYLOAD(TYPE, FUNC, A, P) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (FUNC (&(A)) == (P)) \
|
||||
+ puts ("PASS: " #TYPE " payload " #A); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " payload " #A); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
#define CHECK_SAME_NAN(TYPE, A, B) \
|
||||
do \
|
||||
{ \
|
||||
@@ -71,7 +86,7 @@
|
||||
bits. */
|
||||
#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
|
||||
|
||||
-#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \
|
||||
+#define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \
|
||||
do \
|
||||
{ \
|
||||
TYPE n123 = WRAP_NAN (FUNC, "123"); \
|
||||
@@ -82,6 +97,10 @@
|
||||
CHECK_IS_NAN (TYPE, n456); \
|
||||
TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
|
||||
CHECK_IS_NAN (TYPE, s456); \
|
||||
+ TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \
|
||||
+ CHECK_IS_NAN (TYPE, nh123); \
|
||||
+ TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \
|
||||
+ CHECK_IS_NAN (TYPE, sh123); \
|
||||
TYPE n123x = WRAP_NAN (FUNC, "123)"); \
|
||||
CHECK_IS_NAN (TYPE, n123x); \
|
||||
TYPE nemp = WRAP_NAN (FUNC, ""); \
|
||||
@@ -92,8 +111,16 @@
|
||||
CHECK_IS_NAN (TYPE, sx); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n123, s123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, s123, 123); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n456, s456); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, n456, 456); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, s456, 456); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, nh123, sh123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, nh123, 0x123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, sh123, 0x123); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, nemp, semp); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
@@ -110,9 +137,31 @@ static int
|
||||
do_test (void)
|
||||
{
|
||||
int result = 0;
|
||||
- RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
|
||||
- RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
|
||||
- RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
|
||||
+ RUN_TESTS (float, strtof, nanf, getpayloadf, FLT_MANT_DIG);
|
||||
+ RUN_TESTS (double, strtod, nan, getpayload, DBL_MANT_DIG);
|
||||
+ RUN_TESTS (long double, strtold, nanl, getpayloadl, LDBL_MANT_DIG);
|
||||
+#if __HAVE_FLOAT16
|
||||
+ RUN_TESTS (_Float16, strtof16, nanf16, getpayloadf16, FLT16_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT32
|
||||
+ RUN_TESTS (_Float32, strtof32, nanf32, getpayloadf32, FLT32_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT64
|
||||
+ RUN_TESTS (_Float64, strtof64, nanf64, getpayloadf64, FLT64_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT128
|
||||
+ RUN_TESTS (_Float128, strtof128, nanf128, getpayloadf128, FLT128_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT32X
|
||||
+ RUN_TESTS (_Float32x, strtof32x, nanf32x, getpayloadf32x, FLT32X_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT64X
|
||||
+ RUN_TESTS (_Float64x, strtof64x, nanf64x, getpayloadf64x, FLT64X_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT128X
|
||||
+ RUN_TESTS (_Float128x, strtof128x, nanf128x, getpayloadf128x,
|
||||
+ FLT128X_MANT_DIG);
|
||||
+#endif
|
||||
return result;
|
||||
}
|
||||
|
147
SOURCES/glibc-RHEL-46739-6.patch
Normal file
147
SOURCES/glibc-RHEL-46739-6.patch
Normal file
@ -0,0 +1,147 @@
|
||||
commit 64f62c47e9c350f353336f2df6714e1d48ec50d8
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Sep 4 13:21:23 2024 +0000
|
||||
|
||||
Do not set errno for overflowing NaN payload in strtod/nan (bug 32045)
|
||||
|
||||
As reported in bug 32045, it's incorrect for strtod/nan functions to
|
||||
set errno based on overflowing payload (strtod should only set errno
|
||||
for overflow / underflow of its actual result, and potentially if
|
||||
nothing in the string can be parsed as a number at all; nan should be
|
||||
a pure function that never sets it). Save and restore errno around
|
||||
the internal strtoull call and add associated test coverage.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/math/Makefile b/math/Makefile
|
||||
index 2edb044d9d590de1..a3c44def8acae93b 100644
|
||||
--- a/math/Makefile
|
||||
+++ b/math/Makefile
|
||||
@@ -452,6 +452,7 @@ CFLAGS-test-flt-eval-method.c += -fexcess-precision=standard
|
||||
CFLAGS-test-fe-snans-always-signal.c += -fsignaling-nans
|
||||
|
||||
CFLAGS-test-nan-const.c += -fno-builtin
|
||||
+CFLAGS-test-nan-payload.c += -fno-builtin
|
||||
|
||||
include ../Rules
|
||||
|
||||
diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c
|
||||
index 0ee5432d40a3f997..5f54bf26b6163816 100644
|
||||
--- a/math/test-nan-payload.c
|
||||
+++ b/math/test-nan-payload.c
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#define _LIBC_TEST 1
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
+#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
@@ -82,6 +83,26 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
+#define CLEAR_ERRNO \
|
||||
+ do \
|
||||
+ { \
|
||||
+ errno = 12345; \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define CHECK_ERRNO(TYPE, A) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (errno == 12345) \
|
||||
+ puts ("PASS: " #TYPE " " #A " errno"); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " " #A " errno"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
/* Cannot test payloads by memcmp for formats where NaNs have padding
|
||||
bits. */
|
||||
#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
|
||||
@@ -89,26 +110,58 @@
|
||||
#define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \
|
||||
do \
|
||||
{ \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n123 = WRAP_NAN (FUNC, "123"); \
|
||||
+ CHECK_ERRNO (TYPE, n123); \
|
||||
CHECK_IS_NAN (TYPE, n123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \
|
||||
+ CHECK_ERRNO (TYPE, s123); \
|
||||
CHECK_IS_NAN (TYPE, s123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n456 = WRAP_NAN (FUNC, "456"); \
|
||||
+ CHECK_ERRNO (TYPE, n456); \
|
||||
CHECK_IS_NAN (TYPE, n456); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
|
||||
+ CHECK_ERRNO (TYPE, s456); \
|
||||
CHECK_IS_NAN (TYPE, s456); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \
|
||||
+ CHECK_ERRNO (TYPE, nh123); \
|
||||
CHECK_IS_NAN (TYPE, nh123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \
|
||||
+ CHECK_ERRNO (TYPE, sh123); \
|
||||
CHECK_IS_NAN (TYPE, sh123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n123x = WRAP_NAN (FUNC, "123)"); \
|
||||
+ CHECK_ERRNO (TYPE, n123x); \
|
||||
CHECK_IS_NAN (TYPE, n123x); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE nemp = WRAP_NAN (FUNC, ""); \
|
||||
+ CHECK_ERRNO (TYPE, nemp); \
|
||||
CHECK_IS_NAN (TYPE, nemp); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \
|
||||
+ CHECK_ERRNO (TYPE, semp); \
|
||||
CHECK_IS_NAN (TYPE, semp); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \
|
||||
+ CHECK_ERRNO (TYPE, sx); \
|
||||
CHECK_IS_NAN (TYPE, sx); \
|
||||
+ CLEAR_ERRNO; \
|
||||
+ TYPE novf = WRAP_NAN (FUNC, "9999999999" \
|
||||
+ "99999999999999999999" \
|
||||
+ "9999999999"); \
|
||||
+ CHECK_ERRNO (TYPE, novf); \
|
||||
+ CHECK_IS_NAN (TYPE, novf); \
|
||||
+ CLEAR_ERRNO; \
|
||||
+ TYPE sovf = WRAP_STRTO (SFUNC, "NAN(9999999999" \
|
||||
+ "99999999999999999999" \
|
||||
+ "9999999999)"); \
|
||||
+ CHECK_ERRNO (TYPE, sovf); \
|
||||
+ CHECK_IS_NAN (TYPE, sovf); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n123, s123); \
|
||||
CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \
|
||||
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
|
||||
index ba81355d1c0dbeda..8d7d43818bdba79a 100644
|
||||
--- a/stdlib/strtod_nan_main.c
|
||||
+++ b/stdlib/strtod_nan_main.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <errno.h>
|
||||
#include <ieee754.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
@@ -50,7 +51,9 @@ STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
|
||||
STRING_TYPE *endp;
|
||||
unsigned long long int mant;
|
||||
|
||||
+ int save_errno = errno;
|
||||
mant = STRTOULL (str, &endp, 0);
|
||||
+ __set_errno (save_errno);
|
||||
if (endp == cp)
|
||||
SET_NAN_PAYLOAD (retval, mant);
|
||||
|
76
SOURCES/glibc-RHEL-46739-7.patch
Normal file
76
SOURCES/glibc-RHEL-46739-7.patch
Normal file
@ -0,0 +1,76 @@
|
||||
commit cc3e743fc09ee6fca45767629df9cbcbe1feba82
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Sep 5 21:18:23 2024 +0200
|
||||
|
||||
powerpc64le: Build new strtod tests with long double ABI flags (bug 32145)
|
||||
|
||||
This fixes several test failures:
|
||||
|
||||
=====FAIL: stdlib/tst-strtod1i.out=====
|
||||
Locale tests
|
||||
all OK
|
||||
Locale tests
|
||||
all OK
|
||||
Locale tests
|
||||
strtold("1,5") returns -6,38643e+367 and not 1,5
|
||||
strtold("1.5") returns 1,5 and not 1
|
||||
strtold("1.500") returns 1 and not 1500
|
||||
strtold("36.893.488.147.419.103.232") returns 1500 and not 3,68935e+19
|
||||
Locale tests
|
||||
all OK
|
||||
|
||||
=====FAIL: stdlib/tst-strtod3.out=====
|
||||
0: got wrong results -2.5937e+4826, expected 0
|
||||
|
||||
=====FAIL: stdlib/tst-strtod4.out=====
|
||||
0: got wrong results -6,38643e+367, expected 0
|
||||
1: got wrong results 0, expected 1e+06
|
||||
2: got wrong results 1e+06, expected 10
|
||||
|
||||
=====FAIL: stdlib/tst-strtod5i.out=====
|
||||
0: got wrong results -6,38643e+367, expected 0
|
||||
2: got wrong results 0, expected -0
|
||||
4: got wrong results -0, expected 0
|
||||
5: got wrong results 0, expected -0
|
||||
6: got wrong results -0, expected 0
|
||||
7: got wrong results 0, expected -0
|
||||
8: got wrong results -0, expected 0
|
||||
9: got wrong results 0, expected -0
|
||||
10: got wrong results -0, expected 0
|
||||
11: got wrong results 0, expected -0
|
||||
12: got wrong results -0, expected 0
|
||||
13: got wrong results 0, expected -0
|
||||
14: got wrong results -0, expected 0
|
||||
15: got wrong results 0, expected -0
|
||||
16: got wrong results -0, expected 0
|
||||
17: got wrong results 0, expected -0
|
||||
18: got wrong results -0, expected 0
|
||||
20: got wrong results 0, expected -0
|
||||
22: got wrong results -0, expected 0
|
||||
23: got wrong results 0, expected -0
|
||||
24: got wrong results -0, expected 0
|
||||
25: got wrong results 0, expected -0
|
||||
26: got wrong results -0, expected 0
|
||||
27: got wrong results 0, expected -0
|
||||
|
||||
Fixes commit 3fc063dee01da4f80920a14b7db637c8501d6fd4
|
||||
("Make __strtod_internal tests type-generic").
|
||||
|
||||
Suggested-by: Joseph Myers <josmyers@redhat.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
index 7c036b45fcc0d7f9..8bc71fd18d3f1edc 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
@@ -128,6 +128,10 @@ CFLAGS-tst-strtod-round.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-wcstod-round.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strtod-nan-locale.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-wcstod-nan-locale.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod1i.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod3.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod4.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod5i.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strtod6.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strfrom.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strfrom-locale.c += $(type-float128-CFLAGS)
|
254
SOURCES/glibc-RHEL-46739-8.patch
Normal file
254
SOURCES/glibc-RHEL-46739-8.patch
Normal file
@ -0,0 +1,254 @@
|
||||
commit 8de031bcb9adfa736c0caed2c79d10947b8d8f48
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:23:13 2024 +0000
|
||||
|
||||
Make tst-strtod2 and tst-strtod5 type-generic
|
||||
|
||||
Some of the strtod tests use type-generic machinery in tst-strtod.h to
|
||||
test the strto* functions for all floating types, while others only
|
||||
test double even when the tests are in fact meaningful for all
|
||||
floating types.
|
||||
|
||||
Convert tst-strtod2 and tst-strtod5 to use the type-generic machinery
|
||||
so they test all floating types. I haven't tried to convert them to
|
||||
use newer test interfaces in other ways, just made the changes
|
||||
necessary to use the type-generic machinery.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index a7df82ebbde14c5f..2cb0953fa911efd0 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -1,43 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
-struct test
|
||||
-{
|
||||
- const char *str;
|
||||
- double result;
|
||||
- size_t offset;
|
||||
-} tests[] =
|
||||
-{
|
||||
- { "0xy", 0.0, 1 },
|
||||
- { "0x.y", 0.0, 1 },
|
||||
- { "0x0.y", 0.0, 4 },
|
||||
- { "0x.0y", 0.0, 4 },
|
||||
- { ".y", 0.0, 0 },
|
||||
- { "0.y", 0.0, 2 },
|
||||
- { ".0y", 0.0, 2 }
|
||||
-};
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+struct test_strto ## FSUF \
|
||||
+{ \
|
||||
+ const char *str; \
|
||||
+ FTYPE result; \
|
||||
+ size_t offset; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+{ \
|
||||
+ { "0xy", 0.0 ## LSUF, 1 }, \
|
||||
+ { "0x.y", 0.0 ## LSUF, 1 }, \
|
||||
+ { "0x0.y", 0.0 ## LSUF, 4 }, \
|
||||
+ { "0x.0y", 0.0 ## LSUF, 4 }, \
|
||||
+ { ".y", 0.0 ## LSUF, 0 }, \
|
||||
+ { "0.y", 0.0 ## LSUF, 2 }, \
|
||||
+ { ".0y", 0.0 ## LSUF, 2 } \
|
||||
+}; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ for (size_t i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \
|
||||
+ if (r != tests_strto ## FSUF[i].result) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", tests_strto ## FSUF[i].result); \
|
||||
+ printf ("test %zu r = %s, expect %s\n", i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ if (ep != tests_strto ## FSUF[i].str + tests_strto ## FSUF[i].offset) \
|
||||
+ { \
|
||||
+ printf ("test %zu strto" #FSUF \
|
||||
+ " parsed %tu characters, expected %zu\n", \
|
||||
+ i, ep - tests_strto ## FSUF[i].str, \
|
||||
+ tests_strto ## FSUF[i].offset); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ return status; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- int status = 0;
|
||||
- for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = strtod (tests[i].str, &ep);
|
||||
- if (r != tests[i].result)
|
||||
- {
|
||||
- printf ("test %zu r = %g, expect %g\n", i, r, tests[i].result);
|
||||
- status = 1;
|
||||
- }
|
||||
- if (ep != tests[i].str + tests[i].offset)
|
||||
- {
|
||||
- printf ("test %zu strtod parsed %tu characters, expected %zu\n",
|
||||
- i, ep - tests[i].str, tests[i].offset);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod5.c b/stdlib/tst-strtod5.c
|
||||
index be091ec1b9f87394..005b3480a76955da 100644
|
||||
--- a/stdlib/tst-strtod5.c
|
||||
+++ b/stdlib/tst-strtod5.c
|
||||
@@ -22,35 +22,75 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
#define NBSP "\xc2\xa0"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "0", 0.0 },
|
||||
- { "000", 0.0 },
|
||||
- { "-0", -0.0 },
|
||||
- { "-000", -0.0 },
|
||||
- { "0,", 0.0 },
|
||||
- { "-0,", -0.0 },
|
||||
- { "0,0", 0.0 },
|
||||
- { "-0,0", -0.0 },
|
||||
- { "0e-10", 0.0 },
|
||||
- { "-0e-10", -0.0 },
|
||||
- { "0,e-10", 0.0 },
|
||||
- { "-0,e-10", -0.0 },
|
||||
- { "0,0e-10", 0.0 },
|
||||
- { "-0,0e-10", -0.0 },
|
||||
- { "0e-1000000", 0.0 },
|
||||
- { "-0e-1000000", -0.0 },
|
||||
- { "0,0e-1000000", 0.0 },
|
||||
- { "-0,0e-1000000", -0.0 },
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "0", 0.0 ## LSUF }, \
|
||||
+ { "000", 0.0 ## LSUF }, \
|
||||
+ { "-0", -0.0 ## LSUF }, \
|
||||
+ { "-000", -0.0 ## LSUF }, \
|
||||
+ { "0,", 0.0 ## LSUF }, \
|
||||
+ { "-0,", -0.0 ## LSUF }, \
|
||||
+ { "0,0", 0.0 ## LSUF }, \
|
||||
+ { "-0,0", -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", -0.0 ## LSUF }, \
|
||||
+ { "0,e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0,e-10", -0.0 ## LSUF }, \
|
||||
+ { "0,0e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-10", -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", -0.0 ## LSUF }, \
|
||||
+ { "0,0e-1000000", 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-1000000", -0.0 ## LSUF }, \
|
||||
+ }; \
|
||||
+ \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].in, &ep); \
|
||||
+ \
|
||||
+ if (*ep != '\0') \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected \
|
||||
+ || (copysign ## CSUF (10.0 ## LSUF, r) \
|
||||
+ != copysign ## CSUF (10.0 ## LSUF, \
|
||||
+ tests_strto ## FSUF[i].expected))) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -61,29 +101,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = strtod (tests[i].in, &ep);
|
||||
-
|
||||
- if (*ep != '\0')
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected
|
||||
- || copysign (10.0, r) != copysign (10.0, tests[i].expected))
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
79
SOURCES/glibc-RHEL-46739-9.patch
Normal file
79
SOURCES/glibc-RHEL-46739-9.patch
Normal file
@ -0,0 +1,79 @@
|
||||
commit b5d3737b305525315e0c7c93ca49eadc868eabd5
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:24:02 2024 +0000
|
||||
|
||||
Add more tests of strtod end pointer
|
||||
|
||||
Although there are some tests in tst-strtod2 and tst-strtod3 for the
|
||||
end pointer provided by strtod when it doesn't parse the whole string,
|
||||
they aren't very thorough. Add tests of more such cases to
|
||||
tst-strtod2.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index 2cb0953fa911efd0..c84bd792c1a3f511 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -1,3 +1,4 @@
|
||||
+#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -17,10 +18,46 @@ struct test_strto ## FSUF \
|
||||
{ "0x.0y", 0.0 ## LSUF, 4 }, \
|
||||
{ ".y", 0.0 ## LSUF, 0 }, \
|
||||
{ "0.y", 0.0 ## LSUF, 2 }, \
|
||||
- { ".0y", 0.0 ## LSUF, 2 } \
|
||||
+ { ".0y", 0.0 ## LSUF, 2 }, \
|
||||
+ { "1.0e", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e+", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e-", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0ex", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e+x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p+", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p-", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1px", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p+x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "INFx", INFINITY, 3 }, \
|
||||
+ { "infx", INFINITY, 3 }, \
|
||||
+ { "INFINITx", INFINITY, 3 }, \
|
||||
+ { "infinitx", INFINITY, 3 }, \
|
||||
+ { "INFINITYY", INFINITY, 8 }, \
|
||||
+ { "infinityy", INFINITY, 8 }, \
|
||||
+ { "NANx", NAN, 3 }, \
|
||||
+ { "nanx", NAN, 3 }, \
|
||||
+ { "NAN(", NAN, 3 }, \
|
||||
+ { "nan(", NAN, 3 }, \
|
||||
+ { "NAN(x", NAN, 3 }, \
|
||||
+ { "nan(x", NAN, 3 }, \
|
||||
+ { "NAN(x)y", NAN, 6 }, \
|
||||
+ { "nan(x)y", NAN, 6 }, \
|
||||
+ { "NAN(*)y", NAN, 3 }, \
|
||||
+ { "nan(*)y", NAN, 3 } \
|
||||
}; \
|
||||
\
|
||||
static int \
|
||||
+compare_strto ## FSUF (FTYPE x, FTYPE y) \
|
||||
+{ \
|
||||
+ if (isnan (x) && isnan (y)) \
|
||||
+ return 1; \
|
||||
+ return x == y; \
|
||||
+} \
|
||||
+ \
|
||||
+static int \
|
||||
test_strto ## FSUF (void) \
|
||||
{ \
|
||||
int status = 0; \
|
||||
@@ -30,7 +67,7 @@ test_strto ## FSUF (void) \
|
||||
{ \
|
||||
char *ep; \
|
||||
FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \
|
||||
- if (r != tests_strto ## FSUF[i].result) \
|
||||
+ if (!compare_strto ## FSUF (r, tests_strto ## FSUF[i].result)) \
|
||||
{ \
|
||||
char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
58
SOURCES/glibc-RHEL-46740.patch
Normal file
58
SOURCES/glibc-RHEL-46740.patch
Normal file
@ -0,0 +1,58 @@
|
||||
commit dcad78507433a9a64b8b548b19e110933f8d939a
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Thu Oct 10 17:16:35 2024 -0400
|
||||
|
||||
manual: Document stdio.h functions that may be macros
|
||||
|
||||
Glibc has two gnu-extension functions that are implemented as
|
||||
macros but not documented as such: fread_unlocked and
|
||||
fwrite_unlocked. Document them as such.
|
||||
|
||||
Additionally, putc_unlocked and getc_unlocked are documented in
|
||||
POSIX as possibly being macros. Update the manual to add a warning
|
||||
about those also, depite glibc not implementing them as macros.
|
||||
|
||||
diff --git a/manual/stdio.texi b/manual/stdio.texi
|
||||
index 98da13de32f49c7c..01fa2d0ffdbd6f5f 100644
|
||||
--- a/manual/stdio.texi
|
||||
+++ b/manual/stdio.texi
|
||||
@@ -929,6 +929,9 @@ Therefore, @var{stream} should never be an expression with side-effects.
|
||||
@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
|
||||
The @code{putc_unlocked} function is equivalent to the @code{putc}
|
||||
function except that it does not implicitly lock the stream.
|
||||
+Like @code{putc}, it may be implemented as a macro and may evaluate
|
||||
+the @var{stream} argument more than once. Therefore, @var{stream}
|
||||
+should not be an expression with side-effects.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun wint_t putwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
|
||||
@@ -1132,6 +1135,9 @@ Therefore, @var{stream} should never be an expression with side-effects.
|
||||
@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
|
||||
The @code{getc_unlocked} function is equivalent to the @code{getc}
|
||||
function except that it does not implicitly lock the stream.
|
||||
+Like @code{getc}, it may be implemented as a macro and may evaluate
|
||||
+the @var{stream} argument more than once. Therefore, @var{stream}
|
||||
+should not be an expression with side-effects.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun wint_t getwc_unlocked (FILE *@var{stream})
|
||||
@@ -1571,6 +1577,9 @@ The @code{fread_unlocked} function is equivalent to the @code{fread}
|
||||
function except that it does not implicitly lock the stream.
|
||||
|
||||
This function is a GNU extension.
|
||||
+This function may be implemented as a macro and may evaluate
|
||||
+@var{stream} more than once. Therefore, @var{stream} should not be an
|
||||
+expression with side-effects.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun size_t fwrite (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
|
||||
@@ -1589,6 +1598,9 @@ The @code{fwrite_unlocked} function is equivalent to the @code{fwrite}
|
||||
function except that it does not implicitly lock the stream.
|
||||
|
||||
This function is a GNU extension.
|
||||
+This function may be implemented as a macro and may evaluate
|
||||
+@var{stream} more than once. Therefore, @var{stream} should not be an
|
||||
+expression with side-effects.
|
||||
@end deftypefun
|
||||
|
||||
@node Formatted Output
|
76
SOURCES/glibc-RHEL-46761-1.patch
Normal file
76
SOURCES/glibc-RHEL-46761-1.patch
Normal file
@ -0,0 +1,76 @@
|
||||
commit ca6466e8be32369a658035d69542d47603e58a99
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Mon Aug 29 15:05:40 2022 +0200
|
||||
|
||||
Add test for bug 29530
|
||||
|
||||
This tests for a bug that was introduced in commit edc1686af0 ("vfprintf:
|
||||
Reuse work_buffer in group_number") and fixed as a side effect of commit
|
||||
6caddd34bd ("Remove most vfprintf width/precision-dependent allocations
|
||||
(bug 14231, bug 26211).").
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 826823a68dd36a8a..e3939b112ca2037f 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -221,6 +221,7 @@ tests := \
|
||||
tst-getline-enomem \
|
||||
tst-gets \
|
||||
tst-grouping \
|
||||
+ tst-grouping2 \
|
||||
tst-long-dbl-fphex \
|
||||
tst-obprintf \
|
||||
tst-perror \
|
||||
@@ -369,6 +370,7 @@ $(objpfx)bug14.out: $(gen-locales)
|
||||
$(objpfx)scanf13.out: $(gen-locales)
|
||||
$(objpfx)test-vfprintf.out: $(gen-locales)
|
||||
$(objpfx)tst-grouping.out: $(gen-locales)
|
||||
+$(objpfx)tst-grouping2.out: $(gen-locales)
|
||||
$(objpfx)tst-sprintf.out: $(gen-locales)
|
||||
$(objpfx)tst-sscanf.out: $(gen-locales)
|
||||
$(objpfx)tst-swprintf.out: $(gen-locales)
|
||||
diff --git a/stdio-common/tst-grouping2.c b/stdio-common/tst-grouping2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3024c942a60e51bf
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-grouping2.c
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* Test printf with grouping and large width (bug 29530)
|
||||
+ Copyright (C) 2022 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <locale.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ const int field_width = 1000;
|
||||
+ char buf[field_width + 1];
|
||||
+
|
||||
+ xsetlocale (LC_NUMERIC, "de_DE.UTF-8");
|
||||
+
|
||||
+ /* This used to crash in group_number. */
|
||||
+ TEST_COMPARE (sprintf (buf, "%'*d", field_width, 1000), field_width);
|
||||
+ TEST_COMPARE_STRING (buf + field_width - 6, " 1.000");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
183
SOURCES/glibc-RHEL-46761-2.patch
Normal file
183
SOURCES/glibc-RHEL-46761-2.patch
Normal file
@ -0,0 +1,183 @@
|
||||
Backport of the test case from this commit:
|
||||
|
||||
commit 0d50f477f47ba637b54fb03ac48d769ec4543e8d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Jan 25 08:01:00 2023 +0100
|
||||
|
||||
stdio-common: Handle -1 buffer size in __sprintf_chk & co (bug 30039)
|
||||
|
||||
This shows up as an assertion failure when sprintf is called with
|
||||
a specifier like "%.8g" and libquadmath is linked in:
|
||||
|
||||
Fatal glibc error: printf_buffer_as_file.c:31
|
||||
(__printf_buffer_as_file_commit): assertion failed:
|
||||
file->stream._IO_write_ptr <= file->next->write_end
|
||||
|
||||
Fix this by detecting pointer wraparound in __vsprintf_internal
|
||||
and saturate the addition to the end of the address space instead.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
debug/Makefile
|
||||
(missing time64 tests downstream)
|
||||
include/printf_buffer.h
|
||||
libio/iovsprintf.c
|
||||
(not included in test-only backport)
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index ddae3817aef9afad..563e6249121e8bc9 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -187,6 +187,10 @@ LDFLAGS-tst-backtrace6 = -rdynamic
|
||||
|
||||
CFLAGS-tst-ssp-1.c += -fstack-protector-all
|
||||
|
||||
+# Disable compiler optimizations around vsprintf (the function under test).
|
||||
+CFLAGS-tst-sprintf-fortify-unchecked.c = \
|
||||
+ -fno-builtin-vsprintf -fno-builtin-__vsprintf_chk
|
||||
+
|
||||
tests = backtrace-tst \
|
||||
tst-longjmp_chk \
|
||||
test-strcpy_chk \
|
||||
@@ -199,6 +203,7 @@ tests = backtrace-tst \
|
||||
tst-backtrace5 \
|
||||
tst-backtrace6 \
|
||||
tst-realpath-chk \
|
||||
+ tst-sprintf-fortify-unchecked \
|
||||
$(tests-all-chk) \
|
||||
|
||||
ifeq ($(have-ssp),yes)
|
||||
diff --git a/debug/tst-sprintf-fortify-unchecked.c b/debug/tst-sprintf-fortify-unchecked.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7c7bd1b5e4fe12e8
|
||||
--- /dev/null
|
||||
+++ b/debug/tst-sprintf-fortify-unchecked.c
|
||||
@@ -0,0 +1,126 @@
|
||||
+/* Tests for fortified sprintf with unknown buffer bounds (bug 30039).
|
||||
+ Copyright (C) 2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <printf.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+/* This test is not built with _FORTIFY_SOURCE. Instead it calls the
|
||||
+ appropriate implementation directly. The fortify mode is specified
|
||||
+ in this variable. */
|
||||
+static int fortify_mode;
|
||||
+
|
||||
+/* This does not handle long-double redirects etc., but we test only
|
||||
+ format strings that stay within the confines of the base
|
||||
+ implementation. */
|
||||
+int __vsprintf_chk (char *s, int flag, size_t slen, const char *format,
|
||||
+ va_list ap);
|
||||
+
|
||||
+/* Invoke vsprintf or __vsprintf_chk according to fortify_mode. */
|
||||
+static int
|
||||
+my_vsprintf (char *buf, const char *format, va_list ap)
|
||||
+{
|
||||
+ int result;
|
||||
+ if (fortify_mode == 0)
|
||||
+ result = vsprintf (buf, format, ap);
|
||||
+ else
|
||||
+ /* Call the fortified version with an unspecified length. */
|
||||
+ result = __vsprintf_chk (buf, fortify_mode - 1, -1, format, ap);
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/* Run one test, with the specified expected output. */
|
||||
+static void __attribute ((format (printf, 2, 3)))
|
||||
+do_check (const char *expected, const char *format, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ va_start (ap, format);
|
||||
+
|
||||
+ char buf_expected[24];
|
||||
+ memset (buf_expected, '@', sizeof (buf_expected));
|
||||
+ TEST_VERIFY (strlen (expected) < sizeof (buf_expected));
|
||||
+ strcpy (buf_expected, expected);
|
||||
+
|
||||
+ char buf[sizeof (buf_expected)];
|
||||
+ memset (buf, '@', sizeof (buf));
|
||||
+
|
||||
+ int ret = my_vsprintf (buf, format, ap);
|
||||
+ TEST_COMPARE_BLOB (buf_expected, sizeof (buf_expected), buf, sizeof (buf));
|
||||
+ TEST_COMPARE (ret, strlen (expected));
|
||||
+
|
||||
+ va_end (ap);
|
||||
+}
|
||||
+
|
||||
+/* Run the tests in all fortify modes. */
|
||||
+static void
|
||||
+do_tests (void)
|
||||
+{
|
||||
+ for (fortify_mode = 0; fortify_mode <= 3; ++fortify_mode)
|
||||
+ {
|
||||
+ do_check ("0", "%d", 0);
|
||||
+ do_check ("-2147483648", "%d", -2147483647 - 1);
|
||||
+ do_check ("-9223372036854775808", "%lld", -9223372036854775807LL - 1);
|
||||
+ do_check ("", "%s", "");
|
||||
+ do_check (" ", "%22s", "");
|
||||
+ do_check ("XXXXXXXXXXXXXXXXXXXXXX", "%s", "XXXXXXXXXXXXXXXXXXXXXX");
|
||||
+ do_check ("1.125000", "%f", 1.125);
|
||||
+ do_check ("1.125", "%g", 1.125);
|
||||
+ do_check ("1.125", "%.8g", 1.125);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* printf callback that falls back to the glibc-supplied
|
||||
+ implementation. */
|
||||
+static int
|
||||
+dummy_printf_function (FILE *__stream,
|
||||
+ const struct printf_info *__info,
|
||||
+ const void *const *__args)
|
||||
+{
|
||||
+ return -2; /* Request fallback. */
|
||||
+}
|
||||
+
|
||||
+/* Likewise for the type information. */
|
||||
+static int
|
||||
+dummy_arginfo_function (const struct printf_info *info,
|
||||
+ size_t n, int *argtypes, int *size)
|
||||
+{
|
||||
+ return -1; /* Request fallback. */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ do_tests ();
|
||||
+
|
||||
+ /* Activate __printf_function_invoke mode. */
|
||||
+ register_printf_specifier ('d', dummy_printf_function,
|
||||
+ dummy_arginfo_function);
|
||||
+ register_printf_specifier ('g', dummy_printf_function,
|
||||
+ dummy_arginfo_function);
|
||||
+ register_printf_specifier ('s', dummy_printf_function,
|
||||
+ dummy_arginfo_function);
|
||||
+
|
||||
+ /* Rerun the tests with callback functions. */
|
||||
+ do_tests ();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
102
SOURCES/glibc-RHEL-46761-3.patch
Normal file
102
SOURCES/glibc-RHEL-46761-3.patch
Normal file
@ -0,0 +1,102 @@
|
||||
Backport of the test case from the upstream commit. Note
|
||||
that the test fails in the version included here.
|
||||
|
||||
commit c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Jan 19 12:50:20 2023 +0100
|
||||
|
||||
Account for grouping in printf width (bug 30068)
|
||||
|
||||
This is a partial fix for mishandling of grouping when formatting
|
||||
integers. It properly computes the width in the presence of grouping
|
||||
characters when the width is larger than the number of significant
|
||||
digits. The precision related issue is documented in bug 23432.
|
||||
|
||||
Co-authored-by: Andreas Schwab <schwab@suse.de>
|
||||
|
||||
Conflicts:
|
||||
stdio-common/Makefile
|
||||
(missing tests downstream)
|
||||
stdio-common/vfprintf-process-arg.c
|
||||
(not included in backport)
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index e3939b112ca2037f..74e0edff73a9e468 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -222,6 +222,7 @@ tests := \
|
||||
tst-gets \
|
||||
tst-grouping \
|
||||
tst-grouping2 \
|
||||
+ tst-grouping3 \
|
||||
tst-long-dbl-fphex \
|
||||
tst-obprintf \
|
||||
tst-perror \
|
||||
@@ -375,6 +376,7 @@ $(objpfx)tst-sprintf.out: $(gen-locales)
|
||||
$(objpfx)tst-sscanf.out: $(gen-locales)
|
||||
$(objpfx)tst-swprintf.out: $(gen-locales)
|
||||
$(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales)
|
||||
+$(objpfx)tst-grouping3.out: $(gen-locales)
|
||||
endif
|
||||
|
||||
tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \
|
||||
diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e9e39218e25a2720
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-grouping3.c
|
||||
@@ -0,0 +1,54 @@
|
||||
+/* Test printf with grouping and padding (bug 30068)
|
||||
+ Copyright (C) 2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <locale.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char buf[80];
|
||||
+
|
||||
+ xsetlocale (LC_NUMERIC, "de_DE.UTF-8");
|
||||
+
|
||||
+ /* The format string has the following conversion specifier:
|
||||
+ ' - Use thousands grouping.
|
||||
+ + - The result of a signed conversion shall begin with a sign.
|
||||
+ - - Left justified.
|
||||
+ 13 - Minimum 13 bytes of width.
|
||||
+ 9 - Minimum 9 digits of precision.
|
||||
+
|
||||
+ In bug 30068 the grouping characters were not accounted for in
|
||||
+ the width, and were added after the fact resulting in a 15-byte
|
||||
+ output instead of a 13-byte output. The two additional bytes
|
||||
+ come from the locale-specific thousands separator. This increase
|
||||
+ in size could result in a buffer overflow if a reasonable caller
|
||||
+ calculated the size of the expected buffer using nl_langinfo to
|
||||
+ determine the sie of THOUSEP in bytes.
|
||||
+
|
||||
+ This bug is distinct from bug 23432 which has to do with the
|
||||
+ minimum precision calculation (digit based). */
|
||||
+ sprintf (buf, "%+-'13.9d", 1234567);
|
||||
+ TEST_COMPARE_STRING (buf, "+001.234.567 ");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
17
SOURCES/glibc-RHEL-46761-4.patch
Normal file
17
SOURCES/glibc-RHEL-46761-4.patch
Normal file
@ -0,0 +1,17 @@
|
||||
Adjust the test expectation for stdio-common/tst-grouping3 to match
|
||||
the state of the RHEL 9 printf implementation, which does not add
|
||||
zero padding when grouping integers.
|
||||
|
||||
diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c
|
||||
index e9e39218e25a2720..5a247cfe3fb8564f 100644
|
||||
--- a/stdio-common/tst-grouping3.c
|
||||
+++ b/stdio-common/tst-grouping3.c
|
||||
@@ -46,7 +46,7 @@ do_test (void)
|
||||
This bug is distinct from bug 23432 which has to do with the
|
||||
minimum precision calculation (digit based). */
|
||||
sprintf (buf, "%+-'13.9d", 1234567);
|
||||
- TEST_COMPARE_STRING (buf, "+001.234.567 ");
|
||||
+ TEST_COMPARE_STRING (buf, "+1.234.567 ");
|
||||
|
||||
return 0;
|
||||
}
|
120
SOURCES/glibc-RHEL-46761-5.patch
Normal file
120
SOURCES/glibc-RHEL-46761-5.patch
Normal file
@ -0,0 +1,120 @@
|
||||
commit be7a5468d4f694ee8d052b537141f51af43ca7f2
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Oct 3 15:09:36 2023 -0300
|
||||
|
||||
debug: Add regression tests for BZ 30932
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
Conflicts:
|
||||
debug/Makefile (fixup context)
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index 563e6249121e8bc9..ab49346698116fc6 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -110,6 +110,7 @@ CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1
|
||||
CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||
CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||
+CFLAGS-tst-sprintf-fortify-rdonly.c += -D_FORTIFY_SOURCE=2
|
||||
|
||||
# _FORTIFY_SOURCE tests.
|
||||
# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
|
||||
@@ -203,6 +204,7 @@ tests = backtrace-tst \
|
||||
tst-backtrace5 \
|
||||
tst-backtrace6 \
|
||||
tst-realpath-chk \
|
||||
+ tst-sprintf-fortify-rdonly \
|
||||
tst-sprintf-fortify-unchecked \
|
||||
$(tests-all-chk) \
|
||||
|
||||
diff --git a/debug/tst-sprintf-fortify-rdonly.c b/debug/tst-sprintf-fortify-rdonly.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..78dece9102d7dfd3
|
||||
--- /dev/null
|
||||
+++ b/debug/tst-sprintf-fortify-rdonly.c
|
||||
@@ -0,0 +1,82 @@
|
||||
+/* Testcase for BZ 30932.
|
||||
+ Copyright (C) 2023 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/resource.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
+
|
||||
+jmp_buf chk_fail_buf;
|
||||
+bool chk_fail_ok;
|
||||
+
|
||||
+const char *str2 = "F";
|
||||
+char buf2[10] = "%s";
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct rlimit rl;
|
||||
+ int max_fd = 24;
|
||||
+
|
||||
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
|
||||
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
|
||||
+
|
||||
+ max_fd = (rl.rlim_cur < max_fd ? rl.rlim_cur : max_fd);
|
||||
+ rl.rlim_cur = max_fd;
|
||||
+
|
||||
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
|
||||
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
|
||||
+
|
||||
+ /* Exhaust the file descriptor limit with temporary files. */
|
||||
+ int nfiles = 0;
|
||||
+ for (; nfiles < max_fd; nfiles++)
|
||||
+ {
|
||||
+ int fd = create_temp_file ("tst-sprintf-fortify-rdonly-.", NULL);
|
||||
+ if (fd == -1)
|
||||
+ {
|
||||
+ if (errno != EMFILE)
|
||||
+ FAIL_EXIT1 ("create_temp_file: %m");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ TEST_VERIFY_EXIT (nfiles != 0);
|
||||
+
|
||||
+ /* When the format string is writable and contains %n,
|
||||
+ with -D_FORTIFY_SOURCE=2 it causes __chk_fail. However, if libc can not
|
||||
+ open procfs to check if the input format string in within a writable
|
||||
+ memory segment, the fortify version can not perform the check. */
|
||||
+ char buf[128];
|
||||
+ int n1;
|
||||
+ int n2;
|
||||
+
|
||||
+ strcpy (buf2 + 2, "%n%s%n");
|
||||
+ if (sprintf (buf, buf2, str2, &n1, str2, &n2) != 2
|
||||
+ || n1 != 1 || n2 != 2)
|
||||
+ FAIL_EXIT1 ("sprintf failed: %s %d %d", buf, n1, n2);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
111
SOURCES/glibc-RHEL-46761-6.patch
Normal file
111
SOURCES/glibc-RHEL-46761-6.patch
Normal file
@ -0,0 +1,111 @@
|
||||
This reverts glibc-RHEL-46761-5.patch, thus dropping the associated test
|
||||
case.
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index cb93ed80da57f2cc..563e6249121e8bc9 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -110,7 +110,6 @@ CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1
|
||||
CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||
CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||
-CFLAGS-tst-sprintf-fortify-rdonly.c += -D_FORTIFY_SOURCE=2
|
||||
|
||||
# _FORTIFY_SOURCE tests.
|
||||
# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
|
||||
@@ -204,7 +203,6 @@ tests = backtrace-tst \
|
||||
tst-backtrace5 \
|
||||
tst-backtrace6 \
|
||||
tst-realpath-chk \
|
||||
- tst-sprintf-fortify-rdonly \
|
||||
tst-sprintf-fortify-unchecked \
|
||||
$(tests-all-chk) \
|
||||
|
||||
diff --git a/debug/tst-sprintf-fortify-rdonly.c b/debug/tst-sprintf-fortify-rdonly.c
|
||||
deleted file mode 100644
|
||||
index 78dece9102d7dfd3..0000000000000000
|
||||
--- a/debug/tst-sprintf-fortify-rdonly.c
|
||||
+++ /dev/null
|
||||
@@ -1,82 +0,0 @@
|
||||
-/* Testcase for BZ 30932.
|
||||
- Copyright (C) 2023 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
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <errno.h>
|
||||
-#include <setjmp.h>
|
||||
-#include <stdbool.h>
|
||||
-#include <stdio.h>
|
||||
-#include <string.h>
|
||||
-#include <sys/resource.h>
|
||||
-#include <unistd.h>
|
||||
-
|
||||
-#include <support/check.h>
|
||||
-#include <support/support.h>
|
||||
-#include <support/temp_file.h>
|
||||
-
|
||||
-jmp_buf chk_fail_buf;
|
||||
-bool chk_fail_ok;
|
||||
-
|
||||
-const char *str2 = "F";
|
||||
-char buf2[10] = "%s";
|
||||
-
|
||||
-static int
|
||||
-do_test (void)
|
||||
-{
|
||||
- struct rlimit rl;
|
||||
- int max_fd = 24;
|
||||
-
|
||||
- if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
|
||||
- FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
|
||||
-
|
||||
- max_fd = (rl.rlim_cur < max_fd ? rl.rlim_cur : max_fd);
|
||||
- rl.rlim_cur = max_fd;
|
||||
-
|
||||
- if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
|
||||
- FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
|
||||
-
|
||||
- /* Exhaust the file descriptor limit with temporary files. */
|
||||
- int nfiles = 0;
|
||||
- for (; nfiles < max_fd; nfiles++)
|
||||
- {
|
||||
- int fd = create_temp_file ("tst-sprintf-fortify-rdonly-.", NULL);
|
||||
- if (fd == -1)
|
||||
- {
|
||||
- if (errno != EMFILE)
|
||||
- FAIL_EXIT1 ("create_temp_file: %m");
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- TEST_VERIFY_EXIT (nfiles != 0);
|
||||
-
|
||||
- /* When the format string is writable and contains %n,
|
||||
- with -D_FORTIFY_SOURCE=2 it causes __chk_fail. However, if libc can not
|
||||
- open procfs to check if the input format string in within a writable
|
||||
- memory segment, the fortify version can not perform the check. */
|
||||
- char buf[128];
|
||||
- int n1;
|
||||
- int n2;
|
||||
-
|
||||
- strcpy (buf2 + 2, "%n%s%n");
|
||||
- if (sprintf (buf, buf2, str2, &n1, str2, &n2) != 2
|
||||
- || n1 != 1 || n2 != 2)
|
||||
- FAIL_EXIT1 ("sprintf failed: %s %d %d", buf, n1, n2);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-#include <support/test-driver.c>
|
83
SOURCES/glibc-RHEL-46979-1.patch
Normal file
83
SOURCES/glibc-RHEL-46979-1.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From a65ff76c9a1811dd2396ab45563f645579c0e687 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 27 Oct 2022 11:36:44 +0200
|
||||
Subject: ld.so: Export tls_init_tp_called as __rtld_tls_init_tp_called
|
||||
|
||||
This allows the rest of dynamic loader to check whether the TCB
|
||||
has been set up (and THREAD_GETMEM and THREAD_SETMEM will work).
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
|
||||
|
||||
Conflicts:
|
||||
Regenerated for context changes.
|
||||
|
||||
diff -rup a/elf/rtld.c b/elf/rtld.c
|
||||
--- a/elf/rtld.c 2024-08-22 17:57:02.000830481 -0400
|
||||
+++ b/elf/rtld.c 2024-08-22 17:59:30.666562835 -0400
|
||||
@@ -740,7 +740,7 @@ match_version (const char *string, struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static bool tls_init_tp_called;
|
||||
+bool __rtld_tls_init_tp_called;
|
||||
|
||||
static void *
|
||||
init_tls (size_t naudit)
|
||||
@@ -812,7 +812,7 @@ cannot allocate TLS data structures for
|
||||
if (__glibc_unlikely (lossage != NULL))
|
||||
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
|
||||
__tls_init_tp ();
|
||||
- tls_init_tp_called = true;
|
||||
+ __rtld_tls_init_tp_called = true;
|
||||
|
||||
return tcbp;
|
||||
}
|
||||
@@ -2057,7 +2057,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
|
||||
used. Trying to do it lazily is too hairy to try when there could be
|
||||
multiple threads (from a non-TLS-using libpthread). */
|
||||
- bool was_tls_init_tp_called = tls_init_tp_called;
|
||||
+ bool was_tls_init_tp_called = __rtld_tls_init_tp_called;
|
||||
if (tcbp == NULL)
|
||||
tcbp = init_tls (0);
|
||||
|
||||
@@ -2411,7 +2411,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
_dl_protect_relro (l);
|
||||
|
||||
/* Add object to slot information data if necessasy. */
|
||||
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l, true);
|
||||
}
|
||||
}
|
||||
@@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
consider_profiling);
|
||||
|
||||
/* Add object to slot information data if necessasy. */
|
||||
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l, true);
|
||||
}
|
||||
rtld_timer_stop (&relocate_time, start);
|
||||
@@ -2488,7 +2488,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
_dl_allocate_tls_init (tcbp, true);
|
||||
|
||||
/* And finally install it for the main thread. */
|
||||
- if (! tls_init_tp_called)
|
||||
+ if (! __rtld_tls_init_tp_called)
|
||||
{
|
||||
const char *lossage = TLS_INIT_TP (tcbp);
|
||||
if (__glibc_unlikely (lossage != NULL))
|
||||
diff -rup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
--- a/sysdeps/generic/ldsodefs.h 2024-08-22 17:57:02.011830906 -0400
|
||||
+++ b/sysdeps/generic/ldsodefs.h 2024-08-22 17:58:10.900487160 -0400
|
||||
@@ -1262,6 +1262,9 @@ extern void *_dl_allocate_tls_storage (v
|
||||
extern void *_dl_allocate_tls_init (void *result, bool main_thread);
|
||||
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||
|
||||
+/* True if the TCB has been set up. */
|
||||
+extern bool __rtld_tls_init_tp_called attribute_hidden;
|
||||
+
|
||||
/* Deallocate memory allocated with _dl_allocate_tls. */
|
||||
extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb);
|
||||
rtld_hidden_proto (_dl_deallocate_tls)
|
1030
SOURCES/glibc-RHEL-46979-2.patch
Normal file
1030
SOURCES/glibc-RHEL-46979-2.patch
Normal file
File diff suppressed because it is too large
Load Diff
82
SOURCES/glibc-RHEL-46979-3.patch
Normal file
82
SOURCES/glibc-RHEL-46979-3.patch
Normal file
@ -0,0 +1,82 @@
|
||||
Extra changes needed for backport:
|
||||
|
||||
* rename field "rtld_catch" to "rtld_catch_f" to avoid conflict
|
||||
between "struct rtld-catch" and rtld_catch macro
|
||||
|
||||
* move rtld_catch into one of the unused padding fields to preserve
|
||||
ABI
|
||||
|
||||
* Validate that the padding fields used don't overlap other fields.
|
||||
|
||||
diff -rup a/elf/dl-catch.c b/elf/dl-catch.c
|
||||
--- a/elf/dl-catch.c 2024-09-04 16:30:02.086402568 -0400
|
||||
+++ b/elf/dl-catch.c 2024-09-04 16:55:01.933440181 -0400
|
||||
@@ -59,7 +59,7 @@ get_catch (void)
|
||||
return rtld_catch_notls;
|
||||
else
|
||||
#endif
|
||||
- return THREAD_GETMEM (THREAD_SELF, rtld_catch);
|
||||
+ return THREAD_GETMEM (THREAD_SELF, rtld_catch_f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -70,7 +70,7 @@ set_catch (struct rtld_catch *catch)
|
||||
rtld_catch_notls = catch;
|
||||
else
|
||||
#endif
|
||||
- THREAD_SETMEM (THREAD_SELF, rtld_catch, catch);
|
||||
+ THREAD_SETMEM (THREAD_SELF, rtld_catch_f, catch);
|
||||
}
|
||||
|
||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||
diff -rup a/nptl/descr.h b/nptl/descr.h
|
||||
--- a/nptl/descr.h 2024-08-29 11:29:16.801811033 -0400
|
||||
+++ b/nptl/descr.h 2024-08-29 11:48:56.547644398 -0400
|
||||
@@ -164,6 +164,12 @@ struct pthread
|
||||
void *__padding[24];
|
||||
};
|
||||
|
||||
+#ifdef __x86_64__
|
||||
+#define rtld_catch_f header.__padding[7]
|
||||
+#else
|
||||
+#define rtld_catch_f __padding[23]
|
||||
+#endif
|
||||
+
|
||||
/* This descriptor's link on the GL (dl_stack_used) or
|
||||
GL (dl_stack_user) list. */
|
||||
list_t list;
|
||||
@@ -396,9 +402,6 @@ struct pthread
|
||||
masked.) */
|
||||
sigset_t sigmask;
|
||||
|
||||
- /* Used by the exception handling implementation in the dynamic loader. */
|
||||
- struct rtld_catch *rtld_catch;
|
||||
-
|
||||
/* Indicates whether is a C11 thread created by thrd_creat. */
|
||||
bool c11;
|
||||
|
||||
@@ -432,6 +435,12 @@ struct pthread
|
||||
+ sizeof ((struct pthread) {}.rseq_area))
|
||||
} __attribute ((aligned (TCB_ALIGNMENT)));
|
||||
|
||||
+#ifdef __x86_64__
|
||||
+_Static_assert (sizeof ((*(struct pthread *)0).header) > sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||
+#else
|
||||
+_Static_assert (sizeof ((*(struct pthread *)0).header) < sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||
+#endif
|
||||
+
|
||||
static inline bool
|
||||
cancel_enabled_and_canceled (int value)
|
||||
{
|
||||
diff -rup a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
|
||||
--- a/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:29:16.810811382 -0400
|
||||
+++ b/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:35:45.262899113 -0400
|
||||
@@ -50,7 +50,7 @@ typedef struct
|
||||
struct hurd_sigstate *_hurd_sigstate;
|
||||
|
||||
/* Used by the exception handling implementation in the dynamic loader. */
|
||||
- struct rtld_catch *rtld_catch;
|
||||
+ struct rtld_catch *rtld_catch_f;
|
||||
} tcbhead_t;
|
||||
#endif
|
||||
|
79
SOURCES/glibc-RHEL-46979-4.patch
Normal file
79
SOURCES/glibc-RHEL-46979-4.patch
Normal file
@ -0,0 +1,79 @@
|
||||
New test case to verify padding usage.
|
||||
|
||||
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||
index ff4d590f11c38277..9a56d34313d06444 100644
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -319,6 +319,8 @@ tests-internal := tst-robustpi8 tst-rwlock19 tst-rwlock20 \
|
||||
tst-barrier5 tst-signal7 tst-mutex8 tst-mutex8-static \
|
||||
tst-mutexpi8 tst-mutexpi8-static \
|
||||
tst-setgetname \
|
||||
+ tst-nptl-padding \
|
||||
+ # tests-internal
|
||||
|
||||
xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
|
||||
tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 tst-setgroups \
|
||||
diff --git a/nptl/tst-nptl-padding.c b/nptl/tst-nptl-padding.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5bb64f4a54335e36
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-nptl-padding.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+/* Downstream-only test for verifying that fields that have been
|
||||
+ relocated into struct pthread padding actually use the padding.
|
||||
+
|
||||
+ At present, only rtld_catch (downstream: rtld_catch_f) has been
|
||||
+ placed into padding. */
|
||||
+
|
||||
+#include <descr.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct pthread descr;
|
||||
+
|
||||
+ /* Mark the entire descriptor as used. */
|
||||
+ memset (&descr, 0xff, sizeof (descr));
|
||||
+
|
||||
+ /* Mark the padding as unused. */
|
||||
+#ifdef __x86_64__
|
||||
+ /* Special case: Usable padding is in the header. */
|
||||
+ memset (&descr.header.__padding, 0, sizeof (descr.header.__padding));
|
||||
+#else
|
||||
+ /* The padding should be directly adjacent to the first real
|
||||
+ struct field. */
|
||||
+ TEST_COMPARE (sizeof (descr.__padding), offsetof (struct pthread, list));
|
||||
+
|
||||
+ /* Clear the unused tail of the padding. */
|
||||
+ {
|
||||
+ char *base = (char *) &descr;
|
||||
+ char *end_of_header = base + sizeof (descr.header);
|
||||
+ char *end_of_padding = base + sizeof (descr.__padding);
|
||||
+ memset (end_of_header, 0, end_of_padding - end_of_header);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* These fields are not in padding and should remain marked as used. */
|
||||
+ TEST_COMPARE (descr.header.gscope_flag, -1);
|
||||
+ TEST_COMPARE ((intptr_t) descr.list.next, -1);
|
||||
+ TEST_COMPARE ((intptr_t) descr.list.prev, -1);
|
||||
+
|
||||
+ /* But this field remains in padding. */
|
||||
+ TEST_COMPARE ((intptr_t) descr.rtld_catch_f, 0);
|
||||
+
|
||||
+ /* Write to all padding-relocated fields below to show that they
|
||||
+ have independent locations. */
|
||||
+ struct rtld_catch *rtld_catch_dummy = (void *) "rtld_catch_dummy";
|
||||
+ descr.rtld_catch_f = rtld_catch_dummy;
|
||||
+
|
||||
+ TEST_VERIFY (descr.rtld_catch_f == rtld_catch_dummy);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
146
SOURCES/glibc-RHEL-47467.patch
Normal file
146
SOURCES/glibc-RHEL-47467.patch
Normal file
@ -0,0 +1,146 @@
|
||||
commit b7d4de086ce7fcc531cdd67a61dc27b5b3eff482
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Aug 5 16:01:12 2024 +0200
|
||||
|
||||
manual: Describe struct link_map, support link maps with dlinfo
|
||||
|
||||
This does not describe how to use RTLD_DI_ORIGIN and l_name
|
||||
to reconstruct a full path for the an object. The reason
|
||||
is that I think we should not recommend further use of
|
||||
RTLD_DI_ORIGIN due to its buffer overflow potential (bug 24298).
|
||||
This should be covered by another dlinfo extension. It would
|
||||
also obsolete the need for the dladdr approach to obtain
|
||||
the file name for the main executable.
|
||||
|
||||
Obtaining the lowest address from load segments in program
|
||||
headers is quite clumsy and should be provided directly
|
||||
via dlinfo.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
|
||||
index 39d0a4c4b908e87b..d59dca2b7a916889 100644
|
||||
--- a/manual/dynlink.texi
|
||||
+++ b/manual/dynlink.texi
|
||||
@@ -351,16 +351,119 @@ support the XGETBV instruction.
|
||||
@node Dynamic Linker Introspection
|
||||
@section Dynamic Linker Introspection
|
||||
|
||||
-@Theglibc{} provides various functions for querying information from the
|
||||
+@Theglibc{} provides various facilities for querying information from the
|
||||
dynamic linker.
|
||||
|
||||
+@deftp {Data Type} {struct link_map}
|
||||
+
|
||||
+@cindex link map
|
||||
+A @dfn{link map} is associated with the main executable and each shared
|
||||
+object. Some fields of the link map are accessible to applications and
|
||||
+exposed through the @code{struct link_map}. Applications must not modify
|
||||
+the link map directly.
|
||||
+
|
||||
+Pointers to link maps can be obtained from the @code{_r_debug} variable,
|
||||
+from the @code{RTLD_DI_LINKMAP} request for @code{dlinfo}, and from the
|
||||
+@code{_dl_find_object} function. See below for details.
|
||||
+
|
||||
+@table @code
|
||||
+@item l_addr
|
||||
+@cindex load address
|
||||
+This field contains the @dfn{load address} of the object. This is the
|
||||
+offset that needs to be applied to unrelocated addresses in the object
|
||||
+image (as stored on disk) to form an address that can be used at run
|
||||
+time for accessing data or running code. For position-dependent
|
||||
+executables, the load address is typically zero, and no adjustment is
|
||||
+required. For position-independent objects, the @code{l_addr} field
|
||||
+usually contains the address of the object's ELF header in the process
|
||||
+image. However, this correspondence is not guaranteed because the ELF
|
||||
+header might not be mapped at all, and the ELF file as stored on disk
|
||||
+might use zero as the lowest virtual address. Due to the second
|
||||
+variable, values of the @code{l_addr} field do not necessarily uniquely
|
||||
+identify a shared object.
|
||||
+
|
||||
+On Linux, to obtain the lowest loaded address of the main program, use
|
||||
+@code{getauxval} to obtain the @code{AT_PHDR} and @code{AT_PHNUM} values
|
||||
+for the current process. Alternatively, call
|
||||
+@samp{dlinfo (_r_debug.r_map, &@var{phdr})}
|
||||
+to obtain the number of program headers, and the address of the program
|
||||
+header array will be stored in @var{phdr}
|
||||
+(of type @code{const ElfW(Phdr) *}, as explained below).
|
||||
+These values allow processing the array of program headers and the
|
||||
+address information in the @code{PT_LOAD} entries among them.
|
||||
+This works even when the program was started with an explicit loader
|
||||
+invocation.
|
||||
+
|
||||
+@item l_name
|
||||
+For a shared object, this field contains the file name that the
|
||||
+@theglibc{} dynamic loader used when opening the object. This can be
|
||||
+a relative path (relative to the current directory at process start,
|
||||
+or if the object was loaded later, via @code{dlopen} or
|
||||
+@code{dlmopen}). Symbolic links are not necessarily resolved.
|
||||
+
|
||||
+For the main executable, @code{l_name} is @samp{""} (the empty string).
|
||||
+(The main executable is not loaded by @theglibc{}, so its file name is
|
||||
+not available.) On Linux, the main executable is available as
|
||||
+@file{/proc/self/exe} (unless an explicit loader invocation was used to
|
||||
+start the program). The file name @file{/proc/self/exe} continues to
|
||||
+resolve to the same file even if it is moved within or deleted from the
|
||||
+file system. Its current location can be read using @code{readlink}.
|
||||
+@xref{Symbolic Links}. (Although @file{/proc/self/exe} is not actually
|
||||
+a symbol link, it is only presented as one.) Note that @file{/proc} may
|
||||
+not be mounted, in which case @file{/proc/self/exe} is not available.
|
||||
+
|
||||
+If an explicit loader invocation is used (such as @samp{ld.so
|
||||
+/usr/bin/emacs}), the @file{/proc/self/exe} approach does not work
|
||||
+because the file name refers to the dynamic linker @code{ld.so}, and not
|
||||
+the @code{/usr/bin/emacs} program. An approximation to the executable
|
||||
+path is still available in the @code{@var{info}.dli_fname} member after
|
||||
+calling @samp{dladdr (_r_debug.r_map->l_ld, &@var{info})}. Note that
|
||||
+this could be a relative path, and it is supplied by the process that
|
||||
+created the current process, not the kernel, so it could be inaccurate.
|
||||
+
|
||||
+@item l_ld
|
||||
+This is a pointer to the ELF dynamic segment, an array of tag/value
|
||||
+pairs that provide various pieces of information that the dynamic
|
||||
+linking process uses. On most architectures, addresses in the dynamic
|
||||
+segment are relocated at run time, but on some architectures and in some
|
||||
+run-time configurations, it is necessary to add the @code{l_addr} field
|
||||
+value to obtain a proper address.
|
||||
+
|
||||
+@item l_prev
|
||||
+@itemx l_next
|
||||
+These fields are used to maintain a double-linked linked list of all
|
||||
+link maps within one @code{dlmopen} namespace. Note that there is
|
||||
+currently no thread-safe way to iterate over this list. The
|
||||
+callback-based @code{dl_iterate_phdr} interface can be used instead.
|
||||
+@end table
|
||||
+@end deftp
|
||||
+
|
||||
+@strong{Portability note:} It is not possible to create a @code{struct
|
||||
+link_map} object and pass a pointer to a function that expects a
|
||||
+@code{struct link_map *} argument. Only link map pointers initially
|
||||
+supplied by @theglibc{} are permitted as arguments. In current versions
|
||||
+of @theglibc{}, handles returned by @code{dlopen} and @code{dlmopen} are
|
||||
+pointers to link maps. However, this is not a portable assumption, and
|
||||
+may even change in future versions of @theglibc{}. To obtain the link
|
||||
+map associated with a handle, see @code{dlinfo} and
|
||||
+@code{RTLD_DI_LINKMAP} below. If a function accepts both
|
||||
+@code{dlopen}/@code{dlmopen} handles and @code{struct link_map} pointers
|
||||
+in its @code{void *} argument, that is documented explicitly.
|
||||
+
|
||||
+@subsection Querying information for loaded objects
|
||||
+
|
||||
+The @code{dlinfo} function provides access to internal information
|
||||
+associated with @code{dlopen}/@code{dlmopen} handles and link maps.
|
||||
+
|
||||
@deftypefun {int} dlinfo (void *@var{handle}, int @var{request}, void *@var{arg})
|
||||
@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
|
||||
@standards{GNU, dlfcn.h}
|
||||
This function returns information about @var{handle} in the memory
|
||||
location @var{arg}, based on @var{request}. The @var{handle} argument
|
||||
must be a pointer returned by @code{dlopen} or @code{dlmopen}; it must
|
||||
-not have been closed by @code{dlclose}.
|
||||
+not have been closed by @code{dlclose}. Alternatively, @var{handle}
|
||||
+can be a @code{struct link_map *} value for a link map of an object
|
||||
+that has not been closed.
|
||||
|
||||
On success, @code{dlinfo} returns 0 for most request types; exceptions
|
||||
are noted below. If there is an error, the function returns @math{-1},
|
51
SOURCES/glibc-RHEL-49489-1.patch
Normal file
51
SOURCES/glibc-RHEL-49489-1.patch
Normal file
@ -0,0 +1,51 @@
|
||||
commit 9b7651410375ec8848a1944992d663d514db4ba7
|
||||
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||
Date: Thu Jul 11 11:28:53 2024 +0200
|
||||
|
||||
s390x: Fix segfault in wcsncmp [BZ #31934]
|
||||
|
||||
The z13/vector-optimized wcsncmp implementation segfaults if n=1
|
||||
and there is only one character (equal on both strings) before
|
||||
the page end. Then it loads and compares one character and misses
|
||||
to check n again. The following load fails.
|
||||
|
||||
This patch removes the extra load and compare of the first character
|
||||
and just start with the loop which uses vector-load-to-block-boundary.
|
||||
This code-path also checks n.
|
||||
|
||||
With this patch both tests are passing:
|
||||
- the simplified one mentioned in the bugzilla 31934
|
||||
- the full one in Florian Weimer's patch:
|
||||
"manual: Document a GNU extension for strncmp/wcsncmp"
|
||||
(https://patchwork.sourceware.org/project/glibc/patch/874j9eml6y.fsf@oldenburg.str.redhat.com/):
|
||||
On s390x-linux-gnu (z16), the new wcsncmp test fails due to bug 31934.
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S
|
||||
index bf6dfa6bc2..8b081567a2 100644
|
||||
--- a/sysdeps/s390/wcsncmp-vx.S
|
||||
+++ b/sysdeps/s390/wcsncmp-vx.S
|
||||
@@ -59,14 +59,7 @@ ENTRY(WCSNCMP_Z13)
|
||||
sllg %r4,%r4,2 /* Convert character-count to byte-count. */
|
||||
locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
|
||||
|
||||
- /* Check first character without vector load. */
|
||||
- lghi %r5,4 /* current_len = 4 bytes. */
|
||||
- /* Check s1/2[0]. */
|
||||
- lt %r0,0(%r2)
|
||||
- l %r1,0(%r3)
|
||||
- je .Lend_cmp_one_char
|
||||
- crjne %r0,%r1,.Lend_cmp_one_char
|
||||
-
|
||||
+ lghi %r5,0 /* current_len = 0 bytes. */
|
||||
.Lloop:
|
||||
vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
|
||||
vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
|
||||
@@ -167,7 +160,6 @@ ENTRY(WCSNCMP_Z13)
|
||||
srl %r4,2 /* And convert it to character-index. */
|
||||
vlgvf %r0,%v16,0(%r4) /* Load character-values. */
|
||||
vlgvf %r1,%v17,0(%r4)
|
||||
-.Lend_cmp_one_char:
|
||||
cr %r0,%r1
|
||||
je .Lend_equal
|
||||
lghi %r2,1
|
248
SOURCES/glibc-RHEL-49489-2.patch
Normal file
248
SOURCES/glibc-RHEL-49489-2.patch
Normal file
@ -0,0 +1,248 @@
|
||||
commit 54252394c25ddf0062e288d4a6ab7a885f8ae009
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Jun 27 16:26:56 2024 +0200
|
||||
|
||||
Enhanced test coverage for strncmp, wcsncmp
|
||||
|
||||
Add string/test-strncmp-nonarray and
|
||||
wcsmbs/test-wcsncmp-nonarray.
|
||||
|
||||
This is the test that uncovered bug 31934. Test run time
|
||||
is more than one minute on a fairly current system, so turn
|
||||
these into xtests that do not run automatically.
|
||||
|
||||
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
|
||||
diff -Nrup a/string/Makefile b/string/Makefile
|
||||
--- a/string/Makefile 2024-09-03 11:42:30.396319962 -0400
|
||||
+++ b/string/Makefile 2024-09-03 11:52:17.707438963 -0400
|
||||
@@ -76,7 +76,10 @@ tests-unsupported += $(tests-translation
|
||||
endif
|
||||
|
||||
# This test allocates a lot of memory and can run for a long time.
|
||||
-xtests = tst-strcoll-overflow
|
||||
+xtests += tst-strcoll-overflow
|
||||
+
|
||||
+# This test runs for a long time.
|
||||
+xtests += test-strncmp-nonarray
|
||||
|
||||
# This test needs libdl.
|
||||
ifeq (yes,$(build-shared))
|
||||
diff -Nrup a/string/test-Xncmp-nonarray.c b/string/test-Xncmp-nonarray.c
|
||||
--- a/string/test-Xncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ b/string/test-Xncmp-nonarray.c 2024-09-03 11:52:17.707438963 -0400
|
||||
@@ -0,0 +1,183 @@
|
||||
+/* Test non-array inputs to string comparison functions.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This skeleton file is included from string/test-strncmp-nonarray.c and
|
||||
+ wcsmbs/test-wcsncmp-nonarray.c to test that reading of the arrays stops
|
||||
+ at the first null character.
|
||||
+
|
||||
+ TEST_IDENTIFIER must be the test function identifier. TEST_NAME is
|
||||
+ the same as a string.
|
||||
+
|
||||
+ CHAR must be defined as the character type. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/next_to_fault.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <sys/param.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* Much shorter than test-Xnlen-nonarray.c because of deeply nested loops. */
|
||||
+enum { buffer_length = 80 };
|
||||
+
|
||||
+/* The test buffer layout follows what is described test-Xnlen-nonarray.c,
|
||||
+ except that there two buffers, left and right. The variables
|
||||
+ a_count, zero_count, start_offset are all duplicated. */
|
||||
+
|
||||
+/* Return the maximum string length for a string that starts at
|
||||
+ start_offset. */
|
||||
+static int
|
||||
+string_length (int a_count, int start_offset)
|
||||
+{
|
||||
+ if (start_offset == buffer_length || start_offset >= a_count)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return a_count - start_offset;
|
||||
+}
|
||||
+
|
||||
+/* This is the valid maximum length argument computation for
|
||||
+ strnlen/wcsnlen. See text-Xnlen-nonarray.c. */
|
||||
+static int
|
||||
+maximum_length (int start_offset, int zero_count)
|
||||
+{
|
||||
+ if (start_offset == buffer_length)
|
||||
+ return 0;
|
||||
+ else if (zero_count > 0)
|
||||
+ /* Effectively unbounded, but we need to stop fairly low,
|
||||
+ otherwise testing takes too long. */
|
||||
+ return buffer_length + 32;
|
||||
+ else
|
||||
+ return buffer_length - start_offset;
|
||||
+}
|
||||
+
|
||||
+typedef __typeof (TEST_IDENTIFIER) *proto_t;
|
||||
+
|
||||
+#define TEST_MAIN
|
||||
+#include "test-string.h"
|
||||
+
|
||||
+IMPL (TEST_IDENTIFIER, 1)
|
||||
+
|
||||
+static int
|
||||
+test_main (void)
|
||||
+{
|
||||
+ TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length);
|
||||
+ test_init ();
|
||||
+
|
||||
+ struct support_next_to_fault left_ntf
|
||||
+ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
|
||||
+ CHAR *left_buffer = (CHAR *) left_ntf.buffer;
|
||||
+ struct support_next_to_fault right_ntf
|
||||
+ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
|
||||
+ CHAR *right_buffer = (CHAR *) right_ntf.buffer;
|
||||
+
|
||||
+ FOR_EACH_IMPL (impl, 0)
|
||||
+ {
|
||||
+ printf ("info: testing %s\n", impl->name);
|
||||
+ for (size_t i = 0; i < buffer_length; ++i)
|
||||
+ left_buffer[i] = 'A';
|
||||
+
|
||||
+ for (int left_zero_count = 0; left_zero_count <= buffer_length;
|
||||
+ ++left_zero_count)
|
||||
+ {
|
||||
+ if (left_zero_count > 0)
|
||||
+ left_buffer[buffer_length - left_zero_count] = 0;
|
||||
+ int left_a_count = buffer_length - left_zero_count;
|
||||
+ for (size_t i = 0; i < buffer_length; ++i)
|
||||
+ right_buffer[i] = 'A';
|
||||
+ for (int right_zero_count = 0; right_zero_count <= buffer_length;
|
||||
+ ++right_zero_count)
|
||||
+ {
|
||||
+ if (right_zero_count > 0)
|
||||
+ right_buffer[buffer_length - right_zero_count] = 0;
|
||||
+ int right_a_count = buffer_length - right_zero_count;
|
||||
+ for (int left_start_offset = 0;
|
||||
+ left_start_offset <= buffer_length;
|
||||
+ ++left_start_offset)
|
||||
+ {
|
||||
+ CHAR *left_start_pointer = left_buffer + left_start_offset;
|
||||
+ int left_maxlen
|
||||
+ = maximum_length (left_start_offset, left_zero_count);
|
||||
+ int left_length
|
||||
+ = string_length (left_a_count, left_start_offset);
|
||||
+ for (int right_start_offset = 0;
|
||||
+ right_start_offset <= buffer_length;
|
||||
+ ++right_start_offset)
|
||||
+ {
|
||||
+ CHAR *right_start_pointer
|
||||
+ = right_buffer + right_start_offset;
|
||||
+ int right_maxlen
|
||||
+ = maximum_length (right_start_offset, right_zero_count);
|
||||
+ int right_length
|
||||
+ = string_length (right_a_count, right_start_offset);
|
||||
+
|
||||
+ /* Maximum length is modelled after strnlen/wcsnlen,
|
||||
+ and must be valid for both pointer arguments at
|
||||
+ the same time. */
|
||||
+ int maxlen = MIN (left_maxlen, right_maxlen);
|
||||
+
|
||||
+ for (int length_argument = 0; length_argument <= maxlen;
|
||||
+ ++length_argument)
|
||||
+ {
|
||||
+ if (test_verbose)
|
||||
+ {
|
||||
+ printf ("left: zero_count=%d"
|
||||
+ " a_count=%d start_offset=%d\n",
|
||||
+ left_zero_count, left_a_count,
|
||||
+ left_start_offset);
|
||||
+ printf ("right: zero_count=%d"
|
||||
+ " a_count=%d start_offset=%d\n",
|
||||
+ right_zero_count, right_a_count,
|
||||
+ right_start_offset);
|
||||
+ printf ("length argument: %d\n",
|
||||
+ length_argument);
|
||||
+ }
|
||||
+
|
||||
+ /* Effective lengths bounded by length argument.
|
||||
+ The effective length determines the
|
||||
+ outcome of the comparison. */
|
||||
+ int left_effective
|
||||
+ = MIN (left_length, length_argument);
|
||||
+ int right_effective
|
||||
+ = MIN (right_length, length_argument);
|
||||
+ if (left_effective == right_effective)
|
||||
+ TEST_COMPARE (CALL (impl,
|
||||
+ left_start_pointer,
|
||||
+ right_start_pointer,
|
||||
+ length_argument), 0);
|
||||
+ else if (left_effective < right_effective)
|
||||
+ TEST_COMPARE (CALL (impl,
|
||||
+ left_start_pointer,
|
||||
+ right_start_pointer,
|
||||
+ length_argument) < 0, 1);
|
||||
+ else
|
||||
+ TEST_COMPARE (CALL (impl,
|
||||
+ left_start_pointer,
|
||||
+ right_start_pointer,
|
||||
+ length_argument) > 0, 1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff -Nrup a/string/test-strncmp-nonarray.c b/string/test-strncmp-nonarray.c
|
||||
--- a/string/test-strncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ b/string/test-strncmp-nonarray.c 2024-09-03 11:52:17.707438963 -0400
|
||||
@@ -0,0 +1,4 @@
|
||||
+#define TEST_IDENTIFIER strncmp
|
||||
+#define TEST_NAME "strncmp"
|
||||
+typedef char CHAR;
|
||||
+#include "test-Xncmp-nonarray.c"
|
||||
diff -Nrup a/wcsmbs/Makefile b/wcsmbs/Makefile
|
||||
--- a/wcsmbs/Makefile 2024-09-03 11:42:30.398319976 -0400
|
||||
+++ b/wcsmbs/Makefile 2024-09-03 11:53:44.806049806 -0400
|
||||
@@ -56,6 +56,10 @@ tests := tst-wcstof wcsmbs-tst1 tst-wcsn
|
||||
$(addprefix test-,$(strop-tests)) tst-mbstowcs \
|
||||
test-wcsdup
|
||||
|
||||
+# This test runs for a long time.
|
||||
+xtests += test-wcsncmp-nonarray
|
||||
+
|
||||
+
|
||||
include ../Rules
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
diff -Nrup a/wcsmbs/test-wcsncmp-nonarray.c b/wcsmbs/test-wcsncmp-nonarray.c
|
||||
--- a/wcsmbs/test-wcsncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ b/wcsmbs/test-wcsncmp-nonarray.c 2024-09-03 11:52:17.708438970 -0400
|
||||
@@ -0,0 +1,5 @@
|
||||
+#include <wchar.h>
|
||||
+#define TEST_IDENTIFIER wcsncmp
|
||||
+#define TEST_NAME "wcsncmp"
|
||||
+typedef wchar_t CHAR;
|
||||
+#include "../string/test-Xncmp-nonarray.c"
|
121
SOURCES/glibc-RHEL-50545-1.patch
Normal file
121
SOURCES/glibc-RHEL-50545-1.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 3bfdc4e2bceb601b90c81a9baa73c1904db58b2f Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@suse.de>
|
||||
Date: Tue, 28 Feb 2023 10:37:18 -0300
|
||||
Subject: [PATCH] support: use 64-bit time_t (bug 30111)
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
Ensure to use 64-bit time_t in the test infrastructure.
|
||||
---
|
||||
support/Makefile | 18 ++++++++++++++++++
|
||||
support/shell-container.c | 2 --
|
||||
support/support_can_chroot.c | 4 ++--
|
||||
support/support_copy_file.c | 2 +-
|
||||
support/support_descriptor_supports_holes.c | 2 +-
|
||||
support/test-container.c | 2 --
|
||||
6 files changed, 22 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index b29b7eb505..a304c5cdc0 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -239,6 +239,24 @@ CFLAGS-support_paths.c = \
|
||||
CFLAGS-timespec.c += -fexcess-precision=standard
|
||||
CFLAGS-timespec-time64.c += -fexcess-precision=standard
|
||||
|
||||
+# Ensure that general support files use 64-bit time_t
|
||||
+CFLAGS-delayed_exit.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-shell-container.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_can_chroot.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_copy_file.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_copy_file_range.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_descriptor_supports_holes.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_descriptors.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_process_state.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_stat_nanoseconds.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_subprocess.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-support_test_main.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-test-container.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+CFLAGS-xmkdirp.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+# This is required to get an mkstemp which can create large files on some
|
||||
+# 32-bit platforms.
|
||||
+CFLAGS-temp_file.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
|
||||
+
|
||||
ifeq (,$(CXX))
|
||||
LINKS_DSO_PROGRAM = links-dso-program-c
|
||||
else
|
||||
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||
index e9ac9b6d04..ffa3378b5e 100644
|
||||
--- a/support/shell-container.c
|
||||
+++ b/support/shell-container.c
|
||||
@@ -16,8 +16,6 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
diff --git a/support/support_can_chroot.c b/support/support_can_chroot.c
|
||||
index 7d9f91205d..7b4f491b53 100644
|
||||
--- a/support/support_can_chroot.c
|
||||
+++ b/support/support_can_chroot.c
|
||||
@@ -29,14 +29,14 @@ static void
|
||||
callback (void *closure)
|
||||
{
|
||||
int *result = closure;
|
||||
- struct stat64 before;
|
||||
+ struct stat before;
|
||||
xstat ("/dev", &before);
|
||||
if (chroot ("/dev") != 0)
|
||||
{
|
||||
*result = errno;
|
||||
return;
|
||||
}
|
||||
- struct stat64 after;
|
||||
+ struct stat after;
|
||||
xstat ("/", &after);
|
||||
TEST_VERIFY (before.st_dev == after.st_dev);
|
||||
TEST_VERIFY (before.st_ino == after.st_ino);
|
||||
diff --git a/support/support_copy_file.c b/support/support_copy_file.c
|
||||
index 50ff87b9f1..f3e0a2d1b7 100644
|
||||
--- a/support/support_copy_file.c
|
||||
+++ b/support/support_copy_file.c
|
||||
@@ -24,7 +24,7 @@
|
||||
void
|
||||
support_copy_file (const char *from, const char *to)
|
||||
{
|
||||
- struct stat64 st;
|
||||
+ struct stat st;
|
||||
xstat (from, &st);
|
||||
int fd_from = xopen (from, O_RDONLY, 0);
|
||||
mode_t mode = st.st_mode & 0777;
|
||||
diff --git a/support/support_descriptor_supports_holes.c b/support/support_descriptor_supports_holes.c
|
||||
index 7af5934808..91db216bf0 100644
|
||||
--- a/support/support_descriptor_supports_holes.c
|
||||
+++ b/support/support_descriptor_supports_holes.c
|
||||
@@ -40,7 +40,7 @@ support_descriptor_supports_holes (int fd)
|
||||
block_headroom = 32,
|
||||
};
|
||||
|
||||
- struct stat64 st;
|
||||
+ struct stat st;
|
||||
xfstat (fd, &st);
|
||||
if (!S_ISREG (st.st_mode))
|
||||
FAIL_EXIT1 ("descriptor %d does not refer to a regular file", fd);
|
||||
diff --git a/support/test-container.c b/support/test-container.c
|
||||
index f1a68b224a..e68f16eecf 100644
|
||||
--- a/support/test-container.c
|
||||
+++ b/support/test-container.c
|
||||
@@ -16,8 +16,6 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#define _FILE_OFFSET_BITS 64
|
||||
-
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
--
|
||||
2.43.5
|
||||
|
1337
SOURCES/glibc-RHEL-50545-10.patch
Normal file
1337
SOURCES/glibc-RHEL-50545-10.patch
Normal file
File diff suppressed because it is too large
Load Diff
501
SOURCES/glibc-RHEL-50545-11.patch
Normal file
501
SOURCES/glibc-RHEL-50545-11.patch
Normal file
@ -0,0 +1,501 @@
|
||||
From e3db0a699c639e97deddcb15939fd9c162801c77 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat, 21 Sep 2024 19:25:35 +0200
|
||||
Subject: [PATCH] misc: FUSE-based tests for mkstemp
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
The tests check that O_EXCL is used properly, that 0600 is used
|
||||
as the mode, that the characters used are as expected, and that
|
||||
the distribution of names generated is reasonably random.
|
||||
|
||||
The tests run very slowly on some kernel versions, so make them
|
||||
xtests.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
Conflicts
|
||||
misc/Makefile
|
||||
context
|
||||
---
|
||||
misc/Makefile | 6 +
|
||||
misc/tst-mkstemp-fuse-parallel.c | 219 +++++++++++++++++++++++++++++++
|
||||
misc/tst-mkstemp-fuse.c | 197 +++++++++++++++++++++++++++
|
||||
3 files changed, 422 insertions(+)
|
||||
create mode 100644 misc/tst-mkstemp-fuse-parallel.c
|
||||
create mode 100644 misc/tst-mkstemp-fuse.c
|
||||
|
||||
diff --git a/misc/Makefile b/misc/Makefile
|
||||
index 7b7f8351bf..1422c95317 100644
|
||||
--- a/misc/Makefile
|
||||
+++ b/misc/Makefile
|
||||
@@ -109,6 +109,12 @@ tests-static := tst-empty
|
||||
tests-internal += tst-fd_to_filename
|
||||
tests-static += tst-fd_to_filename
|
||||
|
||||
+# Tests with long run times.
|
||||
+xtests += \
|
||||
+ tst-mkstemp-fuse \
|
||||
+ tst-mkstemp-fuse-parallel \
|
||||
+ # xtests
|
||||
+
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += $(objpfx)tst-error1-mem.out \
|
||||
$(objpfx)tst-allocate_once-mem.out
|
||||
diff --git a/misc/tst-mkstemp-fuse-parallel.c b/misc/tst-mkstemp-fuse-parallel.c
|
||||
new file mode 100644
|
||||
index 0000000000..219f26cb3b
|
||||
--- /dev/null
|
||||
+++ b/misc/tst-mkstemp-fuse-parallel.c
|
||||
@@ -0,0 +1,246 @@
|
||||
+/* FUSE-based test for mkstemp. Parallel collision statistics.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <limits.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/fuse.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+/* The number of subprocesses that call mkstemp. */
|
||||
+static pid_t processes[4];
|
||||
+
|
||||
+/* Enough space to record the expected number of replies (62**3) for
|
||||
+ each process. */
|
||||
+enum { results_allocated = array_length (processes) * 62 * 62 * 62 };
|
||||
+
|
||||
+/* The thread will store the results there. */
|
||||
+static uint64_t *results;
|
||||
+
|
||||
+/* Currently used part of the results array. */
|
||||
+static size_t results_used;
|
||||
+
|
||||
+
|
||||
+/* Copied from upstream's string/strlcpy.c . */
|
||||
+static size_t
|
||||
+strlcpy (char *__restrict dest, const char *__restrict src, size_t size)
|
||||
+{
|
||||
+ size_t src_length = strlen (src);
|
||||
+
|
||||
+ if (__glibc_unlikely (src_length >= size))
|
||||
+ {
|
||||
+ if (size > 0)
|
||||
+ {
|
||||
+ /* Copy the leading portion of the string. The last
|
||||
+ character is subsequently overwritten with the NUL
|
||||
+ terminator, but the destination size is usually a
|
||||
+ multiple of a small power of two, so writing it twice
|
||||
+ should be more efficient than copying an odd number of
|
||||
+ bytes. */
|
||||
+ memcpy (dest, src, size);
|
||||
+ dest[size - 1] = '\0';
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ /* Copy the string and its terminating NUL character. */
|
||||
+ memcpy (dest, src, src_length + 1);
|
||||
+ return src_length;
|
||||
+}
|
||||
+
|
||||
+/* Fail with EEXIST (so that mkstemp tries again). Record observed
|
||||
+ names for later statistical analysis. */
|
||||
+static void
|
||||
+fuse_thread (struct support_fuse *f, void *closure)
|
||||
+{
|
||||
+ struct fuse_in_header *inh;
|
||||
+ while ((inh = support_fuse_next (f)) != NULL)
|
||||
+ {
|
||||
+ if (support_fuse_handle_mountpoint (f)
|
||||
+ || (inh->nodeid == 1 && support_fuse_handle_directory (f)))
|
||||
+ continue;
|
||||
+ if (inh->opcode != FUSE_LOOKUP || results_used >= results_allocated)
|
||||
+ {
|
||||
+ support_fuse_reply_error (f, EIO);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ char *name = support_fuse_cast (LOOKUP, inh);
|
||||
+ TEST_COMPARE_BLOB (name, 3, "new", 3);
|
||||
+ TEST_COMPARE (strlen (name), 9);
|
||||
+ /* Extract 8 bytes of the name: 'w', the X replacements, and the
|
||||
+ null terminator. Treat it as an uint64_t for easy sorting
|
||||
+ below. Endianess does not matter because the relative order
|
||||
+ of the entries is not important; sorting is only used to find
|
||||
+ duplicates. */
|
||||
+ TEST_VERIFY_EXIT (results_used < results_allocated);
|
||||
+ memcpy (&results[results_used], name + 2, 8);
|
||||
+ ++results_used;
|
||||
+ struct fuse_entry_out *out = support_fuse_prepare_entry (f, 2);
|
||||
+ out->attr.mode = S_IFREG | 0600;
|
||||
+ support_fuse_reply_prepared (f);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Used to sort the results array, to find duplicates. */
|
||||
+static int
|
||||
+results_sort (const void *a1, const void *b1)
|
||||
+{
|
||||
+ const uint64_t *a = a1;
|
||||
+ const uint64_t *b = b1;
|
||||
+ if (*a < *b)
|
||||
+ return -1;
|
||||
+ if (*a == *b)
|
||||
+ return 0;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* Number of occurrences of certain streak lengths. */
|
||||
+static size_t streak_lengths[6];
|
||||
+
|
||||
+/* Called for every encountered streak. */
|
||||
+static inline void
|
||||
+report_streak (uint64_t current, size_t length)
|
||||
+{
|
||||
+ if (length > 1)
|
||||
+ {
|
||||
+ printf ("info: name \"ne%.8s\" repeats: %zu\n",
|
||||
+ (char *) ¤t, length);
|
||||
+ TEST_VERIFY_EXIT (length < array_length (streak_lengths));
|
||||
+ }
|
||||
+ TEST_VERIFY_EXIT (length < array_length (streak_lengths));
|
||||
+ ++streak_lengths[length];
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ support_fuse_init ();
|
||||
+
|
||||
+ results = xmalloc (results_allocated * sizeof (*results));
|
||||
+
|
||||
+ struct shared
|
||||
+ {
|
||||
+ /* Used to synchronize the start of all subprocesses, to make it
|
||||
+ more likely to expose concurrency-related bugs. */
|
||||
+ pthread_barrier_t barrier1;
|
||||
+ pthread_barrier_t barrier2;
|
||||
+
|
||||
+ /* Filled in after fork. */
|
||||
+ char mountpoint[4096];
|
||||
+ };
|
||||
+
|
||||
+ /* Used to synchronize the start of all subprocesses, to make it
|
||||
+ more likely to expose concurrency-related bugs. */
|
||||
+ struct shared *pshared = support_shared_allocate (sizeof (*pshared));
|
||||
+ {
|
||||
+ pthread_barrierattr_t attr;
|
||||
+ xpthread_barrierattr_init (&attr);
|
||||
+ xpthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_SHARED);
|
||||
+ xpthread_barrierattr_destroy (&attr);
|
||||
+ xpthread_barrier_init (&pshared->barrier1, &attr,
|
||||
+ array_length (processes) + 1);
|
||||
+ xpthread_barrier_init (&pshared->barrier2, &attr,
|
||||
+ array_length (processes) + 1);
|
||||
+ xpthread_barrierattr_destroy (&attr);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < array_length (processes); ++i)
|
||||
+ {
|
||||
+ processes[i] = xfork ();
|
||||
+ if (processes[i] == 0)
|
||||
+ {
|
||||
+ /* Wait for mountpoint initialization. */
|
||||
+ xpthread_barrier_wait (&pshared->barrier1);
|
||||
+ char *path = xasprintf ("%s/newXXXXXX", pshared->mountpoint);
|
||||
+
|
||||
+ /* Park this process until all processes have started. */
|
||||
+ xpthread_barrier_wait (&pshared->barrier2);
|
||||
+ errno = 0;
|
||||
+ TEST_COMPARE (mkstemp (path), -1);
|
||||
+ TEST_COMPARE (errno, EEXIST);
|
||||
+ free (path);
|
||||
+ _exit (0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Do this after the forking, to minimize initialization inteference. */
|
||||
+ struct support_fuse *f = support_fuse_mount (fuse_thread, NULL);
|
||||
+ TEST_VERIFY (strlcpy (pshared->mountpoint, support_fuse_mountpoint (f),
|
||||
+ sizeof (pshared->mountpoint))
|
||||
+ < sizeof (pshared->mountpoint));
|
||||
+ xpthread_barrier_wait (&pshared->barrier1);
|
||||
+
|
||||
+ puts ("info: performing mkstemp calls");
|
||||
+ xpthread_barrier_wait (&pshared->barrier2);
|
||||
+
|
||||
+ for (int i = 0; i < array_length (processes); ++i)
|
||||
+ {
|
||||
+ int status;
|
||||
+ xwaitpid (processes[i], &status, 0);
|
||||
+ TEST_COMPARE (status, 0);
|
||||
+ }
|
||||
+
|
||||
+ support_fuse_unmount (f);
|
||||
+ xpthread_barrier_destroy (&pshared->barrier2);
|
||||
+ xpthread_barrier_destroy (&pshared->barrier1);
|
||||
+
|
||||
+ printf ("info: checking results (count %zu)\n", results_used);
|
||||
+ qsort (results, results_used, sizeof (*results), results_sort);
|
||||
+
|
||||
+ uint64_t current = -1;
|
||||
+ size_t streak = 0;
|
||||
+ for (size_t i = 0; i < results_used; ++i)
|
||||
+ if (results[i] == current)
|
||||
+ ++streak;
|
||||
+ else
|
||||
+ {
|
||||
+ report_streak (current, streak);
|
||||
+ current = results[i];
|
||||
+ streak = 1;
|
||||
+ }
|
||||
+ report_streak (current, streak);
|
||||
+
|
||||
+ puts ("info: repetition count distribution:");
|
||||
+ for (int i = 1; i < array_length (streak_lengths); ++i)
|
||||
+ printf (" length %d: %zu\n", i, streak_lengths[i]);
|
||||
+ /* Some arbitrary threshold, hopefully unlikely enough. In over
|
||||
+ 260,000 runs of a simulation of this test, at most 26 pairs were
|
||||
+ observed, and only one three-way collisions. */
|
||||
+ if (streak_lengths[2] > 30)
|
||||
+ FAIL ("unexpected repetition count 2: %zu", streak_lengths[2]);
|
||||
+ if (streak_lengths[3] > 2)
|
||||
+ FAIL ("unexpected repetition count 3: %zu", streak_lengths[3]);
|
||||
+ for (int i = 4; i < array_length (streak_lengths); ++i)
|
||||
+ if (streak_lengths[i] > 0)
|
||||
+ FAIL ("too many repeats of count %d: %zu", i, streak_lengths[i]);
|
||||
+
|
||||
+ free (results);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/misc/tst-mkstemp-fuse.c b/misc/tst-mkstemp-fuse.c
|
||||
new file mode 100644
|
||||
index 0000000000..5ac6a6872a
|
||||
--- /dev/null
|
||||
+++ b/misc/tst-mkstemp-fuse.c
|
||||
@@ -0,0 +1,197 @@
|
||||
+/* FUSE-based test for mkstemp.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/fuse.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+/* Set to true in do_test to cause the first FUSE_CREATE attempt to fail. */
|
||||
+static _Atomic bool simulate_creat_race;
|
||||
+
|
||||
+/* Basic tests with eventually successful creation. */
|
||||
+static void
|
||||
+fuse_thread_basic (struct support_fuse *f, void *closure)
|
||||
+{
|
||||
+ char *previous_name = NULL;
|
||||
+ int state = 0;
|
||||
+ struct fuse_in_header *inh;
|
||||
+ while ((inh = support_fuse_next (f)) != NULL)
|
||||
+ {
|
||||
+ if (support_fuse_handle_mountpoint (f)
|
||||
+ || (inh->nodeid == 1 && support_fuse_handle_directory (f)))
|
||||
+ continue;
|
||||
+
|
||||
+ switch (inh->opcode)
|
||||
+ {
|
||||
+ case FUSE_LOOKUP:
|
||||
+ /* File does not exist initially. */
|
||||
+ TEST_COMPARE (inh->nodeid, 1);
|
||||
+ if (simulate_creat_race)
|
||||
+ {
|
||||
+ if (state < 3)
|
||||
+ ++state;
|
||||
+ else
|
||||
+ FAIL ("invalid state: %d", state);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_COMPARE (state, 0);
|
||||
+ state = 3;
|
||||
+ }
|
||||
+ support_fuse_reply_error (f, ENOENT);
|
||||
+ break;
|
||||
+ case FUSE_CREATE:
|
||||
+ {
|
||||
+ TEST_COMPARE (inh->nodeid, 1);
|
||||
+ char *name;
|
||||
+ struct fuse_create_in *p
|
||||
+ = support_fuse_cast_name (CREATE, inh, &name);
|
||||
+ /* Name follows after struct fuse_create_in. */
|
||||
+ TEST_COMPARE (p->flags & O_ACCMODE, O_RDWR);
|
||||
+ TEST_VERIFY (p->flags & O_EXCL);
|
||||
+ TEST_VERIFY (p->flags & O_CREAT);
|
||||
+ TEST_COMPARE (p->mode & 07777, 0600);
|
||||
+ TEST_VERIFY (S_ISREG (p->mode));
|
||||
+ TEST_COMPARE_BLOB (name, 3, "new", 3);
|
||||
+
|
||||
+ if (state != 3 && simulate_creat_race)
|
||||
+ {
|
||||
+ ++state;
|
||||
+ support_fuse_reply_error (f, EEXIST);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (previous_name != NULL)
|
||||
+ /* This test has a very small probability of failure
|
||||
+ due to a harmless collision (one in 62**6 tests). */
|
||||
+ TEST_VERIFY (strcmp (name, previous_name) != 0);
|
||||
+ TEST_COMPARE (state, 3);
|
||||
+ ++state;
|
||||
+ struct fuse_entry_out *entry;
|
||||
+ struct fuse_open_out *open;
|
||||
+ support_fuse_prepare_create (f, 2, &entry, &open);
|
||||
+ entry->attr.mode = S_IFREG | 0600;
|
||||
+ support_fuse_reply_prepared (f);
|
||||
+ }
|
||||
+ free (previous_name);
|
||||
+ previous_name = xstrdup (name);
|
||||
+ }
|
||||
+ break;
|
||||
+ case FUSE_FLUSH:
|
||||
+ case FUSE_RELEASE:
|
||||
+ TEST_COMPARE (state, 4);
|
||||
+ TEST_COMPARE (inh->nodeid, 2);
|
||||
+ support_fuse_reply_empty (f);
|
||||
+ break;
|
||||
+ default:
|
||||
+ support_fuse_reply_error (f, EIO);
|
||||
+ }
|
||||
+ }
|
||||
+ free (previous_name);
|
||||
+}
|
||||
+
|
||||
+/* Reply that all files exist. */
|
||||
+static void
|
||||
+fuse_thread_eexist (struct support_fuse *f, void *closure)
|
||||
+{
|
||||
+ uint64_t counter = 0;
|
||||
+ struct fuse_in_header *inh;
|
||||
+ while ((inh = support_fuse_next (f)) != NULL)
|
||||
+ {
|
||||
+ if (support_fuse_handle_mountpoint (f)
|
||||
+ || (inh->nodeid == 1 && support_fuse_handle_directory (f)))
|
||||
+ continue;
|
||||
+
|
||||
+ switch (inh->opcode)
|
||||
+ {
|
||||
+ case FUSE_LOOKUP:
|
||||
+ ++counter;
|
||||
+ TEST_COMPARE (inh->nodeid, 1);
|
||||
+ char *name = support_fuse_cast (LOOKUP, inh);
|
||||
+ TEST_COMPARE_BLOB (name, 3, "new", 3);
|
||||
+ TEST_COMPARE (strlen (name), 9);
|
||||
+ for (int i = 3; i <= 8; ++i)
|
||||
+ {
|
||||
+ /* The glibc implementation uses letters and digits only. */
|
||||
+ char ch = name[i];
|
||||
+ TEST_VERIFY (('0' <= ch && ch <= '9')
|
||||
+ || ('a' <= ch && ch <= 'z')
|
||||
+ || ('A' <= ch && ch <= 'Z'));
|
||||
+ }
|
||||
+ struct fuse_entry_out out =
|
||||
+ {
|
||||
+ .nodeid = 2,
|
||||
+ .attr = {
|
||||
+ .mode = S_IFREG | 0600,
|
||||
+ .ino = 2,
|
||||
+ },
|
||||
+ };
|
||||
+ support_fuse_reply (f, &out, sizeof (out));
|
||||
+ break;
|
||||
+ default:
|
||||
+ support_fuse_reply_error (f, EIO);
|
||||
+ }
|
||||
+ }
|
||||
+ /* Verify that mkstemp has retried a lot. The current
|
||||
+ implementation tries 62 * 62 * 62 times until it goves up. */
|
||||
+ TEST_VERIFY (counter >= 200000);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ support_fuse_init ();
|
||||
+
|
||||
+ for (int do_simulate_creat_race = 0; do_simulate_creat_race < 2;
|
||||
+ ++do_simulate_creat_race)
|
||||
+ {
|
||||
+ simulate_creat_race = do_simulate_creat_race;
|
||||
+ printf ("info: testing with simulate_creat_race == %d\n",
|
||||
+ (int) simulate_creat_race);
|
||||
+ struct support_fuse *f = support_fuse_mount (fuse_thread_basic, NULL);
|
||||
+ char *path = xasprintf ("%s/newXXXXXX", support_fuse_mountpoint (f));
|
||||
+ int fd = mkstemp (path);
|
||||
+ TEST_VERIFY (fd > 2);
|
||||
+ xclose (fd);
|
||||
+ free (path);
|
||||
+ support_fuse_unmount (f);
|
||||
+ }
|
||||
+
|
||||
+ puts ("info: testing EEXIST failure case for mkstemp");
|
||||
+ {
|
||||
+ struct support_fuse *f = support_fuse_mount (fuse_thread_eexist, NULL);
|
||||
+ char *path = xasprintf ("%s/newXXXXXX", support_fuse_mountpoint (f));
|
||||
+ errno = 0;
|
||||
+ TEST_COMPARE (mkstemp (path), -1);
|
||||
+ TEST_COMPARE (errno, EEXIST);
|
||||
+ free (path);
|
||||
+ support_fuse_unmount (f);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
--
|
||||
2.43.5
|
||||
|
40
SOURCES/glibc-RHEL-50545-12.patch
Normal file
40
SOURCES/glibc-RHEL-50545-12.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 455c7622835d16c79e49fe75b8d3a1ae59a3d0ee Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat, 21 Sep 2024 19:25:35 +0200
|
||||
Subject: [PATCH] support: Fix memory leaks in FUSE tests
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
The internal read buffer (used by all FUSE tests) was not freed.
|
||||
The support/tst-support_fuse test missed a deallocation.
|
||||
---
|
||||
support/support_fuse.c | 1 +
|
||||
support/tst-support_fuse.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/support/support_fuse.c b/support/support_fuse.c
|
||||
index 135dbf1198..f6c063b549 100644
|
||||
--- a/support/support_fuse.c
|
||||
+++ b/support/support_fuse.c
|
||||
@@ -659,6 +659,7 @@ support_fuse_unmount (struct support_fuse *f)
|
||||
if (rmdir (f->mountpoint) != 0)
|
||||
FAIL ("FUSE: rmdir (\"%s\"): %m", f->mountpoint);
|
||||
xclose (f->fd);
|
||||
+ free (f->buffer_start);
|
||||
free (f->mountpoint);
|
||||
free (f->readdir_buffer);
|
||||
free (f);
|
||||
diff --git a/support/tst-support_fuse.c b/support/tst-support_fuse.c
|
||||
index c4075a6608..9ee637cbab 100644
|
||||
--- a/support/tst-support_fuse.c
|
||||
+++ b/support/tst-support_fuse.c
|
||||
@@ -331,6 +331,7 @@ do_test (void)
|
||||
{
|
||||
char *subdir_path = xasprintf ("%s/subdir", support_fuse_mountpoint (f));
|
||||
xmkdir (subdir_path, 01234);
|
||||
+ free (subdir_path);
|
||||
}
|
||||
|
||||
{
|
||||
--
|
||||
2.43.5
|
||||
|
32
SOURCES/glibc-RHEL-50545-13.patch
Normal file
32
SOURCES/glibc-RHEL-50545-13.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 366cce74d2aa2e5753d8787d415b745fd57fda04 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat, 21 Sep 2024 19:29:13 +0200
|
||||
Subject: [PATCH] support: Add valgrind instructions to <support/fuse.h>
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
Replacing an outdated comment (namespace setup is now handled by
|
||||
support_fuse_init).
|
||||
---
|
||||
support/fuse.h | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/support/fuse.h b/support/fuse.h
|
||||
index 4c365fbc0c..1c862bedbe 100644
|
||||
--- a/support/fuse.h
|
||||
+++ b/support/fuse.h
|
||||
@@ -16,8 +16,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-/* Before using this functionality, use support_enter_mount_namespace
|
||||
- to ensure that mounts do not impact the overall system. */
|
||||
+/* To run FUSE tests under valgrind, pass the
|
||||
+ --sim-hints=fuse-compatible option to valgrind. This option tells
|
||||
+ valgrind that additional system calls effectively call back into
|
||||
+ the current program. */
|
||||
|
||||
#ifndef SUPPORT_FUSE_H
|
||||
#define SUPPORT_FUSE_H
|
||||
--
|
||||
2.43.5
|
||||
|
24
SOURCES/glibc-RHEL-50545-14.patch
Normal file
24
SOURCES/glibc-RHEL-50545-14.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 3ef26b708725b528a1c69ab3eb523036c50b89d6 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 24 Sep 2024 13:05:48 +0200
|
||||
Subject: [PATCH] misc: Link tst-mkstemp-fuse-parallel with
|
||||
$(shared-thread-library)
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
The barrier functions require this on Hurd.
|
||||
---
|
||||
misc/Makefile | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/misc/Makefile b/misc/Makefile
|
||||
index 1422c95317..a932b1aab4 100644
|
||||
--- a/misc/Makefile
|
||||
+++ b/misc/Makefile
|
||||
@@ -178,3 +178,4 @@ $(objpfx)tst-select: $(librt)
|
||||
$(objpfx)tst-select-time64: $(librt)
|
||||
$(objpfx)tst-pselect: $(librt)
|
||||
$(objpfx)tst-pselect-time64: $(librt)
|
||||
+$(objpfx)tst-mkstemp-fuse-parallel: $(shared-thread-library)
|
||||
--
|
||||
2.43.5
|
||||
|
785
SOURCES/glibc-RHEL-50545-2.patch
Normal file
785
SOURCES/glibc-RHEL-50545-2.patch
Normal file
@ -0,0 +1,785 @@
|
||||
From 026a84a54d3b6c23b999b793e2a6f8ecd211e3b8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20B=C3=A9rat?= <fberat@redhat.com>
|
||||
Date: Thu, 1 Jun 2023 12:40:05 -0400
|
||||
Subject: [PATCH] tests: replace write by xwrite
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
Using write without cheks leads to warn unused result when __wur is
|
||||
enabled.
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
---
|
||||
dirent/tst-fdopendir.c | 4 +++-
|
||||
io/tst-faccessat.c | 3 ++-
|
||||
io/tst-fchmodat.c | 3 ++-
|
||||
io/tst-fchownat.c | 3 ++-
|
||||
io/tst-fstatat.c | 3 ++-
|
||||
io/tst-futimesat.c | 3 ++-
|
||||
io/tst-linkat.c | 3 ++-
|
||||
io/tst-openat.c | 3 ++-
|
||||
io/tst-renameat.c | 3 ++-
|
||||
io/tst-symlinkat.c | 3 ++-
|
||||
io/tst-unlinkat.c | 3 ++-
|
||||
libio/bug-ungetc.c | 4 +++-
|
||||
libio/bug-ungetc3.c | 4 +++-
|
||||
libio/bug-ungetc4.c | 4 +++-
|
||||
libio/bug-wfflush.c | 4 +++-
|
||||
libio/bug-wsetpos.c | 4 +++-
|
||||
nptl/tst-stackguard1.c | 4 +++-
|
||||
nptl/tst-tls3.c | 2 ++
|
||||
nptl/tst-tls3mod.c | 5 +++--
|
||||
rt/tst-cpuclock2.c | 4 +++-
|
||||
rt/tst-cputimer1.c | 4 +++-
|
||||
rt/tst-cputimer2.c | 4 +++-
|
||||
rt/tst-cputimer3.c | 4 +++-
|
||||
support/test-container.c | 8 ++++----
|
||||
sysdeps/pthread/tst-cond18.c | 4 +++-
|
||||
sysdeps/pthread/tst-flock1.c | 3 ++-
|
||||
sysdeps/pthread/tst-flock2.c | 3 ++-
|
||||
sysdeps/pthread/tst-key1.c | 11 ++++++-----
|
||||
sysdeps/pthread/tst-signal1.c | 3 ++-
|
||||
sysdeps/pthread/tst-signal2.c | 3 ++-
|
||||
sysdeps/pthread/tst-timer.c | 3 ++-
|
||||
time/tst-cpuclock1.c | 4 +++-
|
||||
32 files changed, 84 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/dirent/tst-fdopendir.c b/dirent/tst-fdopendir.c
|
||||
index 6321af1daa..2c9520574d 100644
|
||||
--- a/dirent/tst-fdopendir.c
|
||||
+++ b/dirent/tst-fdopendir.c
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
#ifndef O_NOATIME
|
||||
# define O_NOATIME 0
|
||||
#endif
|
||||
@@ -22,7 +24,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
close (fd);
|
||||
|
||||
struct stat64 st;
|
||||
diff --git a/io/tst-faccessat.c b/io/tst-faccessat.c
|
||||
index 7bdeed008c..b90954e318 100644
|
||||
--- a/io/tst-faccessat.c
|
||||
+++ b/io/tst-faccessat.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -96,7 +97,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
/* Before closing the file, try using this file descriptor to open
|
||||
diff --git a/io/tst-fchmodat.c b/io/tst-fchmodat.c
|
||||
index 7d4a8717ff..83003e2f21 100644
|
||||
--- a/io/tst-fchmodat.c
|
||||
+++ b/io/tst-fchmodat.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -98,7 +99,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-fchownat.c b/io/tst-fchownat.c
|
||||
index e8adf6229f..c0b87cda8f 100644
|
||||
--- a/io/tst-fchownat.c
|
||||
+++ b/io/tst-fchownat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -106,7 +107,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-fstatat.c b/io/tst-fstatat.c
|
||||
index 4766bb2e71..6a60024b63 100644
|
||||
--- a/io/tst-fstatat.c
|
||||
+++ b/io/tst-fstatat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-futimesat.c b/io/tst-futimesat.c
|
||||
index 3d41721f42..b7ef386e06 100644
|
||||
--- a/io/tst-futimesat.c
|
||||
+++ b/io/tst-futimesat.c
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <support/test-driver.h>
|
||||
#include <support/temp_file.h>
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
#ifndef struct_stat
|
||||
# define struct_stat struct stat64
|
||||
@@ -114,7 +115,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct_stat st1;
|
||||
diff --git a/io/tst-linkat.c b/io/tst-linkat.c
|
||||
index 97445b7954..6b22a01c88 100644
|
||||
--- a/io/tst-linkat.c
|
||||
+++ b/io/tst-linkat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-openat.c b/io/tst-openat.c
|
||||
index 741b8d0ad2..2ce89e3db1 100644
|
||||
--- a/io/tst-openat.c
|
||||
+++ b/io/tst-openat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
|
||||
/* Before closing the file, try using this file descriptor to open
|
||||
another file. This must fail. */
|
||||
diff --git a/io/tst-renameat.c b/io/tst-renameat.c
|
||||
index 435302b52b..0b9da5fd6d 100644
|
||||
--- a/io/tst-renameat.c
|
||||
+++ b/io/tst-renameat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-symlinkat.c b/io/tst-symlinkat.c
|
||||
index 214a8e348e..4a34994df7 100644
|
||||
--- a/io/tst-symlinkat.c
|
||||
+++ b/io/tst-symlinkat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
diff --git a/io/tst-unlinkat.c b/io/tst-unlinkat.c
|
||||
index e21d56f9f7..21a2dbaf57 100644
|
||||
--- a/io/tst-unlinkat.c
|
||||
+++ b/io/tst-unlinkat.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
@@ -94,7 +95,7 @@ do_test (void)
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
- write (fd, "hello", 5);
|
||||
+ xwrite (fd, "hello", 5);
|
||||
close (fd);
|
||||
puts ("file created");
|
||||
|
||||
diff --git a/libio/bug-ungetc.c b/libio/bug-ungetc.c
|
||||
index 51940b68f5..4ea2d14ed6 100644
|
||||
--- a/libio/bug-ungetc.c
|
||||
+++ b/libio/bug-ungetc.c
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static void do_prepare (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
static int do_test (void);
|
||||
@@ -20,7 +22,7 @@ do_prepare (void)
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
- write (fd, pattern, sizeof (pattern));
|
||||
+ xwrite (fd, pattern, sizeof (pattern));
|
||||
close (fd);
|
||||
}
|
||||
|
||||
diff --git a/libio/bug-ungetc3.c b/libio/bug-ungetc3.c
|
||||
index 0c83c1161e..6100d7a936 100644
|
||||
--- a/libio/bug-ungetc3.c
|
||||
+++ b/libio/bug-ungetc3.c
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static void do_prepare (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
static int do_test (void);
|
||||
@@ -20,7 +22,7 @@ do_prepare (void)
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
- write (fd, pattern, sizeof (pattern));
|
||||
+ xwrite (fd, pattern, sizeof (pattern));
|
||||
close (fd);
|
||||
}
|
||||
|
||||
diff --git a/libio/bug-ungetc4.c b/libio/bug-ungetc4.c
|
||||
index 0bd02a570d..8a05def686 100644
|
||||
--- a/libio/bug-ungetc4.c
|
||||
+++ b/libio/bug-ungetc4.c
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static void do_prepare (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
static int do_test (void);
|
||||
@@ -37,7 +39,7 @@ do_prepare (void)
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
- write (fd, pattern, sizeof (pattern) - 1);
|
||||
+ xwrite (fd, pattern, sizeof (pattern) - 1);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
diff --git a/libio/bug-wfflush.c b/libio/bug-wfflush.c
|
||||
index a8fd61e997..d1b9d8e9de 100644
|
||||
--- a/libio/bug-wfflush.c
|
||||
+++ b/libio/bug-wfflush.c
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static void do_prepare (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
static int do_test (void);
|
||||
@@ -20,7 +22,7 @@ do_prepare (void)
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
- write (fd, "1!", 2);
|
||||
+ xwrite (fd, "1!", 2);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
diff --git a/libio/bug-wsetpos.c b/libio/bug-wsetpos.c
|
||||
index ccb22a4b62..0fc373ba49 100644
|
||||
--- a/libio/bug-wsetpos.c
|
||||
+++ b/libio/bug-wsetpos.c
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static void do_prepare (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
static int do_test (void);
|
||||
@@ -22,7 +24,7 @@ do_prepare (void)
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
- write (fd, pattern, sizeof (pattern));
|
||||
+ xwrite (fd, pattern, sizeof (pattern));
|
||||
close (fd);
|
||||
}
|
||||
|
||||
diff --git a/nptl/tst-stackguard1.c b/nptl/tst-stackguard1.c
|
||||
index b9cf6844de..4ac57157e9 100644
|
||||
--- a/nptl/tst-stackguard1.c
|
||||
+++ b/nptl/tst-stackguard1.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <tls.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static const char *command;
|
||||
static bool child;
|
||||
static uintptr_t stack_chk_guard_copy;
|
||||
@@ -97,7 +99,7 @@ do_test (void)
|
||||
else if (ret != NULL)
|
||||
return 1;
|
||||
|
||||
- write (2, &stack_chk_guard_copy, sizeof (stack_chk_guard_copy));
|
||||
+ xwrite (2, &stack_chk_guard_copy, sizeof (stack_chk_guard_copy));
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/nptl/tst-tls3.c b/nptl/tst-tls3.c
|
||||
index b1a40c624a..33d94c8cc5 100644
|
||||
--- a/nptl/tst-tls3.c
|
||||
+++ b/nptl/tst-tls3.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <unistd.h>
|
||||
#include <pthreaddef.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
#define THE_SIG SIGUSR1
|
||||
|
||||
/* The stack size can be overriden. With a sufficiently large stack
|
||||
diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c
|
||||
index c6e8910b1e..345a48e1c7 100644
|
||||
--- a/nptl/tst-tls3mod.c
|
||||
+++ b/nptl/tst-tls3mod.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <pthreaddef.h>
|
||||
#include <descr.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
extern pthread_barrier_t b;
|
||||
|
||||
@@ -44,7 +45,7 @@ handler (int sig)
|
||||
{
|
||||
if (sig != THE_SIG)
|
||||
{
|
||||
- write (STDOUT_FILENO, "wrong signal\n", 13);
|
||||
+ xwrite (STDOUT_FILENO, "wrong signal\n", 13);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ handler (int sig)
|
||||
|
||||
if (sem_post (&s) != 0)
|
||||
{
|
||||
- write (STDOUT_FILENO, "sem_post failed\n", 16);
|
||||
+ xwrite (STDOUT_FILENO, "sem_post failed\n", 16);
|
||||
_exit (1);
|
||||
}
|
||||
}
|
||||
diff --git a/rt/tst-cpuclock2.c b/rt/tst-cpuclock2.c
|
||||
index e4584d8791..8afd34ed9c 100644
|
||||
--- a/rt/tst-cpuclock2.c
|
||||
+++ b/rt/tst-cpuclock2.c
|
||||
@@ -37,6 +37,8 @@ do_test ()
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
/* This function is intended to rack up both user and system time. */
|
||||
@@ -55,7 +57,7 @@ chew_cpu (void *arg)
|
||||
for (int i = 0; i < 100; ++i)
|
||||
for (size_t j = 0; j < sizeof buf; ++j)
|
||||
buf[j] = 0xbb;
|
||||
- write (nullfd, (char *) buf, sizeof buf);
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
close (nullfd);
|
||||
}
|
||||
|
||||
diff --git a/rt/tst-cputimer1.c b/rt/tst-cputimer1.c
|
||||
index 8f5dd76cf2..18d8b195a2 100644
|
||||
--- a/rt/tst-cputimer1.c
|
||||
+++ b/rt/tst-cputimer1.c
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
#define TEST_CLOCK CLOCK_PROCESS_CPUTIME_ID
|
||||
#define TEST_CLOCK_MISSING(clock) \
|
||||
(setup_test () ? "process CPU clock timer support" : NULL)
|
||||
@@ -29,7 +31,7 @@ chew_cpu (void *arg)
|
||||
for (int i = 0; i < 100; ++i)
|
||||
for (size_t j = 0; j < sizeof buf; ++j)
|
||||
buf[j] = 0xbb;
|
||||
- write (nullfd, (char *) buf, sizeof buf);
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
close (nullfd);
|
||||
}
|
||||
|
||||
diff --git a/rt/tst-cputimer2.c b/rt/tst-cputimer2.c
|
||||
index 397d7998c0..a5700d4bac 100644
|
||||
--- a/rt/tst-cputimer2.c
|
||||
+++ b/rt/tst-cputimer2.c
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static clockid_t worker_thread_clock;
|
||||
|
||||
#define TEST_CLOCK worker_thread_clock
|
||||
@@ -32,7 +34,7 @@ chew_cpu (void *arg)
|
||||
for (int i = 0; i < 100; ++i)
|
||||
for (size_t j = 0; j < sizeof buf; ++j)
|
||||
buf[j] = 0xbb;
|
||||
- write (nullfd, (char *) buf, sizeof buf);
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
close (nullfd);
|
||||
}
|
||||
|
||||
diff --git a/rt/tst-cputimer3.c b/rt/tst-cputimer3.c
|
||||
index 056766a377..786de93a02 100644
|
||||
--- a/rt/tst-cputimer3.c
|
||||
+++ b/rt/tst-cputimer3.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
static clockid_t child_clock;
|
||||
|
||||
#define TEST_CLOCK child_clock
|
||||
@@ -33,7 +35,7 @@ chew_cpu (void)
|
||||
for (int i = 0; i < 100; ++i)
|
||||
for (size_t j = 0; j < sizeof buf; ++j)
|
||||
buf[j] = 0xbb;
|
||||
- write (nullfd, (char *) buf, sizeof buf);
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
close (nullfd);
|
||||
if (getppid () == 1)
|
||||
_exit (2);
|
||||
diff --git a/support/test-container.c b/support/test-container.c
|
||||
index e68f16eecf..d4ca41fe7c 100644
|
||||
--- a/support/test-container.c
|
||||
+++ b/support/test-container.c
|
||||
@@ -1177,7 +1177,7 @@ main (int argc, char **argv)
|
||||
int status;
|
||||
|
||||
/* Send the child's "outside" pid to it. */
|
||||
- write (pipes[1], &child, sizeof(child));
|
||||
+ xwrite (pipes[1], &child, sizeof(child));
|
||||
close (pipes[0]);
|
||||
close (pipes[1]);
|
||||
|
||||
@@ -1246,7 +1246,7 @@ main (int argc, char **argv)
|
||||
|
||||
sprintf (tmp, "%lld %lld 1\n",
|
||||
(long long) (be_su ? 0 : original_uid), (long long) original_uid);
|
||||
- write (UMAP, tmp, strlen (tmp));
|
||||
+ xwrite (UMAP, tmp, strlen (tmp));
|
||||
xclose (UMAP);
|
||||
|
||||
/* We must disable setgroups () before we can map our groups, else we
|
||||
@@ -1255,7 +1255,7 @@ main (int argc, char **argv)
|
||||
if (GMAP >= 0)
|
||||
{
|
||||
/* We support kernels old enough to not have this. */
|
||||
- write (GMAP, "deny\n", 5);
|
||||
+ xwrite (GMAP, "deny\n", 5);
|
||||
xclose (GMAP);
|
||||
}
|
||||
|
||||
@@ -1267,7 +1267,7 @@ main (int argc, char **argv)
|
||||
|
||||
sprintf (tmp, "%lld %lld 1\n",
|
||||
(long long) (be_su ? 0 : original_gid), (long long) original_gid);
|
||||
- write (GMAP, tmp, strlen (tmp));
|
||||
+ xwrite (GMAP, tmp, strlen (tmp));
|
||||
xclose (GMAP);
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/pthread/tst-cond18.c b/sysdeps/pthread/tst-cond18.c
|
||||
index edac4fa4ff..ffae356c04 100644
|
||||
--- a/sysdeps/pthread/tst-cond18.c
|
||||
+++ b/sysdeps/pthread/tst-cond18.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
bool exiting;
|
||||
@@ -41,7 +43,7 @@ tf (void *id)
|
||||
while (!exiting)
|
||||
{
|
||||
if ((spins++ % 1000) == 0)
|
||||
- write (fd, ".", 1);
|
||||
+ xwrite (fd, ".", 1);
|
||||
pthread_mutex_unlock (&lock);
|
||||
|
||||
pthread_mutex_lock (&lock);
|
||||
diff --git a/sysdeps/pthread/tst-flock1.c b/sysdeps/pthread/tst-flock1.c
|
||||
index 7eef9070ab..9de148afd3 100644
|
||||
--- a/sysdeps/pthread/tst-flock1.c
|
||||
+++ b/sysdeps/pthread/tst-flock1.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -57,7 +58,7 @@ do_test (void)
|
||||
|
||||
unlink (tmp);
|
||||
|
||||
- write (fd, "foobar xyzzy", 12);
|
||||
+ xwrite (fd, "foobar xyzzy", 12);
|
||||
|
||||
if (flock (fd, LOCK_EX | LOCK_NB) != 0)
|
||||
{
|
||||
diff --git a/sysdeps/pthread/tst-flock2.c b/sysdeps/pthread/tst-flock2.c
|
||||
index 8762e93b52..952b79e5db 100644
|
||||
--- a/sysdeps/pthread/tst-flock2.c
|
||||
+++ b/sysdeps/pthread/tst-flock2.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -71,7 +72,7 @@ do_test (void)
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 20; ++i)
|
||||
- write (fd, "foobar xyzzy", 12);
|
||||
+ xwrite (fd, "foobar xyzzy", 12);
|
||||
|
||||
pthread_barrier_t *b;
|
||||
b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
|
||||
diff --git a/sysdeps/pthread/tst-key1.c b/sysdeps/pthread/tst-key1.c
|
||||
index 933edafef8..60245c4e47 100644
|
||||
--- a/sysdeps/pthread/tst-key1.c
|
||||
+++ b/sysdeps/pthread/tst-key1.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static int do_test (void);
|
||||
|
||||
@@ -52,7 +53,7 @@ do_test (void)
|
||||
|
||||
if (pthread_setspecific (keys[i], (const void *) (i + 100l)) != 0)
|
||||
{
|
||||
- write (2, "setspecific failed\n", 19);
|
||||
+ xwrite (2, "setspecific failed\n", 19);
|
||||
_exit (1);
|
||||
}
|
||||
}
|
||||
@@ -61,13 +62,13 @@ do_test (void)
|
||||
{
|
||||
if (pthread_getspecific (keys[i]) != (void *) (i + 100l))
|
||||
{
|
||||
- write (2, "getspecific failed\n", 19);
|
||||
+ xwrite (2, "getspecific failed\n", 19);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
if (pthread_key_delete (keys[i]) != 0)
|
||||
{
|
||||
- write (2, "key_delete failed\n", 18);
|
||||
+ xwrite (2, "key_delete failed\n", 18);
|
||||
_exit (1);
|
||||
}
|
||||
}
|
||||
@@ -75,13 +76,13 @@ do_test (void)
|
||||
/* Now it must be once again possible to allocate keys. */
|
||||
if (pthread_key_create (&keys[0], NULL) != 0)
|
||||
{
|
||||
- write (2, "2nd key_create failed\n", 22);
|
||||
+ xwrite (2, "2nd key_create failed\n", 22);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
if (pthread_key_delete (keys[0]) != 0)
|
||||
{
|
||||
- write (2, "2nd key_delete failed\n", 22);
|
||||
+ xwrite (2, "2nd key_delete failed\n", 22);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/pthread/tst-signal1.c b/sysdeps/pthread/tst-signal1.c
|
||||
index d1073e8459..d1082027ca 100644
|
||||
--- a/sysdeps/pthread/tst-signal1.c
|
||||
+++ b/sysdeps/pthread/tst-signal1.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static sigset_t ss;
|
||||
static pthread_barrier_t *b;
|
||||
@@ -106,7 +107,7 @@ do_test (void)
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 20; ++i)
|
||||
- write (fd, "foobar xyzzy", 12);
|
||||
+ xwrite (fd, "foobar xyzzy", 12);
|
||||
|
||||
b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
diff --git a/sysdeps/pthread/tst-signal2.c b/sysdeps/pthread/tst-signal2.c
|
||||
index dfe7d9f64a..15b7747877 100644
|
||||
--- a/sysdeps/pthread/tst-signal2.c
|
||||
+++ b/sysdeps/pthread/tst-signal2.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static sigset_t ss;
|
||||
static pthread_barrier_t *b;
|
||||
@@ -112,7 +113,7 @@ do_test (void)
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 20; ++i)
|
||||
- write (fd, "foobar xyzzy", 12);
|
||||
+ xwrite (fd, "foobar xyzzy", 12);
|
||||
|
||||
b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
diff --git a/sysdeps/pthread/tst-timer.c b/sysdeps/pthread/tst-timer.c
|
||||
index 47472ab8e1..4cfe0b67dc 100644
|
||||
--- a/sysdeps/pthread/tst-timer.c
|
||||
+++ b/sysdeps/pthread/tst-timer.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
|
||||
static void
|
||||
notify_func1 (union sigval sigval)
|
||||
@@ -45,7 +46,7 @@ signal_func (int sig)
|
||||
{
|
||||
static const char text[] = "signal_func\n";
|
||||
signal (sig, signal_func);
|
||||
- write (STDOUT_FILENO, text, sizeof text - 1);
|
||||
+ xwrite (STDOUT_FILENO, text, sizeof text - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/time/tst-cpuclock1.c b/time/tst-cpuclock1.c
|
||||
index 6f2e70a58a..6a793e06df 100644
|
||||
--- a/time/tst-cpuclock1.c
|
||||
+++ b/time/tst-cpuclock1.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
/* This function is intended to rack up both user and system time. */
|
||||
static void
|
||||
chew_cpu (void)
|
||||
@@ -41,7 +43,7 @@ chew_cpu (void)
|
||||
for (int i = 0; i < 100; ++i)
|
||||
for (size_t j = 0; j < sizeof buf; ++j)
|
||||
buf[j] = 0xbb;
|
||||
- write (nullfd, (char *) buf, sizeof buf);
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
close (nullfd);
|
||||
if (getppid () == 1)
|
||||
_exit (2);
|
||||
--
|
||||
2.43.5
|
||||
|
30
SOURCES/glibc-RHEL-50545-3.patch
Normal file
30
SOURCES/glibc-RHEL-50545-3.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 34bb581e7713589d38c797c214f4c6bf2b14b702 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri, 16 Aug 2024 16:05:19 +0200
|
||||
Subject: [PATCH] support: Include <string.h> for strcmp in
|
||||
support_format_addrinfo.c
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
This is currently implied by the internal headers, but it makes
|
||||
sense not to rely on this.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
---
|
||||
support/support_format_addrinfo.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/support/support_format_addrinfo.c b/support/support_format_addrinfo.c
|
||||
index cbc72910a9..77f4db345c 100644
|
||||
--- a/support/support_format_addrinfo.c
|
||||
+++ b/support/support_format_addrinfo.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <support/support.h>
|
||||
#include <support/xmemstream.h>
|
||||
|
||||
--
|
||||
2.43.5
|
||||
|
91
SOURCES/glibc-RHEL-50545-4.patch
Normal file
91
SOURCES/glibc-RHEL-50545-4.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 921690512946d73bf66a8c495baff31316e4489f Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri, 16 Aug 2024 16:05:19 +0200
|
||||
Subject: [PATCH] support: Add the xstatx function
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
Conflict:
|
||||
support/Makefile
|
||||
context
|
||||
---
|
||||
support/Makefile | 1 +
|
||||
support/xstatx.c | 32 ++++++++++++++++++++++++++++++++
|
||||
support/xunistd.h | 2 ++
|
||||
3 files changed, 35 insertions(+)
|
||||
create mode 100644 support/xstatx.c
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index aa57207bdc..5b1c96a49e 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -200,6 +200,7 @@ libsupport-routines = \
|
||||
xsignal \
|
||||
xsigstack \
|
||||
xsocket \
|
||||
+ xstatx \
|
||||
xposix_spawn \
|
||||
xposix_spawn_file_actions_addclose \
|
||||
xposix_spawn_file_actions_adddup2 \
|
||||
diff --git a/support/xstatx.c b/support/xstatx.c
|
||||
new file mode 100644
|
||||
index 0000000000..621f2440f8
|
||||
--- /dev/null
|
||||
+++ b/support/xstatx.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* Error-checking wrapper for statx.
|
||||
+ Copyright (C) 2024 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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+#include <fcntl.h>
|
||||
+#include <support/check.h>
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+void
|
||||
+xstatx (int fd, const char *path, int flags, unsigned int mask,
|
||||
+ struct statx *stx)
|
||||
+{
|
||||
+ if (statx (fd, path, flags, mask, stx) != 0)
|
||||
+ FAIL_EXIT1 ("statx (AT_FDCWD, \"%s\", 0x%x, 0x%x): %m",
|
||||
+ path, (unsigned int) flags, mask);
|
||||
+}
|
||||
diff --git a/support/xunistd.h b/support/xunistd.h
|
||||
index 13be9a46a3..cc74c4fad0 100644
|
||||
--- a/support/xunistd.h
|
||||
+++ b/support/xunistd.h
|
||||
@@ -30,6 +30,7 @@
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct stat64;
|
||||
+struct statx;
|
||||
|
||||
pid_t xfork (void);
|
||||
pid_t xwaitpid (pid_t, int *status, int flags);
|
||||
@@ -51,6 +52,7 @@ void __REDIRECT (xstat, (const char *path, struct stat *), xstat_time64);
|
||||
void __REDIRECT (xlstat, (const char *path, struct stat *), xlstat_time64);
|
||||
void __REDIRECT (xfstat, (int fd, struct stat *), xfstat_time64);
|
||||
#endif
|
||||
+void xstatx (int, const char *, int, unsigned int, struct statx *);
|
||||
void xmkdir (const char *path, mode_t);
|
||||
void xchroot (const char *path);
|
||||
void xunlink (const char *path);
|
||||
--
|
||||
2.43.5
|
||||
|
410
SOURCES/glibc-RHEL-50545-5.patch
Normal file
410
SOURCES/glibc-RHEL-50545-5.patch
Normal file
@ -0,0 +1,410 @@
|
||||
From bf2927484152e12996af60ea439cf94b66fcd81d Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri, 16 Aug 2024 16:05:20 +0200
|
||||
Subject: [PATCH] io: Use struct statx and xstatx in tests
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
This avoids the need to define struct_statx to an appropriate
|
||||
struct stat type variant because struct statx does not change
|
||||
based on time/file offset flags.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
---
|
||||
io/tst-futimens-time64.c | 1 -
|
||||
io/tst-futimens.c | 13 +++++--------
|
||||
io/tst-futimes-time64.c | 1 -
|
||||
io/tst-futimes.c | 13 +++++--------
|
||||
io/tst-futimesat-time64.c | 3 ---
|
||||
io/tst-futimesat.c | 30 ++++++++----------------------
|
||||
io/tst-lutimes-time64.c | 1 -
|
||||
io/tst-lutimes.c | 26 ++++++++++++--------------
|
||||
io/tst-utime-time64.c | 1 -
|
||||
io/tst-utime.c | 13 +++++--------
|
||||
io/tst-utimensat-time64.c | 1 -
|
||||
io/tst-utimensat.c | 35 +++++++++++++++++------------------
|
||||
io/tst-utimes-time64.c | 1 -
|
||||
io/tst-utimes.c | 13 +++++--------
|
||||
14 files changed, 57 insertions(+), 95 deletions(-)
|
||||
|
||||
diff --git a/io/tst-futimens-time64.c b/io/tst-futimens-time64.c
|
||||
index 88fcb38489..71204a6166 100644
|
||||
--- a/io/tst-futimens-time64.c
|
||||
+++ b/io/tst-futimens-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-futimens.c"
|
||||
diff --git a/io/tst-futimens.c b/io/tst-futimens.c
|
||||
index 6204befedd..075ca42b93 100644
|
||||
--- a/io/tst-futimens.c
|
||||
+++ b/io/tst-futimens.c
|
||||
@@ -18,26 +18,23 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_futimens_helper (const char *file, int fd, const struct timespec *ts)
|
||||
{
|
||||
int result = futimens (fd, ts);
|
||||
TEST_VERIFY_EXIT (result == 0);
|
||||
|
||||
- struct_stat st;
|
||||
- xfstat (fd, &st);
|
||||
+ struct statx st;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st);
|
||||
|
||||
/* Check if seconds for atime match */
|
||||
- TEST_COMPARE (st.st_atime, ts[0].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_atime.tv_sec, ts[0].tv_sec);
|
||||
|
||||
/* Check if seconds for mtime match */
|
||||
- TEST_COMPARE (st.st_mtime, ts[1].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_mtime.tv_sec, ts[1].tv_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/io/tst-futimes-time64.c b/io/tst-futimes-time64.c
|
||||
index d489c265d1..eeb4bed7c4 100644
|
||||
--- a/io/tst-futimes-time64.c
|
||||
+++ b/io/tst-futimes-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-futimes.c"
|
||||
diff --git a/io/tst-futimes.c b/io/tst-futimes.c
|
||||
index d21acf6a24..612fe460cf 100644
|
||||
--- a/io/tst-futimes.c
|
||||
+++ b/io/tst-futimes.c
|
||||
@@ -18,27 +18,24 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_futimens_helper (const char *file, int fd, const struct timeval *tv)
|
||||
{
|
||||
int r = futimes (fd, tv);
|
||||
TEST_VERIFY_EXIT (r == 0);
|
||||
|
||||
- struct_stat st;
|
||||
- xfstat (fd, &st);
|
||||
+ struct statx st;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st);
|
||||
|
||||
/* Check if seconds for atime match */
|
||||
- TEST_COMPARE (st.st_atime, tv[0].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_atime.tv_sec, tv[0].tv_sec);
|
||||
|
||||
/* Check if seconds for mtime match */
|
||||
- TEST_COMPARE (st.st_mtime, tv[1].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_mtime.tv_sec, tv[1].tv_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/io/tst-futimesat-time64.c b/io/tst-futimesat-time64.c
|
||||
index f6c0500eef..1585317579 100644
|
||||
--- a/io/tst-futimesat-time64.c
|
||||
+++ b/io/tst-futimesat-time64.c
|
||||
@@ -1,4 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
-#define fstat fstat
|
||||
-#define fstatat fstatat
|
||||
#include "io/tst-futimesat.c"
|
||||
diff --git a/io/tst-futimesat.c b/io/tst-futimesat.c
|
||||
index 67a8551beb..feae4e7aa7 100644
|
||||
--- a/io/tst-futimesat.c
|
||||
+++ b/io/tst-futimesat.c
|
||||
@@ -30,12 +30,6 @@
|
||||
#include <support/temp_file.h>
|
||||
#include <support/xunistd.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-# define fstat fstat64
|
||||
-# define fstatat fstatat64
|
||||
-#endif
|
||||
-
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
@@ -118,19 +112,15 @@ do_test (void)
|
||||
xwrite (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
- struct_stat st1;
|
||||
- if (fstat (fd, &st1) != 0)
|
||||
- {
|
||||
- puts ("fstat64 failed");
|
||||
- return 1;
|
||||
- }
|
||||
+ struct statx st1;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st1);
|
||||
|
||||
close (fd);
|
||||
|
||||
struct timeval tv[2];
|
||||
- tv[0].tv_sec = st1.st_atime + 1;
|
||||
+ tv[0].tv_sec = st1.stx_atime.tv_sec + 1;
|
||||
tv[0].tv_usec = 0;
|
||||
- tv[1].tv_sec = st1.st_mtime + 1;
|
||||
+ tv[1].tv_sec = st1.stx_mtime.tv_sec + 1;
|
||||
tv[1].tv_usec = 0;
|
||||
if (futimesat (dir_fd, "some-file", tv) != 0)
|
||||
{
|
||||
@@ -138,16 +128,12 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- struct_stat st2;
|
||||
- if (fstatat (dir_fd, "some-file", &st2, 0) != 0)
|
||||
- {
|
||||
- puts ("fstatat64 failed");
|
||||
- return 1;
|
||||
- }
|
||||
+ struct statx st2;
|
||||
+ xstatx (dir_fd, "some-file", 0, STATX_BASIC_STATS, &st2);
|
||||
|
||||
- if (st2.st_mtime != tv[1].tv_sec
|
||||
+ if (st2.stx_mtime.tv_sec != tv[1].tv_sec
|
||||
#ifdef _STATBUF_ST_NSEC
|
||||
- || st2.st_mtim.tv_nsec != 0
|
||||
+ || st2.stx_mtime.tv_nsec != 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
diff --git a/io/tst-lutimes-time64.c b/io/tst-lutimes-time64.c
|
||||
index 06caec0a91..c5bea965da 100644
|
||||
--- a/io/tst-lutimes-time64.c
|
||||
+++ b/io/tst-lutimes-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-lutimes.c"
|
||||
diff --git a/io/tst-lutimes.c b/io/tst-lutimes.c
|
||||
index edef5ab90e..78bcc58291 100644
|
||||
--- a/io/tst-lutimes.c
|
||||
+++ b/io/tst-lutimes.c
|
||||
@@ -18,34 +18,32 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_lutimes_helper (const char *testfile, int fd, const char *testlink,
|
||||
const struct timeval *tv)
|
||||
{
|
||||
- struct_stat stfile_orig;
|
||||
- xlstat (testfile, &stfile_orig);
|
||||
+ struct statx stfile_orig;
|
||||
+ xstatx (AT_FDCWD, testfile, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS,
|
||||
+ &stfile_orig);
|
||||
|
||||
TEST_VERIFY_EXIT (lutimes (testlink, tv) == 0);
|
||||
|
||||
- struct_stat stlink;
|
||||
- xlstat (testlink, &stlink);
|
||||
+ struct statx stlink;
|
||||
+ xstatx (AT_FDCWD, testlink, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS, &stlink);
|
||||
|
||||
- TEST_COMPARE (stlink.st_atime, tv[0].tv_sec);
|
||||
- TEST_COMPARE (stlink.st_mtime, tv[1].tv_sec);
|
||||
+ TEST_COMPARE (stlink.stx_atime.tv_sec, tv[0].tv_sec);
|
||||
+ TEST_COMPARE (stlink.stx_mtime.tv_sec, tv[1].tv_sec);
|
||||
|
||||
/* Check if the timestamp from original file is not changed. */
|
||||
- struct_stat stfile;
|
||||
- xlstat (testfile, &stfile);
|
||||
+ struct statx stfile;
|
||||
+ xstatx (AT_FDCWD, testfile, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS, &stfile);
|
||||
|
||||
- TEST_COMPARE (stfile_orig.st_atime, stfile.st_atime);
|
||||
- TEST_COMPARE (stfile_orig.st_mtime, stfile.st_mtime);
|
||||
+ TEST_COMPARE (stfile_orig.stx_atime.tv_sec, stfile.stx_atime.tv_sec);
|
||||
+ TEST_COMPARE (stfile_orig.stx_mtime.tv_sec, stfile.stx_mtime.tv_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/io/tst-utime-time64.c b/io/tst-utime-time64.c
|
||||
index eb62f59126..8894592a15 100644
|
||||
--- a/io/tst-utime-time64.c
|
||||
+++ b/io/tst-utime-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-utime.c"
|
||||
diff --git a/io/tst-utime.c b/io/tst-utime.c
|
||||
index e2e6dcd04c..f329358289 100644
|
||||
--- a/io/tst-utime.c
|
||||
+++ b/io/tst-utime.c
|
||||
@@ -19,26 +19,23 @@
|
||||
#include <utime.h>
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_utime_helper (const char *file, int fd, const struct utimbuf *ut)
|
||||
{
|
||||
int result = utime (file, ut);
|
||||
TEST_VERIFY_EXIT (result == 0);
|
||||
|
||||
- struct_stat st;
|
||||
- xfstat (fd, &st);
|
||||
+ struct statx st;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st);
|
||||
|
||||
/* Check if seconds for actime match */
|
||||
- TEST_COMPARE (st.st_atime, ut->actime);
|
||||
+ TEST_COMPARE (st.stx_atime.tv_sec, ut->actime);
|
||||
|
||||
/* Check if seconds for modtime match */
|
||||
- TEST_COMPARE (st.st_mtime, ut->modtime);
|
||||
+ TEST_COMPARE (st.stx_mtime.tv_sec, ut->modtime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/io/tst-utimensat-time64.c b/io/tst-utimensat-time64.c
|
||||
index 7ac7d8df1d..5d60fce881 100644
|
||||
--- a/io/tst-utimensat-time64.c
|
||||
+++ b/io/tst-utimensat-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-utimensat.c"
|
||||
diff --git a/io/tst-utimensat.c b/io/tst-utimensat.c
|
||||
index 3d9a72c471..2a756d7b07 100644
|
||||
--- a/io/tst-utimensat.c
|
||||
+++ b/io/tst-utimensat.c
|
||||
@@ -22,10 +22,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_utimesat_helper (const char *testfile, int fd, const char *testlink,
|
||||
const struct timespec *ts)
|
||||
@@ -33,35 +29,38 @@ test_utimesat_helper (const char *testfile, int fd, const char *testlink,
|
||||
{
|
||||
TEST_VERIFY_EXIT (utimensat (fd, testfile, ts, 0) == 0);
|
||||
|
||||
- struct_stat st;
|
||||
- xfstat (fd, &st);
|
||||
+ struct statx st;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st);
|
||||
|
||||
/* Check if seconds for atime match */
|
||||
- TEST_COMPARE (st.st_atime, ts[0].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_atime.tv_sec, ts[0].tv_sec);
|
||||
|
||||
/* Check if seconds for mtime match */
|
||||
- TEST_COMPARE (st.st_mtime, ts[1].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_mtime.tv_sec, ts[1].tv_sec);
|
||||
}
|
||||
|
||||
{
|
||||
- struct_stat stfile_orig;
|
||||
- xlstat (testfile, &stfile_orig);
|
||||
+ struct statx stfile_orig;
|
||||
+ xstatx (AT_FDCWD, testfile, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS,
|
||||
+ &stfile_orig);
|
||||
|
||||
TEST_VERIFY_EXIT (utimensat (0 /* ignored */, testlink, ts,
|
||||
AT_SYMLINK_NOFOLLOW)
|
||||
== 0);
|
||||
- struct_stat stlink;
|
||||
- xlstat (testlink, &stlink);
|
||||
+ struct statx stlink;
|
||||
+ xstatx (AT_FDCWD, testlink, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS,
|
||||
+ &stlink);
|
||||
|
||||
- TEST_COMPARE (stlink.st_atime, ts[0].tv_sec);
|
||||
- TEST_COMPARE (stlink.st_mtime, ts[1].tv_sec);
|
||||
+ TEST_COMPARE (stlink.stx_atime.tv_sec, ts[0].tv_sec);
|
||||
+ TEST_COMPARE (stlink.stx_mtime.tv_sec, ts[1].tv_sec);
|
||||
|
||||
/* Check if the timestamp from original file is not changed. */
|
||||
- struct_stat stfile;
|
||||
- xlstat (testfile, &stfile);
|
||||
+ struct statx stfile;
|
||||
+ xstatx (AT_FDCWD, testfile, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS,
|
||||
+ &stfile);
|
||||
|
||||
- TEST_COMPARE (stfile_orig.st_atime, stfile.st_atime);
|
||||
- TEST_COMPARE (stfile_orig.st_mtime, stfile.st_mtime);
|
||||
+ TEST_COMPARE (stfile_orig.stx_atime.tv_sec, stfile.stx_atime.tv_sec);
|
||||
+ TEST_COMPARE (stfile_orig.stx_mtime.tv_sec, stfile.stx_mtime.tv_sec);
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/io/tst-utimes-time64.c b/io/tst-utimes-time64.c
|
||||
index 234ec02541..026ef5f78d 100644
|
||||
--- a/io/tst-utimes-time64.c
|
||||
+++ b/io/tst-utimes-time64.c
|
||||
@@ -1,2 +1 @@
|
||||
-#define struct_stat struct stat
|
||||
#include "tst-utimes.c"
|
||||
diff --git a/io/tst-utimes.c b/io/tst-utimes.c
|
||||
index 8edcfabebf..6cd436c5a0 100644
|
||||
--- a/io/tst-utimes.c
|
||||
+++ b/io/tst-utimes.c
|
||||
@@ -18,28 +18,25 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
-#ifndef struct_stat
|
||||
-# define struct_stat struct stat64
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
test_utimes_helper (const char *file, int fd, const struct timeval *tv)
|
||||
{
|
||||
int result = utimes (file, tv);
|
||||
TEST_VERIFY_EXIT (result == 0);
|
||||
|
||||
- struct_stat st;
|
||||
- xfstat (fd, &st);
|
||||
+ struct statx st;
|
||||
+ xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st);
|
||||
|
||||
/* Check if seconds for atime match */
|
||||
- TEST_COMPARE (st.st_atime, tv[0].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_atime.tv_sec, tv[0].tv_sec);
|
||||
|
||||
/* Check if seconds for mtime match */
|
||||
- TEST_COMPARE (st.st_mtime, tv[1].tv_sec);
|
||||
+ TEST_COMPARE (st.stx_mtime.tv_sec, tv[1].tv_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.43.5
|
||||
|
452
SOURCES/glibc-RHEL-50545-6.patch
Normal file
452
SOURCES/glibc-RHEL-50545-6.patch
Normal file
@ -0,0 +1,452 @@
|
||||
From e7c14e542d8d858b824b5df4f4e3dc93695e6171 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri, 16 Aug 2024 16:05:20 +0200
|
||||
Subject: [PATCH] support: Use macros for *stat wrappers
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
Macros will automatically use the correct types, without
|
||||
having to fiddle with internal glibc macros. It's also
|
||||
impossible to get the types wrong due to aliasing because
|
||||
support_check_stat_fd and support_check_stat_path do not
|
||||
depend on the struct stat* types.
|
||||
|
||||
The changes reveal some inconsistencies in tests.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
Conflicts
|
||||
locale/tst-localedef-path-norm.c
|
||||
context
|
||||
support/Makefile
|
||||
context
|
||||
support/xunistd.h
|
||||
context
|
||||
all
|
||||
copyright years
|
||||
---
|
||||
elf/tst-ldconfig-bad-aux-cache.c | 2 +-
|
||||
io/tst-copy_file_range.c | 2 +-
|
||||
io/tst-statx.c | 4 +--
|
||||
locale/tst-localedef-path-norm.c | 2 +-
|
||||
localedata/tst-localedef-hardlinks.c | 2 +-
|
||||
posix/tst-execveat.c | 2 +-
|
||||
stdio-common/tst-renameat2.c | 2 +-
|
||||
stdlib/tst-system.c | 2 +-
|
||||
support/Makefile | 8 ++---
|
||||
support/support-xfstat-time64.c | 32 -------------------
|
||||
support/support-xstat-time64.c | 32 -------------------
|
||||
support/support-xstat.c | 30 -----------------
|
||||
support/{xlstat.c => support_check_stat_fd.c} | 11 +++----
|
||||
...ort-xfstat.c => support_check_stat_path.c} | 9 +++---
|
||||
support/xlstat-time64.c | 32 -------------------
|
||||
support/xunistd.h | 30 ++++++++---------
|
||||
16 files changed, 34 insertions(+), 168 deletions(-)
|
||||
delete mode 100644 support/support-xfstat-time64.c
|
||||
delete mode 100644 support/support-xstat-time64.c
|
||||
delete mode 100644 support/support-xstat.c
|
||||
rename support/{xlstat.c => support_check_stat_fd.c} (76%)
|
||||
rename support/{support-xfstat.c => support_check_stat_path.c} (81%)
|
||||
delete mode 100644 support/xlstat-time64.c
|
||||
|
||||
diff --git a/elf/tst-ldconfig-bad-aux-cache.c b/elf/tst-ldconfig-bad-aux-cache.c
|
||||
index 7f1fbb5252..8c2e62ecc2 100644
|
||||
--- a/elf/tst-ldconfig-bad-aux-cache.c
|
||||
+++ b/elf/tst-ldconfig-bad-aux-cache.c
|
||||
@@ -85,7 +85,7 @@ do_test (void)
|
||||
support_capture_subprocess_check (&result, "execv", 0, sc_allow_none);
|
||||
support_capture_subprocess_free (&result);
|
||||
|
||||
- xstat (path, &fs);
|
||||
+ xstat64 (path, &fs);
|
||||
|
||||
size = fs.st_size;
|
||||
/* Run 3 tests, each truncating aux-cache shorter and shorter. */
|
||||
diff --git a/io/tst-copy_file_range.c b/io/tst-copy_file_range.c
|
||||
index 9837b7c339..3d7b0aa901 100644
|
||||
--- a/io/tst-copy_file_range.c
|
||||
+++ b/io/tst-copy_file_range.c
|
||||
@@ -117,7 +117,7 @@ simple_file_copy (void)
|
||||
TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 6 + length);
|
||||
|
||||
struct stat64 st;
|
||||
- xfstat (outfd, &st);
|
||||
+ xfstat64 (outfd, &st);
|
||||
if (length > 0)
|
||||
TEST_COMPARE (st.st_size, out_skipped + length);
|
||||
else
|
||||
diff --git a/io/tst-statx.c b/io/tst-statx.c
|
||||
index d84568859e..685924ae76 100644
|
||||
--- a/io/tst-statx.c
|
||||
+++ b/io/tst-statx.c
|
||||
@@ -78,7 +78,7 @@ both_implementations_tests (statx_function impl, const char *path, int fd)
|
||||
struct statx stx = { 0, };
|
||||
TEST_COMPARE (statx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &stx), 0);
|
||||
struct stat64 st;
|
||||
- xfstat (fd, &st);
|
||||
+ xfstat64 (fd, &st);
|
||||
TEST_COMPARE (stx.stx_mode, st.st_mode);
|
||||
TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
|
||||
TEST_COMPARE (stx.stx_dev_minor, minor (st.st_dev));
|
||||
@@ -88,7 +88,7 @@ both_implementations_tests (statx_function impl, const char *path, int fd)
|
||||
TEST_COMPARE (statx (AT_FDCWD, "/dev/null", 0, STATX_BASIC_STATS, &stx),
|
||||
0);
|
||||
struct stat64 st;
|
||||
- xstat ("/dev/null", &st);
|
||||
+ xstat64 ("/dev/null", &st);
|
||||
TEST_COMPARE (stx.stx_mode, st.st_mode);
|
||||
TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
|
||||
TEST_COMPARE (stx.stx_dev_minor, minor (st.st_dev));
|
||||
diff --git a/locale/tst-localedef-path-norm.c b/locale/tst-localedef-path-norm.c
|
||||
index ffe8cbd467..f592b9a960 100644
|
||||
--- a/locale/tst-localedef-path-norm.c
|
||||
+++ b/locale/tst-localedef-path-norm.c
|
||||
@@ -81,7 +81,7 @@ run_test (struct test_closure data)
|
||||
support_capture_subprocess_free (&result);
|
||||
|
||||
/* Verify path is present and is a directory. */
|
||||
- xstat (path, &fs);
|
||||
+ xstat64 (path, &fs);
|
||||
TEST_VERIFY_EXIT (S_ISDIR (fs.st_mode));
|
||||
printf ("info: Directory '%s' exists.\n", path);
|
||||
}
|
||||
diff --git a/localedata/tst-localedef-hardlinks.c b/localedata/tst-localedef-hardlinks.c
|
||||
index e88215a150..23927b462f 100644
|
||||
--- a/localedata/tst-localedef-hardlinks.c
|
||||
+++ b/localedata/tst-localedef-hardlinks.c
|
||||
@@ -62,7 +62,7 @@ check_link (struct test_data step)
|
||||
char *output;
|
||||
|
||||
output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output);
|
||||
- xstat (output, &locale);
|
||||
+ xstat64 (output, &locale);
|
||||
free (output);
|
||||
TEST_COMPARE (locale.st_nlink, step.st_nlink);
|
||||
}
|
||||
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
|
||||
index 4565d6b19f..dde034a9f1 100644
|
||||
--- a/posix/tst-execveat.c
|
||||
+++ b/posix/tst-execveat.c
|
||||
@@ -155,7 +155,7 @@ do_test (void)
|
||||
tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
|
||||
add_temp_file (tmp_sh);
|
||||
fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
|
||||
- xstat ("/bin/sh", &st);
|
||||
+ xstat64 ("/bin/sh", &st);
|
||||
fd = xopen ("/bin/sh", O_RDONLY, 0);
|
||||
xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
|
||||
xfchmod (fd_out, 0700);
|
||||
diff --git a/stdio-common/tst-renameat2.c b/stdio-common/tst-renameat2.c
|
||||
index b65afed75e..7f4345f716 100644
|
||||
--- a/stdio-common/tst-renameat2.c
|
||||
+++ b/stdio-common/tst-renameat2.c
|
||||
@@ -82,7 +82,7 @@ static void
|
||||
check_size (const char *path, off64_t expected_size)
|
||||
{
|
||||
struct stat64 st;
|
||||
- xstat (path, &st);
|
||||
+ xstat64 (path, &st);
|
||||
if (st.st_size != expected_size)
|
||||
FAIL_EXIT1 ("file \"%s\": expected size %lld, actual size %lld",
|
||||
path, (unsigned long long int) expected_size,
|
||||
diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
|
||||
index 47c742f963..b5b630a41b 100644
|
||||
--- a/stdlib/tst-system.c
|
||||
+++ b/stdlib/tst-system.c
|
||||
@@ -156,7 +156,7 @@ do_test (void)
|
||||
|
||||
{
|
||||
struct stat64 st;
|
||||
- xstat (_PATH_BSHELL, &st);
|
||||
+ xstat64 (_PATH_BSHELL, &st);
|
||||
mode_t mode = st.st_mode;
|
||||
xchmod (_PATH_BSHELL, mode & ~(S_IXUSR | S_IXGRP | S_IXOTH));
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 5b1c96a49e..6e3c55394f 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -42,14 +42,12 @@ libsupport-routines = \
|
||||
resolv_test \
|
||||
set_fortify_handler \
|
||||
support_stack_alloc \
|
||||
- support-xfstat \
|
||||
- support-xfstat-time64 \
|
||||
- support-xstat \
|
||||
- support-xstat-time64 \
|
||||
support_become_root \
|
||||
support_can_chroot \
|
||||
support_capture_subprocess \
|
||||
support_capture_subprocess_check \
|
||||
+ support_check_stat_fd \
|
||||
+ support_check_stat_path \
|
||||
support_chroot \
|
||||
support_copy_file \
|
||||
support_copy_file_range \
|
||||
@@ -130,8 +128,6 @@ libsupport-routines = \
|
||||
xgetsockname \
|
||||
xlisten \
|
||||
xlseek \
|
||||
- xlstat \
|
||||
- xlstat-time64 \
|
||||
xmalloc \
|
||||
xmemstream \
|
||||
xmkdir \
|
||||
diff --git a/support/support-xfstat-time64.c b/support/support-xfstat-time64.c
|
||||
deleted file mode 100644
|
||||
index 589a69bb3e..0000000000
|
||||
--- a/support/support-xfstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021 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
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-/* NB: Non-standard file name to avoid sysdeps override for xstat. */
|
||||
-
|
||||
-#include <support/check.h>
|
||||
-#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-#if __TIMESIZE != 64
|
||||
-void
|
||||
-xfstat_time64 (int fd, struct __stat64_t64 *result)
|
||||
-{
|
||||
- if (__fstat64_time64 (fd, result) != 0)
|
||||
- FAIL_EXIT1 ("__fstat64_time64 (%d): %m", fd);
|
||||
-}
|
||||
-#endif
|
||||
diff --git a/support/support-xstat-time64.c b/support/support-xstat-time64.c
|
||||
deleted file mode 100644
|
||||
index 451948734a..0000000000
|
||||
--- a/support/support-xstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021 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
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-/* NB: Non-standard file name to avoid sysdeps override for xstat. */
|
||||
-
|
||||
-#include <support/check.h>
|
||||
-#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-#if __TIMESIZE != 64
|
||||
-void
|
||||
-xstat_time64 (const char *path, struct __stat64_t64 *result)
|
||||
-{
|
||||
- if (__stat64_time64 (path, result) != 0)
|
||||
- FAIL_EXIT1 ("__stat64_time64 (\"%s\"): %m", path);
|
||||
-}
|
||||
-#endif
|
||||
diff --git a/support/support-xstat.c b/support/support-xstat.c
|
||||
deleted file mode 100644
|
||||
index ce866f74d2..0000000000
|
||||
--- a/support/support-xstat.c
|
||||
+++ /dev/null
|
||||
@@ -1,30 +0,0 @@
|
||||
-/* stat64 with error checking.
|
||||
- Copyright (C) 2017-2021 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
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-/* NB: Non-standard file name to avoid sysdeps override for xstat. */
|
||||
-
|
||||
-#include <support/check.h>
|
||||
-#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-void
|
||||
-xstat (const char *path, struct stat64 *result)
|
||||
-{
|
||||
- if (stat64 (path, result) != 0)
|
||||
- FAIL_EXIT1 ("stat64 (\"%s\"): %m", path);
|
||||
-}
|
||||
diff --git a/support/xlstat.c b/support/support_check_stat_fd.c
|
||||
similarity index 76%
|
||||
rename from support/xlstat.c
|
||||
rename to support/support_check_stat_fd.c
|
||||
index 87df988879..4c12adf6b7 100644
|
||||
--- a/support/xlstat.c
|
||||
+++ b/support/support_check_stat_fd.c
|
||||
@@ -1,5 +1,5 @@
|
||||
-/* lstat64 with error checking.
|
||||
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
+/* Error checking for descriptor-based stat functions.
|
||||
+ Copyright (C) 2024 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
|
||||
@@ -18,11 +18,10 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
|
||||
void
|
||||
-xlstat (const char *path, struct stat64 *result)
|
||||
+support_check_stat_fd (const char *name, int fd, int result)
|
||||
{
|
||||
- if (lstat64 (path, result) != 0)
|
||||
- FAIL_EXIT1 ("lstat64 (\"%s\"): %m", path);
|
||||
+ if (result != 0)
|
||||
+ FAIL_EXIT1 ("%s (%d): %m", name, fd);
|
||||
}
|
||||
diff --git a/support/support-xfstat.c b/support/support_check_stat_path.c
|
||||
similarity index 81%
|
||||
rename from support/support-xfstat.c
|
||||
rename to support/support_check_stat_path.c
|
||||
index ab4b01c97d..3cf72afe59 100644
|
||||
--- a/support/support-xfstat.c
|
||||
+++ b/support/support_check_stat_path.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* fstat64 with error checking.
|
||||
+/* Error checking for path-based stat functions.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -18,11 +18,10 @@
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
|
||||
void
|
||||
-xfstat (int fd, struct stat64 *result)
|
||||
+support_check_stat_path (const char *name, const char *path, int result)
|
||||
{
|
||||
- if (fstat64 (fd, result) != 0)
|
||||
- FAIL_EXIT1 ("fstat64 (%d): %m", fd);
|
||||
+ if (result != 0)
|
||||
+ FAIL_EXIT1 ("%s (\"%s\"): %m", name, path);
|
||||
}
|
||||
diff --git a/support/xlstat-time64.c b/support/xlstat-time64.c
|
||||
deleted file mode 100644
|
||||
index 2bc3ca6593..0000000000
|
||||
--- a/support/xlstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021 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
|
||||
- <https://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-/* NB: Non-standard file name to avoid sysdeps override for xstat. */
|
||||
-
|
||||
-#include <support/check.h>
|
||||
-#include <support/xunistd.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-#if __TIMESIZE != 64
|
||||
-void
|
||||
-xlstat_time64 (const char *path, struct __stat64_t64 *result)
|
||||
-{
|
||||
- if (__lstat64_time64 (path, result) != 0)
|
||||
- FAIL_EXIT1 ("__lstat64_time64 (\"%s\"): %m", path);
|
||||
-}
|
||||
-#endif
|
||||
diff --git a/support/xunistd.h b/support/xunistd.h
|
||||
index cc74c4fad0..204951bce7 100644
|
||||
--- a/support/xunistd.h
|
||||
+++ b/support/xunistd.h
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
-struct stat64;
|
||||
struct statx;
|
||||
|
||||
pid_t xfork (void);
|
||||
@@ -37,21 +36,20 @@ pid_t xwaitpid (pid_t, int *status, int
|
||||
void xpipe (int[2]);
|
||||
void xdup2 (int, int);
|
||||
int xopen (const char *path, int flags, mode_t);
|
||||
-#ifndef __USE_TIME_BITS64
|
||||
-# ifdef __USE_FILE_OFFSET64
|
||||
-void xstat (const char *path, struct stat *);
|
||||
-void xlstat (const char *path, struct stat *);
|
||||
-void xfstat (int fd, struct stat *);
|
||||
-# else
|
||||
-void xstat (const char *path, struct stat64 *);
|
||||
-void xlstat (const char *path, struct stat64 *);
|
||||
-void xfstat (int fd, struct stat64 *);
|
||||
-# endif
|
||||
-#else
|
||||
-void __REDIRECT (xstat, (const char *path, struct stat *), xstat_time64);
|
||||
-void __REDIRECT (xlstat, (const char *path, struct stat *), xlstat_time64);
|
||||
-void __REDIRECT (xfstat, (int fd, struct stat *), xfstat_time64);
|
||||
-#endif
|
||||
+void support_check_stat_fd (const char *name, int fd, int result);
|
||||
+void support_check_stat_path (const char *name, const char *path, int result);
|
||||
+#define xstat(path, st) \
|
||||
+ (support_check_stat_path ("stat", (path), stat ((path), (st))))
|
||||
+#define xfstat(fd, st) \
|
||||
+ (support_check_stat_fd ("fstat", (fd), fstat ((fd), (st))))
|
||||
+#define xlstat(path, st) \
|
||||
+ (support_check_stat_path ("lstat", (path), lstat ((path), (st))))
|
||||
+#define xstat64(path, st) \
|
||||
+ (support_check_stat_path ("stat64", (path), stat64 ((path), (st))))
|
||||
+#define xfstat64(fd, st) \
|
||||
+ (support_check_stat_fd ("fstat64", (fd), fstat64 ((fd), (st))))
|
||||
+#define xlstat64(path, st) \
|
||||
+ (support_check_stat_path ("lstat64", (path), lstat64 ((path), (st))))
|
||||
void xstatx (int, const char *, int, unsigned int, struct statx *);
|
||||
void xmkdir (const char *path, mode_t);
|
||||
void xchroot (const char *path);
|
||||
--
|
||||
2.43.5
|
||||
|
47
SOURCES/glibc-RHEL-50545-7.patch
Normal file
47
SOURCES/glibc-RHEL-50545-7.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 34e52acd55d69964d14fb3188c5538442b8b32be Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 22 Aug 2024 16:14:17 +0200
|
||||
Subject: [PATCH] support: Report errno constants in TEST_COMPARE failures
|
||||
Content-type: text/plain; charset=UTF-8
|
||||
|
||||
If the expression is errno, decode it as an errno constant
|
||||
using strerrorname_np.
|
||||
|
||||
Reviewed-by: Arjun Shankar <arjun@redhat.com>
|
||||
---
|
||||
support/support_test_compare_failure.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c
|
||||
index ae73d200cd..dba79e413f 100644
|
||||
--- a/support/support_test_compare_failure.c
|
||||
+++ b/support/support_test_compare_failure.c
|
||||
@@ -17,7 +17,9 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
+#include <limits.h>
|
||||
#include <stdio.h>
|
||||
+#include <string.h>
|
||||
#include <support/check.h>
|
||||
|
||||
static void
|
||||
@@ -31,7 +33,14 @@ report (const char *which, const char *expr, long long value, int positive,
|
||||
printf ("%lld", value);
|
||||
unsigned long long mask
|
||||
= (~0ULL) >> (8 * (sizeof (unsigned long long) - size));
|
||||
- printf (" (0x%llx); from: %s\n", (unsigned long long) value & mask, expr);
|
||||
+ const char *errno_constant = NULL;
|
||||
+ if (strcmp (expr, "errno") == 0
|
||||
+ && positive && (unsigned long long int) value <= INT_MAX)
|
||||
+ errno_constant = strerrorname_np (value);
|
||||
+ printf (" (0x%llx", (unsigned long long) value & mask);
|
||||
+ if (errno_constant != NULL)
|
||||
+ printf (", %s", errno_constant);
|
||||
+ printf ("); from: %s\n", expr);
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
2.43.5
|
||||
|
1661
SOURCES/glibc-RHEL-50545-8.patch
Normal file
1661
SOURCES/glibc-RHEL-50545-8.patch
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user