Improve test coverage (RHEL-106562)
Resolves: RHEL-106562
This commit is contained in:
parent
0d5bc43414
commit
5e0f6b30b8
69
glibc-RHEL-106562-1.patch
Normal file
69
glibc-RHEL-106562-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 1d60ac783be6fb65..0cae545f86ac1352 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);
|
||||
|
20
glibc-RHEL-106562-10.patch
Normal file
20
glibc-RHEL-106562-10.patch
Normal file
@ -0,0 +1,20 @@
|
||||
commit 79f44e1a47e87907fb8e97bbd098e01c4adc26a5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Aug 26 16:45:31 2024 +0200
|
||||
|
||||
inet: Avoid label at end of compound statement in tst-if_nameindex
|
||||
|
||||
This fails to compile with GCC 8.
|
||||
|
||||
diff --git a/inet/tst-if_nameindex.c b/inet/tst-if_nameindex.c
|
||||
index b025cdb3a7c6b68c..5b905601245bef34 100644
|
||||
--- a/inet/tst-if_nameindex.c
|
||||
+++ b/inet/tst-if_nameindex.c
|
||||
@@ -105,6 +105,7 @@ do_test (void)
|
||||
TEST_VERIFY (errno == ENODEV);
|
||||
|
||||
not_this_one:
|
||||
+ ;
|
||||
}
|
||||
|
||||
|
288
glibc-RHEL-106562-11.patch
Normal file
288
glibc-RHEL-106562-11.patch
Normal file
@ -0,0 +1,288 @@
|
||||
commit 4945ffc88a8ad49280bae64165683ddfd12b2390
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Wed Aug 7 16:55:16 2024 -0400
|
||||
|
||||
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 c822434293b7e809..6b52fd3e0d818960 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -209,6 +209,7 @@ tests := \
|
||||
tst-fdopen2 \
|
||||
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 0000000000000000..5b78447ea9aa3cbe
|
||||
--- /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>
|
90
glibc-RHEL-106562-12.patch
Normal file
90
glibc-RHEL-106562-12.patch
Normal file
@ -0,0 +1,90 @@
|
||||
commit 83fd4149ffdae86c8864a6828f39dd942956636f
|
||||
Author: Aaron Merey <amerey@redhat.com>
|
||||
Date: Thu Sep 19 11:11:39 2024 -0400
|
||||
|
||||
Test that errno is set to 0 at program startup
|
||||
|
||||
Add new testcase elf/tst-startup-errno.c which tests that errno is set
|
||||
to 0 at first ELF constructor execution and at the start of the
|
||||
program's main function.
|
||||
|
||||
Tested for x86_64
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index a46c4f69d98553f7..92da608da1ebc175 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -457,6 +457,7 @@ tests += \
|
||||
tst-single_threaded-pthread \
|
||||
tst-sonamemove-dlopen \
|
||||
tst-sonamemove-link \
|
||||
+ tst-startup-errno \
|
||||
tst-thrlock \
|
||||
tst-tls-dlinfo \
|
||||
tst-tls-ie \
|
||||
diff --git a/elf/tst-startup-errno.c b/elf/tst-startup-errno.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..59a1005fb674a5c3
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-startup-errno.c
|
||||
@@ -0,0 +1,58 @@
|
||||
+/* Test the value of errno at program startup.
|
||||
+ 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 <stdlib.h>
|
||||
+
|
||||
+/* Verify that errno is 0 at first ELF constructor execution and at
|
||||
+ the start of main. */
|
||||
+
|
||||
+static void set_ctor_errno (void) __attribute__((constructor));
|
||||
+static int ctor_errno = -1;
|
||||
+
|
||||
+static void
|
||||
+set_ctor_errno (void)
|
||||
+{
|
||||
+ ctor_errno = errno;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+get_ctor_errno (void)
|
||||
+{
|
||||
+ return ctor_errno;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ if (errno != 0)
|
||||
+ {
|
||||
+ printf ("At start of main errno set to %d != 0\n", errno);
|
||||
+ exit (1);
|
||||
+ }
|
||||
+
|
||||
+ if (get_ctor_errno () != 0)
|
||||
+ {
|
||||
+ printf ("At ctor exec errno set to %d != 0\n", get_ctor_errno ());
|
||||
+ exit (1);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
301
glibc-RHEL-106562-13.patch
Normal file
301
glibc-RHEL-106562-13.patch
Normal file
@ -0,0 +1,301 @@
|
||||
commit cfb35f5f7f32cec8fa4e16b99e35b7d70fa13f1f
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Tue Sep 17 22:52:37 2024 -0400
|
||||
|
||||
rt: more clock_nanosleep tests
|
||||
|
||||
Test that clock_nanosleep rejects out of range time values.
|
||||
|
||||
Test that clock_nanosleep actually sleeps for at least the
|
||||
requested time relative to the requested clock.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/rt/Makefile b/rt/Makefile
|
||||
index 7b50c64f7664c07f..bc5f28c6d03722a3 100644
|
||||
--- a/rt/Makefile
|
||||
+++ b/rt/Makefile
|
||||
@@ -77,6 +77,7 @@ tests := tst-shm tst-timer tst-timer2 \
|
||||
tst-bz28213 \
|
||||
tst-timer3 tst-timer4 tst-timer5 \
|
||||
tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
|
||||
+ tst-clock_nanosleep2 \
|
||||
tst-shm-cancel \
|
||||
tst-mqueue10
|
||||
tests-internal := tst-timer-sigmask
|
||||
@@ -84,6 +85,7 @@ tests-internal := tst-timer-sigmask
|
||||
tests-time64 := \
|
||||
tst-aio6-time64 \
|
||||
tst-cpuclock2-time64 \
|
||||
+ tst-clock_nanosleep2-time64 \
|
||||
tst-mqueue1-time64 \
|
||||
tst-mqueue2-time64 \
|
||||
tst-mqueue4-time64 \
|
||||
diff --git a/rt/tst-clock_nanosleep2-time64.c b/rt/tst-clock_nanosleep2-time64.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8deb4201f38b094a
|
||||
--- /dev/null
|
||||
+++ b/rt/tst-clock_nanosleep2-time64.c
|
||||
@@ -0,0 +1 @@
|
||||
+#include "tst-clock_nanosleep2.c"
|
||||
diff --git a/rt/tst-clock_nanosleep2.c b/rt/tst-clock_nanosleep2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..10c822fd54668531
|
||||
--- /dev/null
|
||||
+++ b/rt/tst-clock_nanosleep2.c
|
||||
@@ -0,0 +1,255 @@
|
||||
+/* Test program for process CPU clocks - invalid inputs, minimum time
|
||||
+ 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 test has two primary goals - first, to validate that invalid
|
||||
+ inputs to clock_nanosleep are caught, and second, to validate that
|
||||
+ clock_nanosleep sleeps for at least the amount of time requested.
|
||||
+ It is assumed that the system may sleep for an arbitrary additional
|
||||
+ amount of time beyond the requested time. */
|
||||
+
|
||||
+#include <unistd.h>
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <time.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <string.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <support/timespec.h>
|
||||
+
|
||||
+/* This is 1 ms per test, we have 10 tests, so this file runs in on
|
||||
+ the order of 0.01 seconds. */
|
||||
+#define TEST_NSEC 1000000
|
||||
+
|
||||
+/* Nanoseconds per second. */
|
||||
+#define NSECMAX 1000000000L
|
||||
+
|
||||
+static pthread_barrier_t barrier;
|
||||
+
|
||||
+/* This function is intended to rack up both user and system time. */
|
||||
+static void *
|
||||
+chew_cpu (void *arg)
|
||||
+{
|
||||
+ pthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ while (1)
|
||||
+ {
|
||||
+ static volatile char buf[4096];
|
||||
+ for (int i = 0; i < 100; ++i)
|
||||
+ for (size_t j = 0; j < sizeof buf; ++j)
|
||||
+ buf[j] = 0xaa;
|
||||
+ int nullfd = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ for (int i = 0; i < 100; ++i)
|
||||
+ for (size_t j = 0; j < sizeof buf; ++j)
|
||||
+ buf[j] = 0xbb;
|
||||
+ xwrite (nullfd, (char *) buf, sizeof buf);
|
||||
+ close (nullfd);
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ptime_1 (const char *n, struct timespec t)
|
||||
+{
|
||||
+ /* This is only for debugging failed test cases. */
|
||||
+ printf ("%12s: %lld.%09lld\n", n, (long long int) t.tv_sec,
|
||||
+ (long long int) t.tv_nsec);
|
||||
+}
|
||||
+#define ptime(t) ptime_1 (#t, t)
|
||||
+
|
||||
+static void
|
||||
+test_interval_1 (const char *n_clock, clockid_t t_clock)
|
||||
+{
|
||||
+ struct timespec me_before, me_after, quantum, me_sleep, me_slept;
|
||||
+ long long int slept, min_slept;
|
||||
+
|
||||
+ /* Arbitrary to ensure our time period is sufficiently bigger than
|
||||
+ the time step. */
|
||||
+ TEST_VERIFY (clock_getres (t_clock, &quantum) == 0);
|
||||
+ printf("Clock quantum: %lld ns, test time: %lld ns\n",
|
||||
+ (long long int) quantum.tv_nsec, (long long int) TEST_NSEC);
|
||||
+ TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10);
|
||||
+
|
||||
+ min_slept = TEST_NSEC;
|
||||
+
|
||||
+ me_sleep = make_timespec (0, min_slept);
|
||||
+
|
||||
+ printf ("test clock %s for %lld.%09lld sec relative\n",
|
||||
+ n_clock, (long long int) me_sleep.tv_sec,
|
||||
+ (long long int) me_sleep.tv_nsec);
|
||||
+
|
||||
+ TEST_COMPARE (clock_gettime (t_clock, &me_before), 0);
|
||||
+ TEST_COMPARE (clock_nanosleep (t_clock, 0, &me_sleep, NULL), 0);
|
||||
+ TEST_COMPARE (clock_gettime (t_clock, &me_after), 0);
|
||||
+
|
||||
+ me_slept = timespec_sub (me_after, me_before);
|
||||
+ slept = support_timespec_ns (me_slept);
|
||||
+
|
||||
+ ptime (me_before);
|
||||
+ ptime (me_after);
|
||||
+ ptime (me_sleep);
|
||||
+ ptime (me_slept);
|
||||
+ printf ("test slept %lld nsec >= asked for %lld ?\n", slept, min_slept);
|
||||
+
|
||||
+ /* This is the important part - verify that the time slept is at
|
||||
+ least as much as the time requested. */
|
||||
+ TEST_VERIFY (slept >= min_slept);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_abs_1 (const char *n_clock, clockid_t t_clock)
|
||||
+{
|
||||
+ struct timespec me_before, me_after, quantum, me_sleep;
|
||||
+
|
||||
+ /* Arbitrary to ensure our time period is sufficiently bigger than
|
||||
+ the time step. */
|
||||
+ TEST_VERIFY (clock_getres (t_clock, &quantum) == 0);
|
||||
+ printf("Clock quantum: %lld ns, test time: %lld ns\n",
|
||||
+ (long long int) quantum.tv_nsec, (long long int) TEST_NSEC);
|
||||
+ TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10);
|
||||
+
|
||||
+ me_sleep = make_timespec (0, TEST_NSEC);
|
||||
+
|
||||
+ printf ("test clock %s for %lld.%09lld sec absolute\n",
|
||||
+ n_clock, (long long int) me_sleep.tv_sec,
|
||||
+ (long long int) me_sleep.tv_nsec);
|
||||
+
|
||||
+ TEST_COMPARE (clock_gettime (t_clock, &me_before), 0);
|
||||
+ me_sleep = timespec_add (me_sleep, me_before);
|
||||
+ TEST_COMPARE (clock_nanosleep (t_clock, TIMER_ABSTIME, &me_sleep, NULL), 0);
|
||||
+ TEST_COMPARE (clock_gettime (t_clock, &me_after), 0);
|
||||
+
|
||||
+ ptime (me_before);
|
||||
+ ptime (me_sleep);
|
||||
+ ptime (me_after);
|
||||
+
|
||||
+ printf("test slept until %lld.%09lld after requested %lld.%09lld ?\n",
|
||||
+ (long long int) me_after.tv_sec, (long long int) me_after.tv_nsec,
|
||||
+ (long long int) me_sleep.tv_sec, (long long int) me_sleep.tv_nsec);
|
||||
+
|
||||
+ /* This is the important part - verify that the time slept is at
|
||||
+ least as much as the time requested. */
|
||||
+ TEST_TIMESPEC_EQUAL_OR_AFTER (me_after, me_sleep);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_invalids_1 (const char *the_clock_name, int the_clock,
|
||||
+ const char *flags_name, int flags)
|
||||
+{
|
||||
+ struct timespec me_before;
|
||||
+
|
||||
+ /* Note: do not use make_timespec() in case that function tries to
|
||||
+ normalize the fields. */
|
||||
+
|
||||
+ printf ("%s: %s: test tv 0, 0\n", the_clock_name, flags_name);
|
||||
+ me_before.tv_sec = 0;
|
||||
+ me_before.tv_nsec = 0;
|
||||
+ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), 0);
|
||||
+
|
||||
+ printf ("%s: %s: test tv -1, 0\n", the_clock_name, flags_name);
|
||||
+ me_before.tv_sec = -1;
|
||||
+ me_before.tv_nsec = 0;
|
||||
+ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
|
||||
+
|
||||
+ printf ("%s: %s: test tv 0, -1\n", the_clock_name, flags_name);
|
||||
+ me_before.tv_sec = 0;
|
||||
+ me_before.tv_nsec = -1;
|
||||
+ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
|
||||
+
|
||||
+ printf ("%s: %s: test tv -1, -1\n", the_clock_name, flags_name);
|
||||
+ me_before.tv_sec = -1;
|
||||
+ me_before.tv_nsec = -1;
|
||||
+ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
|
||||
+
|
||||
+ printf ("%s: %s: test tv 0, MAX\n", the_clock_name, flags_name);
|
||||
+ me_before.tv_sec = 0;
|
||||
+ me_before.tv_nsec = NSECMAX;
|
||||
+ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ pthread_t th;
|
||||
+
|
||||
+ pthread_barrier_init (&barrier, NULL, 2);
|
||||
+
|
||||
+ /* Test for proper error detection. */
|
||||
+
|
||||
+#define test_invalids(c, f) test_invalids_1 (#c, c, #f, f)
|
||||
+ test_invalids (CLOCK_REALTIME, 0);
|
||||
+#ifdef CLOCK_TAI
|
||||
+ test_invalids (CLOCK_TAI, 0);
|
||||
+#endif
|
||||
+ test_invalids (CLOCK_MONOTONIC, 0);
|
||||
+#ifdef CLOCK_BOOTTIME
|
||||
+ test_invalids (CLOCK_BOOTTIME, 0);
|
||||
+#endif
|
||||
+ test_invalids (CLOCK_PROCESS_CPUTIME_ID, 0);
|
||||
+ test_invalids (CLOCK_REALTIME, TIMER_ABSTIME);
|
||||
+#ifdef CLOCK_TAI
|
||||
+ test_invalids (CLOCK_TAI, TIMER_ABSTIME);
|
||||
+#endif
|
||||
+ test_invalids (CLOCK_MONOTONIC, TIMER_ABSTIME);
|
||||
+#ifdef CLOCK_BOOTTIME
|
||||
+ test_invalids (CLOCK_BOOTTIME, TIMER_ABSTIME);
|
||||
+#endif
|
||||
+ test_invalids (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME);
|
||||
+
|
||||
+ /* Test for various clocks "working". */
|
||||
+
|
||||
+#define test_interval(c) test_interval_1 (#c, c)
|
||||
+ test_interval (CLOCK_REALTIME);
|
||||
+#ifdef CLOCK_TAI
|
||||
+ test_interval (CLOCK_TAI);
|
||||
+#endif
|
||||
+ test_interval (CLOCK_MONOTONIC);
|
||||
+#ifdef CLOCK_BOOTTIME
|
||||
+ test_interval (CLOCK_BOOTTIME);
|
||||
+#endif
|
||||
+
|
||||
+ th = xpthread_create (NULL, chew_cpu, NULL);
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+ test_interval (CLOCK_PROCESS_CPUTIME_ID);
|
||||
+ xpthread_cancel (th);
|
||||
+
|
||||
+#define test_abs(c) test_abs_1 (#c, c)
|
||||
+ test_abs (CLOCK_REALTIME);
|
||||
+#ifdef CLOCK_TAI
|
||||
+ test_abs (CLOCK_TAI);
|
||||
+#endif
|
||||
+ test_abs (CLOCK_MONOTONIC);
|
||||
+#ifdef CLOCK_BOOTTIME
|
||||
+ test_abs (CLOCK_BOOTTIME);
|
||||
+#endif
|
||||
+
|
||||
+ th = xpthread_create (NULL, chew_cpu, NULL);
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+ test_abs (CLOCK_PROCESS_CPUTIME_ID);
|
||||
+ xpthread_cancel (th);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
18
glibc-RHEL-106562-14.patch
Normal file
18
glibc-RHEL-106562-14.patch
Normal file
@ -0,0 +1,18 @@
|
||||
commit 1895a35e7092713b224166d36b9bc26e8eb3371f
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Tue Oct 8 14:30:21 2024 -0400
|
||||
|
||||
rt: more clock_nanosleep tests addendum
|
||||
|
||||
Forgot to change the first-line description.
|
||||
|
||||
diff --git a/rt/tst-clock_nanosleep2.c b/rt/tst-clock_nanosleep2.c
|
||||
index 10c822fd54668531..e9b2a2716d6e9016 100644
|
||||
--- a/rt/tst-clock_nanosleep2.c
|
||||
+++ b/rt/tst-clock_nanosleep2.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Test program for process CPU clocks - invalid inputs, minimum time
|
||||
+/* Test for clock_nanosleep parameter checks and sleep duration.
|
||||
Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
218
glibc-RHEL-106562-15.patch
Normal file
218
glibc-RHEL-106562-15.patch
Normal file
@ -0,0 +1,218 @@
|
||||
commit 99671e72bb27a3cb98860bdc4c0e25961ce96b3e
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Nov 22 16:58:51 2024 +0000
|
||||
|
||||
Add multithreaded test of sem_getvalue
|
||||
|
||||
Test coverage of sem_getvalue is fairly limited. Add a test that runs
|
||||
it on threads on each CPU. For this purpose I adapted
|
||||
tst-skeleton-thread-affinity.c; it didn't seem very suitable to use
|
||||
as-is or include directly in a different test doing things per-CPU,
|
||||
but did seem a suitable starting point (thus sharing
|
||||
tst-skeleton-affinity.c) for such testing.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index eee91c7b64d79fe7..47bf050759bd2b4e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -653,6 +653,7 @@ ifeq ($(subdir),nptl)
|
||||
tests += \
|
||||
tst-align-clone \
|
||||
tst-getpid1 \
|
||||
+ tst-sem_getvalue-affinity \
|
||||
# tests
|
||||
|
||||
# tst-rseq-nptl is an internal test because it requires a definition of
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-sem_getvalue-affinity.c b/sysdeps/unix/sysv/linux/tst-sem_getvalue-affinity.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4176f67533357909
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-sem_getvalue-affinity.c
|
||||
@@ -0,0 +1,185 @@
|
||||
+/* Test sem_getvalue across CPUs. Based on tst-skeleton-thread-affinity.c.
|
||||
+ Copyright (C) 2015-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 <pthread.h>
|
||||
+#include <semaphore.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <sys/time.h>
|
||||
+
|
||||
+struct conf;
|
||||
+static bool early_test (struct conf *);
|
||||
+
|
||||
+static int
|
||||
+setaffinity (size_t size, const cpu_set_t *set)
|
||||
+{
|
||||
+ int ret = pthread_setaffinity_np (pthread_self (), size, set);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+getaffinity (size_t size, cpu_set_t *set)
|
||||
+{
|
||||
+ int ret = pthread_getaffinity_np (pthread_self (), size, set);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include "tst-skeleton-affinity.c"
|
||||
+
|
||||
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static sem_t sem;
|
||||
+
|
||||
+static void *
|
||||
+tf (void *arg)
|
||||
+{
|
||||
+ void *ret = NULL;
|
||||
+ xpthread_mutex_lock (&lock);
|
||||
+ int semval;
|
||||
+ if (sem_getvalue (&sem, &semval) != 0)
|
||||
+ {
|
||||
+ printf ("sem_getvalue failed: %m\n");
|
||||
+ ret = (void *) 1;
|
||||
+ }
|
||||
+ else if (semval != 12345)
|
||||
+ {
|
||||
+ printf ("sem_getvalue returned %d not 12345\n", semval);
|
||||
+ ret = (void *) 1;
|
||||
+ }
|
||||
+ xpthread_mutex_unlock (&lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+stop_and_join_threads (struct conf *conf, cpu_set_t *set,
|
||||
+ pthread_t *pinned_first, pthread_t *pinned_last)
|
||||
+{
|
||||
+ int failed = 0;
|
||||
+ for (pthread_t *p = pinned_first; p < pinned_last; ++p)
|
||||
+ {
|
||||
+ int cpu = p - pinned_first;
|
||||
+ if (!CPU_ISSET_S (cpu, CPU_ALLOC_SIZE (conf->set_size), set))
|
||||
+ continue;
|
||||
+
|
||||
+ void *retval = (void *) 1;
|
||||
+ int ret = pthread_join (*p, &retval);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("error: Failed to join thread %d: %s\n", cpu, strerror (ret));
|
||||
+ fflush (stdout);
|
||||
+ /* Cannot shut down cleanly with threads still running. */
|
||||
+ abort ();
|
||||
+ }
|
||||
+ if (retval != NULL)
|
||||
+ failed = 1;
|
||||
+ }
|
||||
+ return failed;
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+early_test (struct conf *conf)
|
||||
+{
|
||||
+ int ret;
|
||||
+ ret = sem_init (&sem, 0, 12345);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("error: sem_init failed: %m\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+ xpthread_mutex_lock (&lock);
|
||||
+ pthread_t *pinned_threads
|
||||
+ = calloc (conf->last_cpu + 1, sizeof (*pinned_threads));
|
||||
+ cpu_set_t *initial_set = CPU_ALLOC (conf->set_size);
|
||||
+ cpu_set_t *scratch_set = CPU_ALLOC (conf->set_size);
|
||||
+
|
||||
+ if (pinned_threads == NULL || initial_set == NULL || scratch_set == NULL)
|
||||
+ {
|
||||
+ puts ("error: Memory allocation failure");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (getaffinity (CPU_ALLOC_SIZE (conf->set_size), initial_set) < 0)
|
||||
+ {
|
||||
+ printf ("error: pthread_getaffinity_np failed: %m\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ pthread_attr_t attr;
|
||||
+ ret = pthread_attr_init (&attr);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("error: pthread_attr_init failed: %s\n", strerror (ret));
|
||||
+ return false;
|
||||
+ }
|
||||
+ support_set_small_thread_stack_size (&attr);
|
||||
+
|
||||
+ /* Spawn a thread pinned to each available CPU. */
|
||||
+ for (int cpu = 0; cpu <= conf->last_cpu; ++cpu)
|
||||
+ {
|
||||
+ if (!CPU_ISSET_S (cpu, CPU_ALLOC_SIZE (conf->set_size), initial_set))
|
||||
+ continue;
|
||||
+ CPU_ZERO_S (CPU_ALLOC_SIZE (conf->set_size), scratch_set);
|
||||
+ CPU_SET_S (cpu, CPU_ALLOC_SIZE (conf->set_size), scratch_set);
|
||||
+ ret = pthread_attr_setaffinity_np
|
||||
+ (&attr, CPU_ALLOC_SIZE (conf->set_size), scratch_set);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("error: pthread_attr_setaffinity_np for CPU %d failed: %s\n",
|
||||
+ cpu, strerror (ret));
|
||||
+ stop_and_join_threads (conf, initial_set,
|
||||
+ pinned_threads, pinned_threads + cpu);
|
||||
+ return false;
|
||||
+ }
|
||||
+ ret = pthread_create (pinned_threads + cpu, &attr,
|
||||
+ tf, (void *) (uintptr_t) cpu);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("error: pthread_create for CPU %d failed: %s\n",
|
||||
+ cpu, strerror (ret));
|
||||
+ stop_and_join_threads (conf, initial_set,
|
||||
+ pinned_threads, pinned_threads + cpu);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Main thread. */
|
||||
+ xpthread_mutex_unlock (&lock);
|
||||
+ int failed = stop_and_join_threads (conf, initial_set,
|
||||
+ pinned_threads,
|
||||
+ pinned_threads + conf->last_cpu + 1);
|
||||
+
|
||||
+ printf ("info: Main thread ran on %d CPU(s) of %d available CPU(s)\n",
|
||||
+ CPU_COUNT_S (CPU_ALLOC_SIZE (conf->set_size), scratch_set),
|
||||
+ CPU_COUNT_S (CPU_ALLOC_SIZE (conf->set_size), initial_set));
|
||||
+
|
||||
+ pthread_attr_destroy (&attr);
|
||||
+ CPU_FREE (scratch_set);
|
||||
+ CPU_FREE (initial_set);
|
||||
+ free (pinned_threads);
|
||||
+ return failed == 0;
|
||||
+}
|
65
glibc-RHEL-106562-16.patch
Normal file
65
glibc-RHEL-106562-16.patch
Normal file
@ -0,0 +1,65 @@
|
||||
commit 4b7cfcc3fbfab55a1bbb32a2da69c048060739d6
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 25 17:32:54 2024 +0100
|
||||
|
||||
debug: Wire up tst-longjmp_chk3
|
||||
|
||||
The test was added in commit ac8cc9e300a002228eb7e660df3e7b333d9a7414
|
||||
without all the required Makefile scaffolding. Tweak the test
|
||||
so that it actually builds (including with dynamic SIGSTKSZ).
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/debug/Makefile b/debug/Makefile
|
||||
index 3903cc97a3706354..76c311d2845df9c1 100644
|
||||
--- a/debug/Makefile
|
||||
+++ b/debug/Makefile
|
||||
@@ -287,6 +287,7 @@ tests = \
|
||||
tst-fortify-wide \
|
||||
tst-longjmp_chk \
|
||||
tst-longjmp_chk2 \
|
||||
+ tst-longjmp_chk3 \
|
||||
tst-realpath-chk \
|
||||
tst-sprintf-fortify-rdonly \
|
||||
tst-sprintf-fortify-unchecked \
|
||||
diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c
|
||||
index 9ff99772075926ce..7bf1646b354fd2fe 100644
|
||||
--- a/debug/tst-longjmp_chk3.c
|
||||
+++ b/debug/tst-longjmp_chk3.c
|
||||
@@ -18,9 +18,12 @@
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
+#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
-static char buf[SIGSTKSZ * 4];
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static char *buf;
|
||||
static jmp_buf jb;
|
||||
|
||||
static void
|
||||
@@ -49,8 +52,10 @@ do_test (void)
|
||||
set_fortify_handler (handler);
|
||||
|
||||
/* Create a valid signal stack and enable it. */
|
||||
+ size_t bufsize = SIGSTKSZ * 4;
|
||||
+ buf = xmalloc (bufsize);
|
||||
ss.ss_sp = buf;
|
||||
- ss.ss_size = sizeof (buf);
|
||||
+ ss.ss_size = bufsize;
|
||||
ss.ss_flags = 0;
|
||||
if (sigaltstack (&ss, NULL) < 0)
|
||||
{
|
||||
@@ -65,8 +70,8 @@ do_test (void)
|
||||
|
||||
/* Shrink the signal stack so the jmpbuf is now invalid.
|
||||
We adjust the start & end to handle stacks that grow up & down. */
|
||||
- ss.ss_sp = buf + sizeof (buf) / 2;
|
||||
- ss.ss_size = sizeof (buf) / 4;
|
||||
+ ss.ss_sp = buf + bufsize / 2;
|
||||
+ ss.ss_size = bufsize / 4;
|
||||
if (sigaltstack (&ss, NULL) < 0)
|
||||
{
|
||||
printf ("second sigaltstack failed: %m\n");
|
20
glibc-RHEL-106562-17.patch
Normal file
20
glibc-RHEL-106562-17.patch
Normal file
@ -0,0 +1,20 @@
|
||||
commit 4836a9af89f1b4d482e6c72ff67e36226d36434c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Nov 26 19:26:13 2024 +0100
|
||||
|
||||
debug: Fix tst-longjmp_chk3 build failure on Hurd
|
||||
|
||||
Explicitly include <unistd.h> for _exit and getpid.
|
||||
|
||||
diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c
|
||||
index 7bf1646b354fd2fe..9b9db3b9e9e37d54 100644
|
||||
--- a/debug/tst-longjmp_chk3.c
|
||||
+++ b/debug/tst-longjmp_chk3.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#include <support/support.h>
|
||||
|
111
glibc-RHEL-106562-18.patch
Normal file
111
glibc-RHEL-106562-18.patch
Normal file
@ -0,0 +1,111 @@
|
||||
commit bde47662b74b883149c3001e2c052dea5d3cd92f
|
||||
Author: Sergey Kolosov <skolosov@redhat.com>
|
||||
Date: Wed Nov 6 15:24:06 2024 +0100
|
||||
|
||||
nptl: Add new test for pthread_spin_trylock
|
||||
|
||||
Add a threaded test for pthread_spin_trylock attempting to lock already
|
||||
acquired spin lock and checking for correct return code.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||
index 04ea56559ef3a79b..8c80b7a606da4c94 100644
|
||||
--- a/sysdeps/pthread/Makefile
|
||||
+++ b/sysdeps/pthread/Makefile
|
||||
@@ -265,6 +265,7 @@ tests += \
|
||||
tst-spin2 \
|
||||
tst-spin3 \
|
||||
tst-spin4 \
|
||||
+ tst-spin5 \
|
||||
tst-stack1 \
|
||||
tst-stdio1 \
|
||||
tst-stdio2 \
|
||||
diff --git a/sysdeps/pthread/tst-spin5.c b/sysdeps/pthread/tst-spin5.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5c23bd48ef27b3ce
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/pthread/tst-spin5.c
|
||||
@@ -0,0 +1,82 @@
|
||||
+/* Threaded test the pthread_spin_trylock 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 <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+pthread_spinlock_t lock;
|
||||
+
|
||||
+void *
|
||||
+thread (void *arg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int thr_id = *(int *) arg;
|
||||
+
|
||||
+ ret = pthread_spin_trylock (&lock);
|
||||
+ if (thr_id == 1)
|
||||
+ /* thread with already acquired lock. */
|
||||
+ {
|
||||
+ if (ret != EBUSY)
|
||||
+ {
|
||||
+ FAIL_EXIT1 ("pthread_spin_trylock should fail with EBUSY");
|
||||
+ }
|
||||
+ }
|
||||
+ else if (thr_id == 2)
|
||||
+ /* thread with released spin lock. */
|
||||
+ {
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ FAIL_EXIT1 ("pthread_spin_trylock should be able to acquire lock");
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ pthread_t thr1, thr2;
|
||||
+ int ret;
|
||||
+ int thr1_id = 1, thr2_id = 2;
|
||||
+
|
||||
+ pthread_spin_init (&lock, PTHREAD_PROCESS_PRIVATE);
|
||||
+ /* lock spin in main thread. */
|
||||
+ ret = pthread_spin_trylock (&lock);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ FAIL_EXIT1 ("Main thread should be able to acquire spin lock");
|
||||
+ }
|
||||
+
|
||||
+ /* create first thread to try locking already acquired spin lock. */
|
||||
+ thr1 = xpthread_create (NULL, thread, &thr1_id);
|
||||
+ xpthread_join (thr1);
|
||||
+
|
||||
+ /* release spin lock and create thread to acquire released spin lock. */
|
||||
+ pthread_spin_unlock (&lock);
|
||||
+ thr2 = xpthread_create (NULL, thread, &thr2_id);
|
||||
+ xpthread_join (thr2);
|
||||
+
|
||||
+ pthread_spin_destroy (&lock);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
575
glibc-RHEL-106562-19.patch
Normal file
575
glibc-RHEL-106562-19.patch
Normal file
@ -0,0 +1,575 @@
|
||||
commit 45c42b65c29422b773ac94771aa71165e245f8f8
|
||||
Author: Martin Coufal <mcoufal@redhat.com>
|
||||
Date: Thu Jan 23 13:04:06 2025 +0100
|
||||
|
||||
Add new tests for fopen
|
||||
|
||||
Adding some basic tests for fopen, testing different modes, stream
|
||||
positioning and concurrent read/write operation on files.
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||
index 6b52fd3e0d818960..f44562df75cb98bc 100644
|
||||
--- a/stdio-common/Makefile
|
||||
+++ b/stdio-common/Makefile
|
||||
@@ -215,6 +215,7 @@ tests := \
|
||||
tst-fmemopen2 \
|
||||
tst-fmemopen3 \
|
||||
tst-fmemopen4 \
|
||||
+ tst-fopen \
|
||||
tst-fphex \
|
||||
tst-fphex-wide \
|
||||
tst-fread \
|
||||
diff --git a/stdio-common/tst-fopen.c b/stdio-common/tst-fopen.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8c1fefd116f9f581
|
||||
--- /dev/null
|
||||
+++ b/stdio-common/tst-fopen.c
|
||||
@@ -0,0 +1,279 @@
|
||||
+/* Basic test for fopen.
|
||||
+ Copyright (C) 2025 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 <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+#define APPENDED_TEXT "This is appended text. "
|
||||
+#define DEFAULT_TEXT "Lorem ipsum dolor sit amet, consectetur " \
|
||||
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et " \
|
||||
+ "dolore magna aliqua."
|
||||
+#define MAX_BUFFER_SIZE 300
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *temp_file;
|
||||
+ FILE *fd_file = NULL;
|
||||
+ char read_buffer[MAX_BUFFER_SIZE] = "";
|
||||
+ size_t ret;
|
||||
+
|
||||
+ /* Prepare files. */
|
||||
+ int fd = create_temp_file ("tst-fopen.", &temp_file);
|
||||
+ TEST_VERIFY_EXIT (fd != -1);
|
||||
+ fd_file = fdopen (fd, "w");
|
||||
+ ret = fwrite (DEFAULT_TEXT, sizeof (char), strlen (DEFAULT_TEXT), fd_file);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ xfclose (fd_file);
|
||||
+
|
||||
+ /* Test 1: This checks for fopen with mode "r". Open text file for
|
||||
+ reading. The stream is positioned at the beginning of the file. */
|
||||
+ printf ("Test 1: This checks for fopen with mode \"r\".\n");
|
||||
+ fd_file = fopen (temp_file, "r");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+ /* Read should succeed. */
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ TEST_VERIFY (strcmp (read_buffer, DEFAULT_TEXT) == 0);
|
||||
+ /* Write should fail. */
|
||||
+ errno = 0;
|
||||
+ ret = fwrite (DEFAULT_TEXT, sizeof (char), strlen (DEFAULT_TEXT), fd_file);
|
||||
+ TEST_VERIFY (ferror (fd_file) != 0);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ clearerr (fd_file);
|
||||
+ /* Opening non-existent file should fail. */
|
||||
+ xfclose (fd_file);
|
||||
+ errno = 0;
|
||||
+ fd_file = fopen ("file-that-does-not-exist", "r");
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+ TEST_COMPARE (errno, ENOENT);
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 2: This checks for fopen with mode "r+". Open for reading and
|
||||
+ writing. The stream is positioned at the beginning of the file. */
|
||||
+ printf ("Test 2: This checks for fopen with mode \"r+\".\n");
|
||||
+ fd_file = fopen (temp_file, "r+");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+ /* Read should succeed. */
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ TEST_VERIFY (strcmp (read_buffer, DEFAULT_TEXT) == 0);
|
||||
+ fflush (fd_file);
|
||||
+ /* File position indicator expected at 0 + read bytes. */
|
||||
+ TEST_COMPARE (ftell (fd_file), ret);
|
||||
+ /* Write should succeed. */
|
||||
+ ret = fwrite (DEFAULT_TEXT, sizeof (char), strlen (DEFAULT_TEXT), fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ /* Opening non-existent file should fail. */
|
||||
+ xfclose (fd_file);
|
||||
+ errno = 0;
|
||||
+ fd_file = fopen ("file-that-does-not-exist", "r+");
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+ TEST_COMPARE (errno, ENOENT);
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 3: This checks for fopen with mode "w". Truncate file to zero
|
||||
+ length or create text file for writing. The stream is positioned
|
||||
+ at the beginning of the file. */
|
||||
+ printf ("Test 3: This checks for fopen with mode \"w\".\n");
|
||||
+ fd_file = fopen (temp_file, "w");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+ /* Read should fail. */
|
||||
+ errno = 0;
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_VERIFY (ferror (fd_file) != 0);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ clearerr (fd_file);
|
||||
+ /* Write should succeed. */
|
||||
+ ret = fwrite (DEFAULT_TEXT, sizeof (char), strlen (DEFAULT_TEXT), fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ /* Opening non-existent file should succeed. */
|
||||
+ xfclose (fd_file);
|
||||
+ fd_file = fopen ("/tmp/file-that-does-not-exist", "w");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+
|
||||
+ xfclose (fd_file);
|
||||
+ remove ("/tmp/file-that-does-not-exist");
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 4: This checks for fopen with mode "w+". Open for reading and
|
||||
+ writing. The file is created if it does not exist, otherwise it is
|
||||
+ truncated. The stream is positioned at the beginning of the file.
|
||||
+ */
|
||||
+ printf ("Test 4: This checks for fopen with mode \"w+\".\n");
|
||||
+ fd_file = fopen (temp_file, "w+");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+ /* Read should succeed. */
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ TEST_VERIFY (read_buffer[0] == '\0');
|
||||
+ /* Write should succeed. */
|
||||
+ ret = fwrite (DEFAULT_TEXT, sizeof (char), strlen (DEFAULT_TEXT), fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT));
|
||||
+ /* Opening non-existent file should succeed. */
|
||||
+ xfclose (fd_file);
|
||||
+ fd_file = fopen ("/tmp/file-that-does-not-exist", "w+");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+
|
||||
+ xfclose (fd_file);
|
||||
+ remove ("/tmp/file-that-does-not-exist");
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 5: This checks for fopen with mode "a". Open for appending
|
||||
+ (writing at end of file). The file is created if it does not
|
||||
+ exist. The stream is positioned at the end of the file. */
|
||||
+ printf ("Test 5: This checks for fopen with mode \"a\".\n");
|
||||
+ fd_file = fopen (temp_file, "a");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), strlen (DEFAULT_TEXT));
|
||||
+ /* Read should fail. */
|
||||
+ errno = 0;
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_VERIFY (ferror (fd_file) != 0);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ clearerr (fd_file);
|
||||
+ /* Write should succeed. */
|
||||
+ ret = fwrite (APPENDED_TEXT, sizeof (char), strlen (APPENDED_TEXT), fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (APPENDED_TEXT));
|
||||
+ /* The file position indicator for the stream is advanced by the
|
||||
+ * number of bytes successfully read or written. */
|
||||
+ TEST_COMPARE (ftell (fd_file), strlen (DEFAULT_TEXT) + ret);
|
||||
+ /* Opening non-existent file should succeed. */
|
||||
+ xfclose (fd_file);
|
||||
+ fd_file = fopen ("/tmp/file-that-does-not-exist", "a");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+
|
||||
+ xfclose (fd_file);
|
||||
+ remove ("/tmp/file-that-does-not-exist");
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 6: This checks for fopen with mode "a+". Open for reading and
|
||||
+ appending (writing at end of file). The file is created if it does
|
||||
+ not exist. Output is always appended to the end of the file. The
|
||||
+ initial file position for reading is at the beginning of the file,
|
||||
+ but it is advanced to the end prior to each write. */
|
||||
+ printf ("Test 6: This checks for fopen with mode \"a+\".\n");
|
||||
+ errno = 0;
|
||||
+ fd_file = fopen (temp_file, "a+");
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+ /* Read should succeed. */
|
||||
+ ret = fread (read_buffer, sizeof (char), MAX_BUFFER_SIZE, fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (DEFAULT_TEXT) + strlen (APPENDED_TEXT));
|
||||
+ TEST_VERIFY (strcmp (read_buffer, DEFAULT_TEXT APPENDED_TEXT) == 0);
|
||||
+ /* Write should succeed. */
|
||||
+ const char* SECOND_APPEND = "This is second append.";
|
||||
+ ret = fwrite (SECOND_APPEND, sizeof (char), strlen (SECOND_APPEND), fd_file);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_COMPARE (ret, strlen (SECOND_APPEND));
|
||||
+ /* The file position indicator for the stream is advanced by the
|
||||
+ number of bytes successfully read or written. */
|
||||
+ TEST_COMPARE (ftell (fd_file),
|
||||
+ strlen (DEFAULT_TEXT) + strlen (APPENDED_TEXT) + ret);
|
||||
+ /* Opening non-existent file should succeed. */
|
||||
+ xfclose (fd_file);
|
||||
+ fd_file = fopen ("/tmp/file-that-does-not-exist", "a+");
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ TEST_COMPARE (ftell (fd_file), 0);
|
||||
+
|
||||
+ xfclose (fd_file);
|
||||
+ remove ("/tmp/file-that-does-not-exist");
|
||||
+ memset (read_buffer, 0, MAX_BUFFER_SIZE);
|
||||
+
|
||||
+ /* Test 7: This checks for fopen with other valid modes set, such as
|
||||
+ "rc", "we" or "am". The test calls fopen with these modes and
|
||||
+ checks that no errors appear. */
|
||||
+ printf ("Test 7: This checks for fopen with other valid modes set, "
|
||||
+ "such as \"rc\", \"we\" or \"am\".\n");
|
||||
+ /* These modes all operate correctly with the file already present. */
|
||||
+ static const char *valid_modes[] =
|
||||
+ { "rc", "we", "am", "r+x", "wb+", "ab", 0 };
|
||||
+ const char **p = valid_modes;
|
||||
+ while (*p != 0)
|
||||
+ {
|
||||
+ fd_file = fopen (temp_file, *p);
|
||||
+ TEST_COMPARE (ferror (fd_file), 0);
|
||||
+ TEST_VERIFY (fd_file != NULL);
|
||||
+ xfclose (fd_file);
|
||||
+ ++p;
|
||||
+ }
|
||||
+
|
||||
+ /* Test 8: This checks for fopen with invalid modes. The test calls
|
||||
+ fopen with these modes and checks that opening existing files with
|
||||
+ invalid mode fails and that opening non-existing files with invalid
|
||||
+ mode doesn't create a new file. */
|
||||
+ printf ("Test 8: This checks for fopen with invalid modes.\n");
|
||||
+ static const char *invalid_modes[] = { "0", "tr", "z", "x", " ", 0 };
|
||||
+ p = invalid_modes;
|
||||
+ while (*p != 0)
|
||||
+ {
|
||||
+ errno = 0;
|
||||
+ fd_file = fopen (temp_file, *p);
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+ TEST_COMPARE (errno, EINVAL);
|
||||
+ errno = 0;
|
||||
+ fd_file = fopen ("/tmp/file-that-does-not-exist", *p);
|
||||
+ TEST_VERIFY (fd_file == NULL);
|
||||
+ TEST_COMPARE (errno, EINVAL);
|
||||
+ ++p;
|
||||
+ TEST_VERIFY (access ("/tmp/file-that-does-not-exist", F_OK) == -1);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||
index 8c80b7a606da4c94..ef3035cea8e1344b 100644
|
||||
--- a/sysdeps/pthread/Makefile
|
||||
+++ b/sysdeps/pthread/Makefile
|
||||
@@ -154,6 +154,7 @@ tests += \
|
||||
tst-exit3 \
|
||||
tst-flock1 \
|
||||
tst-flock2 \
|
||||
+ tst-fopen-threaded \
|
||||
tst-fork1 \
|
||||
tst-fork2 \
|
||||
tst-fork3 \
|
||||
diff --git a/sysdeps/pthread/tst-fopen-threaded.c b/sysdeps/pthread/tst-fopen-threaded.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5c792c93e3711621
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/pthread/tst-fopen-threaded.c
|
||||
@@ -0,0 +1,250 @@
|
||||
+/* Test for fread and fwrite with multiple threads.
|
||||
+ Copyright (C) 2025 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/>. */
|
||||
+
|
||||
+/* Description of test intent.
|
||||
+ The test creates NUM_THREADS threads for reading and writing to the
|
||||
+ prepared file. The prepared file contains 'NUM_THREADS - 1' bytes
|
||||
+ where each byte is unique number from 0 to 'NUM_THREADS - 2'. If all
|
||||
+ operations are correctly multi-threaded safe then all concurent read
|
||||
+ operations should succeed and read a unique 1 byte value. The last
|
||||
+ thread to read should get an EOF. In concurrent write, all write
|
||||
+ operations should succeed and the file should contain all unique 1
|
||||
+ byte values from 0 to 'NUM_THREADS - 1'. Both concurrent read and
|
||||
+ concurrent write tests are repeated ITERS times to increase
|
||||
+ the probability of detecting concurrency issues. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <pthread.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+#define NUM_THREADS 100
|
||||
+#define ITERS 10
|
||||
+
|
||||
+char *temp_file;
|
||||
+pthread_barrier_t barrier;
|
||||
+
|
||||
+struct thread_data
|
||||
+{
|
||||
+ FILE *fd;
|
||||
+ /* Read value or value to be written. */
|
||||
+ unsigned char value;
|
||||
+ bool eof;
|
||||
+};
|
||||
+
|
||||
+static void *
|
||||
+threadReadRoutine (void *argv)
|
||||
+{
|
||||
+ struct thread_data *my_data;
|
||||
+ unsigned char read_buffer;
|
||||
+ int ret = 0;
|
||||
+ my_data = (struct thread_data *) argv;
|
||||
+ /* Wait for all threads to be ready to read. */
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ ret =
|
||||
+ fread (&read_buffer, sizeof (char), sizeof (read_buffer), my_data->fd);
|
||||
+ if (feof (my_data->fd) != 0)
|
||||
+ {
|
||||
+ clearerr (my_data->fd);
|
||||
+ my_data->eof = true;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, 1);
|
||||
+ /* Save the read value. */
|
||||
+ my_data->value = read_buffer;
|
||||
+ }
|
||||
+ TEST_COMPARE (ferror (my_data->fd), 0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+threadWriteRoutine (void *argv)
|
||||
+{
|
||||
+ struct thread_data *my_data;
|
||||
+ int ret = 0;
|
||||
+ my_data = (struct thread_data *) argv;
|
||||
+ /* Wait for all threads to be ready to write. */
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ ret = fwrite (&my_data->value, sizeof (unsigned char), 1, my_data->fd);
|
||||
+ TEST_COMPARE (ferror (my_data->fd), 0);
|
||||
+ TEST_COMPARE (feof (my_data->fd), 0);
|
||||
+ TEST_COMPARE (ret, 1);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+threadOpenCloseRoutine (void *argv)
|
||||
+{
|
||||
+ /* Wait for all threads to be ready to call fopen and fclose. */
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ FILE *fd = xfopen ("/tmp/openclosetest", "w+");
|
||||
+ xfclose (fd);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ FILE *fd_file = NULL;
|
||||
+ unsigned char buffer[NUM_THREADS] = "0";
|
||||
+ size_t ret = 0;
|
||||
+ pthread_t threads[NUM_THREADS];
|
||||
+ struct thread_data thread_data_array[NUM_THREADS];
|
||||
+ bool present_values[NUM_THREADS] = { false };
|
||||
+
|
||||
+ /* Prepare files. */
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ buffer[i] = i;
|
||||
+ int fd = create_temp_file ("tst-fopen.", &temp_file);
|
||||
+ TEST_VERIFY_EXIT (fd != -1);
|
||||
+ fd_file = fdopen (fd, "w");
|
||||
+ /* NUM_THREADS - 1: last thread will read EOF */
|
||||
+ ret = fwrite (buffer, sizeof (unsigned char), NUM_THREADS - 1, fd_file);
|
||||
+ TEST_COMPARE (ret, NUM_THREADS - 1);
|
||||
+ xfclose (fd_file);
|
||||
+
|
||||
+ /* Test 1: Concurrent read. */
|
||||
+ for (int reps = 1; reps <= ITERS; reps++)
|
||||
+ {
|
||||
+ fd_file = xfopen (temp_file, "r");
|
||||
+ xpthread_barrier_init (&barrier, NULL, NUM_THREADS);
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ thread_data_array[i].fd = fd_file;
|
||||
+ /* Initialize with highest possible value so it's easier to debug if
|
||||
+ anything goes wrong. */
|
||||
+ thread_data_array[i].value = 255;
|
||||
+ thread_data_array[i].eof = false;
|
||||
+
|
||||
+ threads[i] =
|
||||
+ xpthread_create (support_small_stack_thread_attribute (),
|
||||
+ threadReadRoutine,
|
||||
+ (void *) &thread_data_array[i]);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ xpthread_join (threads[i]);
|
||||
+ }
|
||||
+ xpthread_barrier_destroy (&barrier);
|
||||
+ xfclose (fd_file);
|
||||
+
|
||||
+ /* Verify read values. */
|
||||
+ int eof_cnt = 0;
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ present_values[i] = false;
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ if (thread_data_array[i].eof)
|
||||
+ {
|
||||
+ /* EOF was read. */
|
||||
+ present_values[NUM_THREADS - 1] = true;
|
||||
+ eof_cnt++;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* The same value shouldn't be read twice. */
|
||||
+ TEST_VERIFY (!present_values[thread_data_array[i].value]);
|
||||
+ present_values[thread_data_array[i].value] = true;
|
||||
+ }
|
||||
+ }
|
||||
+ /* EOF is read exactly once. */
|
||||
+ TEST_COMPARE (eof_cnt, 1);
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ /* All values should be read. */
|
||||
+ TEST_VERIFY (present_values[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Test 2: Concurrent write. */
|
||||
+ for (int reps = 1; reps <= ITERS; reps++)
|
||||
+ {
|
||||
+ fd_file = xfopen (temp_file, "w");
|
||||
+ xpthread_barrier_init (&barrier, NULL, NUM_THREADS);
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ thread_data_array[i].fd = fd_file;
|
||||
+ thread_data_array[i].value = i;
|
||||
+
|
||||
+ threads[i] =
|
||||
+ xpthread_create (support_small_stack_thread_attribute (),
|
||||
+ threadWriteRoutine,
|
||||
+ (void *) &thread_data_array[i]);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ xpthread_join (threads[i]);
|
||||
+ }
|
||||
+ xpthread_barrier_destroy (&barrier);
|
||||
+ xfclose (fd_file);
|
||||
+
|
||||
+ /* Verify written values. */
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ present_values[i] = false;
|
||||
+ memset (buffer, 0, NUM_THREADS);
|
||||
+ fd_file = xfopen (temp_file, "r");
|
||||
+ ret = fread (buffer, sizeof (unsigned char), NUM_THREADS, fd_file);
|
||||
+ TEST_COMPARE (ret, NUM_THREADS);
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ /* The same value shouldn't be written twice. */
|
||||
+ TEST_VERIFY (!present_values[buffer[i]]);
|
||||
+ present_values[buffer[i]] = true;
|
||||
+ }
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ /* All values should be written. */
|
||||
+ TEST_VERIFY (present_values[i]);
|
||||
+ }
|
||||
+ xfclose (fd_file);
|
||||
+ }
|
||||
+
|
||||
+ /* Test 3: Concurrent open/close. */
|
||||
+ for (int reps = 1; reps <= ITERS; reps++)
|
||||
+ {
|
||||
+ xpthread_barrier_init (&barrier, NULL, NUM_THREADS);
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ threads[i] =
|
||||
+ xpthread_create (support_small_stack_thread_attribute (),
|
||||
+ threadOpenCloseRoutine, NULL);
|
||||
+ }
|
||||
+ for (int i = 0; i < NUM_THREADS; i++)
|
||||
+ {
|
||||
+ xpthread_join (threads[i]);
|
||||
+ }
|
||||
+ xpthread_barrier_destroy (&barrier);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
529
glibc-RHEL-106562-2.patch
Normal file
529
glibc-RHEL-106562-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 3356f9b10d7f364e..dfb56e8cde13519a 100644
|
||||
--- a/math/libm-test-driver.c
|
||||
+++ b/math/libm-test-driver.c
|
||||
@@ -1083,9 +1083,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 0cae545f86ac1352..0796f9d4956e3818 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 8baf7e1817157b2a..efb9523e9e91f64f 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);
|
151
glibc-RHEL-106562-20.patch
Normal file
151
glibc-RHEL-106562-20.patch
Normal file
@ -0,0 +1,151 @@
|
||||
commit a9017caff3b77032d04e2e439f7c04a63241e63e
|
||||
Author: Sergey Kolosov <skolosov@redhat.com>
|
||||
Date: Tue Jan 28 23:56:26 2025 +0100
|
||||
|
||||
nptl: extend test coverage for sched_yield
|
||||
|
||||
We add sched_yield() API testing to the existing thread affinity
|
||||
test case because it allows us to test sched_yield() operation
|
||||
in the following scenarios:
|
||||
|
||||
* On a main thread.
|
||||
* On multiple threads simultaneously.
|
||||
* On every CPU the system reports simultaneously.
|
||||
|
||||
The ensures we exercise sched_yield() in as many scenarios as
|
||||
we would exercise calls to the affinity functions.
|
||||
|
||||
Additionally, the test is improved by adding a semaphore to coordinate
|
||||
all the threads running, so that an early starter thread won't consume
|
||||
cpu resources that could be used to start the other threads.
|
||||
|
||||
Co-authored-by: DJ Delorie <dj@redhat.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
index 2f921ed397a1a4d9..7276fd8fef06d620 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
+#include <support/test-driver.h>
|
||||
|
||||
/* CPU set configuration determined. Can be used from early_test. */
|
||||
struct conf
|
||||
@@ -253,12 +254,12 @@ do_test (void)
|
||||
if (getaffinity (sizeof (set), &set) < 0 && errno == ENOSYS)
|
||||
{
|
||||
puts ("warning: getaffinity not supported, test cannot run");
|
||||
- return 0;
|
||||
+ return EXIT_UNSUPPORTED;
|
||||
}
|
||||
if (sched_getcpu () < 0 && errno == ENOSYS)
|
||||
{
|
||||
puts ("warning: sched_getcpu not supported, test cannot run");
|
||||
- return 0;
|
||||
+ return EXIT_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-skeleton-thread-affinity.c b/sysdeps/unix/sysv/linux/tst-skeleton-thread-affinity.c
|
||||
index 5a1e84431a30132d..507c5c94ba89e47b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-skeleton-thread-affinity.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-skeleton-thread-affinity.c
|
||||
@@ -45,10 +45,14 @@ static int still_running;
|
||||
/* 0 if no scheduling failures, 1 if failures are encountered. */
|
||||
static int failed;
|
||||
|
||||
+/* Used to synchronize the threads. */
|
||||
+static pthread_barrier_t barrier;
|
||||
+
|
||||
static void *
|
||||
thread_burn_one_cpu (void *closure)
|
||||
{
|
||||
int cpu = (uintptr_t) closure;
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
while (__atomic_load_n (&still_running, __ATOMIC_RELAXED) == 0)
|
||||
{
|
||||
int current = sched_getcpu ();
|
||||
@@ -61,6 +65,11 @@ thread_burn_one_cpu (void *closure)
|
||||
__atomic_store_n (&still_running, 1, __ATOMIC_RELAXED);
|
||||
}
|
||||
}
|
||||
+ if (sched_yield () != 0)
|
||||
+ {
|
||||
+ printf ("error: sched_yield() failed for cpu %d\n", cpu);
|
||||
+ __atomic_store_n (&failed, 1, __ATOMIC_RELAXED);
|
||||
+ }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -78,6 +87,7 @@ thread_burn_any_cpu (void *closure)
|
||||
{
|
||||
struct burn_thread *param = closure;
|
||||
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
/* Schedule this thread around a bit to see if it lands on another
|
||||
CPU. Run this for 2 seconds, once with sched_yield, once
|
||||
without. */
|
||||
@@ -99,7 +109,11 @@ thread_burn_any_cpu (void *closure)
|
||||
CPU_SET_S (cpu, CPU_ALLOC_SIZE (param->conf->set_size),
|
||||
param->seen_set);
|
||||
if (pass == 1)
|
||||
- sched_yield ();
|
||||
+ if (sched_yield () != 0)
|
||||
+ {
|
||||
+ printf ("error: sched_yield() failed for cpu %d\n", cpu);
|
||||
+ __atomic_store_n (&failed, 1, __ATOMIC_RELAXED);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -156,6 +170,7 @@ early_test (struct conf *conf)
|
||||
= calloc (conf->last_cpu + 1, sizeof (*other_threads));
|
||||
cpu_set_t *initial_set = CPU_ALLOC (conf->set_size);
|
||||
cpu_set_t *scratch_set = CPU_ALLOC (conf->set_size);
|
||||
+ int num_available_cpus = 0;
|
||||
|
||||
if (pinned_threads == NULL || other_threads == NULL
|
||||
|| initial_set == NULL || scratch_set == NULL)
|
||||
@@ -172,6 +187,7 @@ early_test (struct conf *conf)
|
||||
{
|
||||
if (!CPU_ISSET_S (cpu, CPU_ALLOC_SIZE (conf->set_size), initial_set))
|
||||
continue;
|
||||
+ num_available_cpus ++;
|
||||
other_threads[cpu].conf = conf;
|
||||
other_threads[cpu].initial_set = initial_set;
|
||||
other_threads[cpu].thread = cpu;
|
||||
@@ -194,6 +210,15 @@ early_test (struct conf *conf)
|
||||
}
|
||||
support_set_small_thread_stack_size (&attr);
|
||||
|
||||
+ /* This count assumes that all the threads below are created
|
||||
+ successfully, and call pthread_barrier_wait(). If any threads
|
||||
+ fail to be created, this function will return FALSE (failure) and
|
||||
+ the waiting threads will eventually time out the whole test.
|
||||
+ This is acceptable because we're not testing thread creation and
|
||||
+ assume all threads will be created, and failure here implies a
|
||||
+ failure outside the test's scope. */
|
||||
+ xpthread_barrier_init (&barrier, NULL, num_available_cpus * 2 + 1);
|
||||
+
|
||||
/* Spawn a thread pinned to each available CPU. */
|
||||
for (int cpu = 0; cpu <= conf->last_cpu; ++cpu)
|
||||
{
|
||||
@@ -245,6 +270,15 @@ early_test (struct conf *conf)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Test that sched_yield() works correctly in the main thread. This
|
||||
+ also gives the kernel an opportunity to run the other threads,
|
||||
+ randomizing thread startup a bit. */
|
||||
+ if (sched_yield () != 0)
|
||||
+ {
|
||||
+ printf ("error: sched_yield() failed for main thread\n");
|
||||
+ __atomic_store_n (&failed, 1, __ATOMIC_RELAXED);
|
||||
+ }
|
||||
+
|
||||
/* Main thread. */
|
||||
struct burn_thread main_thread;
|
||||
main_thread.conf = conf;
|
62
glibc-RHEL-106562-21.patch
Normal file
62
glibc-RHEL-106562-21.patch
Normal file
@ -0,0 +1,62 @@
|
||||
commit 10af00f7a135c85796a9c4c75228358b8898da5c
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Fri Mar 14 10:18:21 2025 -0400
|
||||
|
||||
tst-fopen-threaded: Only check EOF for failing read
|
||||
|
||||
The fread race checker looks for EOF in every thread, which is incorrect
|
||||
since threads calling fread successfully could lag behind and read the
|
||||
EOF condition, resulting in multiple threads thinking that they
|
||||
encountered an EOF.
|
||||
|
||||
Only look for EOF condition if fread fails to read a char. Also drop
|
||||
the clearerr() since it could mask the failure of another reader, thus
|
||||
hiding a test failure.
|
||||
|
||||
Finally, also check for error in the stream for completeness.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/pthread/tst-fopen-threaded.c b/sysdeps/pthread/tst-fopen-threaded.c
|
||||
index 5c792c93e3711621..ade58ad19eb209d1 100644
|
||||
--- a/sysdeps/pthread/tst-fopen-threaded.c
|
||||
+++ b/sysdeps/pthread/tst-fopen-threaded.c
|
||||
@@ -64,19 +64,27 @@ threadReadRoutine (void *argv)
|
||||
/* Wait for all threads to be ready to read. */
|
||||
xpthread_barrier_wait (&barrier);
|
||||
|
||||
- ret =
|
||||
- fread (&read_buffer, sizeof (char), sizeof (read_buffer), my_data->fd);
|
||||
- if (feof (my_data->fd) != 0)
|
||||
+ ret = fread (&read_buffer, 1, sizeof (read_buffer), my_data->fd);
|
||||
+ /* If no data is returned (we read only 1 byte, so there's no short read
|
||||
+ situation here), look for EOF flag and record it in MY_DATA. The EOF flag
|
||||
+ is not cleared because that could result in a test failure being masked
|
||||
+ when two threads fail to read and one of them clears error/EOF flags
|
||||
+ before the second one has the chance to observe it.
|
||||
+
|
||||
+ Successful readers could still see the EOF if they fall behind the failing
|
||||
+ read when calling feof(), which could result in a false test failure. To
|
||||
+ avoid this race, we only make the failing reader check for EOF or
|
||||
+ error. */
|
||||
+ if (ret == 0)
|
||||
{
|
||||
- clearerr (my_data->fd);
|
||||
- my_data->eof = true;
|
||||
+ if (feof (my_data->fd) != 0)
|
||||
+ my_data->eof = true;
|
||||
+ else
|
||||
+ FAIL_EXIT1 ("fread failed (ferror: %d): %m", ferror (my_data->fd));
|
||||
}
|
||||
else
|
||||
- {
|
||||
- TEST_COMPARE (ret, 1);
|
||||
- /* Save the read value. */
|
||||
- my_data->value = read_buffer;
|
||||
- }
|
||||
+ /* Save the read value. */
|
||||
+ my_data->value = read_buffer;
|
||||
TEST_COMPARE (ferror (my_data->fd), 0);
|
||||
return NULL;
|
||||
}
|
121
glibc-RHEL-106562-22.patch
Normal file
121
glibc-RHEL-106562-22.patch
Normal file
@ -0,0 +1,121 @@
|
||||
commit 81e74c8676479811601b5894d72bb3d7e05f68dd
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Fri Mar 14 16:08:12 2025 -0400
|
||||
|
||||
add ptmx support to test-container
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 6e3c55394fa212b6..23ce2ccec89743bb 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -313,6 +313,7 @@ tests = \
|
||||
README-testing \
|
||||
tst-support-namespace \
|
||||
tst-support-open-dev-null-range \
|
||||
+ tst-support-openpty \
|
||||
tst-support-process_state \
|
||||
tst-support_blob_repeat \
|
||||
tst-support_capture_subprocess \
|
||||
@@ -331,6 +332,10 @@ tests = \
|
||||
tst-xsigstack \
|
||||
# tests
|
||||
|
||||
+tests-container = \
|
||||
+ tst-support-openpty-c \
|
||||
+ # tests-container
|
||||
+
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special = \
|
||||
$(objpfx)tst-support_record_failure-2.out
|
||||
diff --git a/support/test-container.c b/support/test-container.c
|
||||
index adf2b30215273936..1696d676fd101d42 100644
|
||||
--- a/support/test-container.c
|
||||
+++ b/support/test-container.c
|
||||
@@ -1148,6 +1148,9 @@ main (int argc, char **argv)
|
||||
devmount (new_root_path, "null");
|
||||
devmount (new_root_path, "zero");
|
||||
devmount (new_root_path, "urandom");
|
||||
+#ifdef __linux__
|
||||
+ devmount (new_root_path, "ptmx");
|
||||
+#endif
|
||||
|
||||
/* We're done with the "old" root, switch to the new one. */
|
||||
if (chroot (new_root_path) < 0)
|
||||
@@ -1214,6 +1217,14 @@ main (int argc, char **argv)
|
||||
|
||||
maybe_xmkdir ("/tmp", 0755);
|
||||
|
||||
+#ifdef __linux__
|
||||
+ maybe_xmkdir ("/dev/pts", 0777);
|
||||
+ if (mount ("/dev/pts", "/dev/pts", "devpts", 0, "newinstance,ptmxmode=0666,mode=0666") < 0)
|
||||
+ FAIL_EXIT1 ("can't mount /dev/pts: %m\n");
|
||||
+ if (mount ("/dev/pts/ptmx", "/dev/ptmx", "", MS_BIND | MS_REC, NULL) < 0)
|
||||
+ FAIL_EXIT1 ("can't mount /dev/ptmx\n");
|
||||
+#endif
|
||||
+
|
||||
if (require_pidns)
|
||||
{
|
||||
/* Now that we're pid 1 (effectively "root") we can mount /proc */
|
||||
diff --git a/support/tst-support-openpty-c.c b/support/tst-support-openpty-c.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0a6a428fc3cd3400
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support-openpty-c.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+/* Same test, but in a test-container. */
|
||||
+#include "tst-support-openpty.c"
|
||||
diff --git a/support/tst-support-openpty.c b/support/tst-support-openpty.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1222d7018f9b224f
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support-openpty.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+/* Basic test for support_openpty support in test-container.
|
||||
+ Copyright (C) 2025 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 <termios.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+
|
||||
+#include <support/tty.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+/* Note: the purpose of this test isn't to test if ptys function
|
||||
+ correctly, but only to verify that test-container's support for
|
||||
+ them is correct. The many checks in support_openpty.c are
|
||||
+ sufficient for this. */
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int outer, inner;
|
||||
+ char *name;
|
||||
+ struct termios term;
|
||||
+ struct winsize win;
|
||||
+
|
||||
+ cfmakeraw (&term);
|
||||
+ win.ws_row = 24;
|
||||
+ win.ws_col = 80;
|
||||
+
|
||||
+ support_openpty (&outer, &inner, &name, &term, &win);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
1084
glibc-RHEL-106562-23.patch
Normal file
1084
glibc-RHEL-106562-23.patch
Normal file
File diff suppressed because it is too large
Load Diff
112
glibc-RHEL-106562-24.patch
Normal file
112
glibc-RHEL-106562-24.patch
Normal file
@ -0,0 +1,112 @@
|
||||
commit 4fa959d13d21b8f56a43aa0a416100303736c55c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Apr 8 10:39:44 2025 +0200
|
||||
|
||||
stdio-common: In tst-setvbuf2, close helper thread descriptor only if opened
|
||||
|
||||
The helper thread may get canceled before the open system
|
||||
call succeds. Then ThreadData.fd remains zero, and eventually
|
||||
the xclose call in end_reader_thread fails because descriptor 0
|
||||
is not open.
|
||||
|
||||
Instead, initialize the fd member to -1 (not a valid descriptor)
|
||||
and close the descriptor only if valid. Do this in a new end_thread
|
||||
helper routine.
|
||||
|
||||
Also add more error checking to close operations.
|
||||
|
||||
Fixes commit 95b780c1d0549678c0a244c6e2112ec97edf0839 ("stdio: Add
|
||||
more setvbuf tests").
|
||||
|
||||
diff --git a/stdio-common/tst-setvbuf2.c b/stdio-common/tst-setvbuf2.c
|
||||
index 6cc83355f391afab..84d8b43a5811b4be 100644
|
||||
--- a/stdio-common/tst-setvbuf2.c
|
||||
+++ b/stdio-common/tst-setvbuf2.c
|
||||
@@ -240,6 +240,21 @@ typedef struct {
|
||||
/* It's OK if this is static, we only run one at a time. */
|
||||
ThreadData thread_data;
|
||||
|
||||
+static void
|
||||
+end_thread (pthread_t *ptid)
|
||||
+{
|
||||
+ if (*ptid)
|
||||
+ {
|
||||
+ pthread_cancel (*ptid);
|
||||
+ xpthread_join (*ptid);
|
||||
+ /* The descriptor was passed in, or the helper thread made
|
||||
+ sufficient progress and opened the file. */
|
||||
+ if (thread_data.fd >= 0)
|
||||
+ xclose (thread_data.fd);
|
||||
+ *ptid = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void *
|
||||
writer_thread_proc (void *closure)
|
||||
{
|
||||
@@ -306,7 +321,7 @@ static void
|
||||
start_writer_thread_n (const char *fname)
|
||||
{
|
||||
debug;
|
||||
- thread_data.fd = 0;
|
||||
+ thread_data.fd = -1;
|
||||
thread_data.fname = fname;
|
||||
writer_thread_tid = xpthread_create (NULL, writer_thread_proc,
|
||||
(void *)&thread_data);
|
||||
@@ -316,13 +331,7 @@ static void
|
||||
end_writer_thread (void)
|
||||
{
|
||||
debug;
|
||||
- if (writer_thread_tid)
|
||||
- {
|
||||
- pthread_cancel (writer_thread_tid);
|
||||
- xpthread_join (writer_thread_tid);
|
||||
- xclose (thread_data.fd);
|
||||
- writer_thread_tid = 0;
|
||||
- }
|
||||
+ end_thread (&writer_thread_tid);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -339,7 +348,7 @@ static void
|
||||
start_reader_thread_n (const char *fname)
|
||||
{
|
||||
debug;
|
||||
- thread_data.fd = 0;
|
||||
+ thread_data.fd = -1;
|
||||
thread_data.fname = fname;
|
||||
reader_thread_tid = xpthread_create (NULL, reader_thread_proc,
|
||||
(void *)&thread_data);
|
||||
@@ -349,13 +358,7 @@ static void
|
||||
end_reader_thread (void)
|
||||
{
|
||||
debug;
|
||||
- if (reader_thread_tid)
|
||||
- {
|
||||
- pthread_cancel (reader_thread_tid);
|
||||
- xpthread_join (reader_thread_tid);
|
||||
- xclose (thread_data.fd);
|
||||
- reader_thread_tid = 0;
|
||||
- }
|
||||
+ end_thread (&reader_thread_tid);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
@@ -852,7 +855,7 @@ do_second_part (FILE *fp,
|
||||
}
|
||||
|
||||
|
||||
- fclose (fp);
|
||||
+ xfclose (fp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -939,7 +942,7 @@ recurse (FILE *fp,
|
||||
break;
|
||||
|
||||
default: /* parent */
|
||||
- fclose (fp);
|
||||
+ xfclose (fp);
|
||||
xwaitpid (pid, &status, 0);
|
||||
if (WIFEXITED (status)
|
||||
&& WEXITSTATUS (status) == 0)
|
60
glibc-RHEL-106562-3.patch
Normal file
60
glibc-RHEL-106562-3.patch
Normal file
@ -0,0 +1,60 @@
|
||||
commit 3f54e459a633b4247be91b9d0f68a7e08720b8d8
|
||||
Author: Frédéric Bérat <fberat@redhat.com>
|
||||
Date: Tue Aug 13 12:01:26 2024 +0200
|
||||
|
||||
libio/tst-getdelim: Add new test covering NUL as a delimiter
|
||||
|
||||
Add a new test to getdelim to verify that '\0' can be set as a
|
||||
delimiter.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/libio/tst-getdelim.c b/libio/tst-getdelim.c
|
||||
index e6dd964b4918b02a..db15bf92855ee9e1 100644
|
||||
--- a/libio/tst-getdelim.c
|
||||
+++ b/libio/tst-getdelim.c
|
||||
@@ -1,4 +1,6 @@
|
||||
-/* Check that getdelim sets error indicator on error (BZ #29917)
|
||||
+/* Test getdelim conforming to POSIX specifications.
|
||||
+
|
||||
+ Note: Most getdelim use cases are covered by stdio-common/tst-getline.
|
||||
|
||||
Copyright (C) 2023-2024 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
@@ -18,18 +20,36 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/test-driver.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
+ /* Check that getdelim sets error indicator on error (BZ #29917) */
|
||||
clearerr (stdin);
|
||||
TEST_VERIFY (getdelim (0, 0, '\n', stdin) == -1);
|
||||
TEST_VERIFY (ferror (stdin) != 0);
|
||||
TEST_VERIFY (errno == EINVAL);
|
||||
|
||||
+ /* Test getdelim with NUL as delimiter */
|
||||
+ verbose_printf ("Testing NUL delimiter\n");
|
||||
+ char *lineptr = NULL;
|
||||
+ size_t linelen = 0;
|
||||
+ char membuf[] = "abc\0d\nef\0";
|
||||
+ FILE *memstream = fmemopen (membuf, sizeof (membuf), "r");
|
||||
+ TEST_VERIFY_EXIT (memstream != NULL);
|
||||
+ TEST_VERIFY (getdelim (&lineptr, &linelen, '\0', memstream) != -1);
|
||||
+ TEST_COMPARE_BLOB (lineptr, 4, "abc\0", 4);
|
||||
+ TEST_VERIFY (getdelim (&lineptr, &linelen, '\0', memstream) != -1);
|
||||
+ TEST_COMPARE_BLOB (lineptr, 5, "d\nef\0", 5);
|
||||
+ fclose (memstream);
|
||||
+ free (lineptr);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
29
glibc-RHEL-106562-4.patch
Normal file
29
glibc-RHEL-106562-4.patch
Normal file
@ -0,0 +1,29 @@
|
||||
commit b22923abb046311ac9097a36b97b9b97342bac44
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Aug 15 08:12:35 2024 -0400
|
||||
|
||||
Report error if setaffinity wrapper fails (Bug 32040)
|
||||
|
||||
Previously if the setaffinity wrapper failed the rest of the subtest
|
||||
would not execute and the current subtest would be reported as passing.
|
||||
Now if the setaffinity wrapper fails the subtest is correctly reported
|
||||
as faling. Tested manually by changing the conditions of the affinity
|
||||
call including setting size to zero, or checking the wrong condition.
|
||||
|
||||
No regressions on x86_64.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
index 31a15b3ad789a287..2f921ed397a1a4d9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c
|
||||
@@ -157,7 +157,7 @@ test_size (const struct conf *conf, size_t size)
|
||||
if (setaffinity (kernel_size, initial_set) < 0)
|
||||
{
|
||||
printf ("error: size %zu: setaffinity: %m\n", size);
|
||||
- return true;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
/* Use one-CPU set to test switching between CPUs. */
|
78
glibc-RHEL-106562-5.patch
Normal file
78
glibc-RHEL-106562-5.patch
Normal file
@ -0,0 +1,78 @@
|
||||
commit 921690512946d73bf66a8c495baff31316e4489f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 16 16:05:19 2024 +0200
|
||||
|
||||
support: Add the xstatx function
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index aa57207bdccc852d..5b1c96a49e9410f4 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -210,6 +210,7 @@ libsupport-routines = \
|
||||
xsignal \
|
||||
xsigstack \
|
||||
xsocket \
|
||||
+ xstatx \
|
||||
xstrdup \
|
||||
xstrndup \
|
||||
xsymlink \
|
||||
diff --git a/support/xstatx.c b/support/xstatx.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..621f2440f83b598d
|
||||
--- /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 13be9a46a3e6b07b..cc74c4fad07dd088 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);
|
391
glibc-RHEL-106562-6.patch
Normal file
391
glibc-RHEL-106562-6.patch
Normal file
@ -0,0 +1,391 @@
|
||||
commit bf2927484152e12996af60ea439cf94b66fcd81d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 16 16:05:20 2024 +0200
|
||||
|
||||
io: Use struct statx and xstatx in tests
|
||||
|
||||
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>
|
||||
|
||||
diff --git a/io/tst-futimens-time64.c b/io/tst-futimens-time64.c
|
||||
index 88fcb38489b160de..71204a6166eaba56 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 6204befedd869bb6..075ca42b9378d98f 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 d489c265d1964196..eeb4bed7c4f5fb12 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 d21acf6a24715a10..612fe460cf505547 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 f6c0500eefb9c98b..15853175796e59dd 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 67a8551bebf23190..feae4e7aa76ddee7 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 06caec0a91d91b6c..c5bea965dabe6cd7 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 edef5ab90e8681c7..78bcc58291fdcdc8 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 eb62f59126564896..8894592a1570a366 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 e2e6dcd04cebb7fc..f32935828923a47f 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 7ac7d8df1d48f0a0..5d60fce8818f7545 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 3d9a72c4719cc6c9..2a756d7b07b6b07f 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 234ec02541032017..026ef5f78dd4616c 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 8edcfabebfbd978d..6cd436c5a0f94d84 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;
|
||||
}
|
415
glibc-RHEL-106562-7.patch
Normal file
415
glibc-RHEL-106562-7.patch
Normal file
@ -0,0 +1,415 @@
|
||||
commit e7c14e542d8d858b824b5df4f4e3dc93695e6171
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 16 16:05:20 2024 +0200
|
||||
|
||||
support: Use macros for *stat wrappers
|
||||
|
||||
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>
|
||||
|
||||
diff --git a/elf/tst-ldconfig-bad-aux-cache.c b/elf/tst-ldconfig-bad-aux-cache.c
|
||||
index 7f1fbb52523ac1ac..8c2e62ecc2c54c04 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 9837b7c3395725a5..3d7b0aa90160190a 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 d84568859eb5c604..685924ae76245676 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 ffe8cbd46732386f..f592b9a9605bff94 100644
|
||||
--- a/locale/tst-localedef-path-norm.c
|
||||
+++ b/locale/tst-localedef-path-norm.c
|
||||
@@ -84,7 +84,7 @@ run_test (void *closure)
|
||||
support_capture_subprocess_free (&result);
|
||||
|
||||
/* Verify path is present and is a directory. */
|
||||
- xstat (path, &fs);
|
||||
+ xstat64 (path, &fs);
|
||||
if (!S_ISDIR (fs.st_mode))
|
||||
{
|
||||
support_record_failure ();
|
||||
diff --git a/localedata/tst-localedef-hardlinks.c b/localedata/tst-localedef-hardlinks.c
|
||||
index e88215a1507bb30a..23927b462fc2224a 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 4565d6b19f41ca63..dde034a9f1356453 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 b65afed75ec65ca4..7f4345f716182552 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 47c742f963a1b6b4..b5b630a41b9e4663 100644
|
||||
--- a/stdlib/tst-system.c
|
||||
+++ b/stdlib/tst-system.c
|
||||
@@ -169,7 +169,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 5b1c96a49e9410f4..6e3c55394fa212b6 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -42,14 +42,12 @@ libsupport-routines = \
|
||||
resolv_test \
|
||||
set_fortify_handler \
|
||||
support-open-dev-null-range \
|
||||
- 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 \
|
||||
@@ -135,8 +133,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 589a69bb3e04857d..0000000000000000
|
||||
--- a/support/support-xfstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021-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/>. */
|
||||
-
|
||||
-/* 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 451948734ae0de0f..0000000000000000
|
||||
--- a/support/support-xstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021-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/>. */
|
||||
-
|
||||
-/* 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 ce866f74d242c07a..0000000000000000
|
||||
--- a/support/support-xstat.c
|
||||
+++ /dev/null
|
||||
@@ -1,30 +0,0 @@
|
||||
-/* stat64 with error checking.
|
||||
- Copyright (C) 2017-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/>. */
|
||||
-
|
||||
-/* 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 87df988879094d5b..4c12adf6b7f68d0c 100644
|
||||
--- a/support/xlstat.c
|
||||
+++ b/support/support_check_stat_fd.c
|
||||
@@ -1,5 +1,5 @@
|
||||
-/* lstat64 with error checking.
|
||||
- Copyright (C) 2017-2024 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 ab4b01c97d7b5f2f..3cf72afe5901dcd5 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-2024 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 2bc3ca6593bd397d..0000000000000000
|
||||
--- a/support/xlstat-time64.c
|
||||
+++ /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
-/* 64-bit time_t stat with error checking.
|
||||
- Copyright (C) 2021-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/>. */
|
||||
-
|
||||
-/* 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 cc74c4fad07dd088..204951bce75f576b 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 flags);
|
||||
void xpipe (int[2]);
|
||||
void xdup2 (int, int);
|
||||
int xopen (const char *path, int flags, mode_t);
|
||||
-#ifndef __USE_TIME64_REDIRECTS
|
||||
-# 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);
|
148
glibc-RHEL-106562-8.patch
Normal file
148
glibc-RHEL-106562-8.patch
Normal file
@ -0,0 +1,148 @@
|
||||
commit 2eee835eca960c9d4119279804214b7a1ed5d156
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Thu Aug 8 22:44:56 2024 -0400
|
||||
|
||||
inet: test if_nametoindex and if_indextoname
|
||||
|
||||
Tests for if_nameindex, if_name2index, and if_index2name
|
||||
|
||||
Tests that valid results are consistent.
|
||||
|
||||
Tests that invalid parameters fail correctly.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/inet/Makefile b/inet/Makefile
|
||||
index 2f03e6f7ee211525..cb97b45f0f9d223f 100644
|
||||
--- a/inet/Makefile
|
||||
+++ b/inet/Makefile
|
||||
@@ -91,6 +91,7 @@ tests := \
|
||||
tst-getni1 \
|
||||
tst-getni2 \
|
||||
tst-if_index-long \
|
||||
+ tst-if_nameindex \
|
||||
tst-inet6_rth \
|
||||
tst-network \
|
||||
tst-ntoa \
|
||||
diff --git a/inet/tst-if_nameindex.c b/inet/tst-if_nameindex.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b025cdb3a7c6b68c
|
||||
--- /dev/null
|
||||
+++ b/inet/tst-if_nameindex.c
|
||||
@@ -0,0 +1,116 @@
|
||||
+/* Tests for if_nameindex et al.
|
||||
+ 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 <net/if.h>
|
||||
+#include <netdb.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/descriptors.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static char *buffer;
|
||||
+
|
||||
+static const char *test_names[] = {
|
||||
+ "testing",
|
||||
+ "invalid",
|
||||
+ "dont-match",
|
||||
+ "",
|
||||
+ "\001\001\001\177",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+checki (int i)
|
||||
+{
|
||||
+ char *ifname;
|
||||
+
|
||||
+ /* Test that a known-invalid index returns NULL. */
|
||||
+ /* BUFFER should not be accessed. */
|
||||
+
|
||||
+ printf ("Testing if_indextoname (%d) == NULL\n", i);
|
||||
+ ifname = if_indextoname (i, NULL);
|
||||
+ TEST_VERIFY (ifname == NULL);
|
||||
+ TEST_VERIFY (errno == ENXIO);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct if_nameindex *if_ni, *ifp;
|
||||
+ int min_idx, max_idx, buflen = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ if_ni = if_nameindex ();
|
||||
+ TEST_VERIFY (if_ni != NULL);
|
||||
+
|
||||
+ min_idx = max_idx = if_ni->if_index;
|
||||
+
|
||||
+ for (ifp = if_ni; !(ifp->if_index == 0 && ifp->if_name == NULL); ifp++)
|
||||
+ {
|
||||
+ printf ("%u: %s\n", ifp->if_index, ifp->if_name);
|
||||
+ if (ifp->if_index < min_idx)
|
||||
+ min_idx = ifp->if_index;
|
||||
+ if (ifp->if_index > max_idx)
|
||||
+ max_idx = ifp->if_index;
|
||||
+ if (strlen (ifp->if_name) + 1 > buflen)
|
||||
+ buflen = strlen (ifp->if_name) + 1;
|
||||
+ }
|
||||
+ buffer = (char *) xmalloc (buflen);
|
||||
+
|
||||
+ /* Check normal operation. */
|
||||
+ for (ifp = if_ni; !(ifp->if_index == 0 && ifp->if_name == NULL); ifp++)
|
||||
+ {
|
||||
+ unsigned int idx = if_nametoindex (ifp->if_name);
|
||||
+ TEST_VERIFY (idx == ifp->if_index);
|
||||
+
|
||||
+ char *fn = if_indextoname (ifp->if_index, buffer);
|
||||
+ TEST_VERIFY (strcmp (fn, ifp->if_name) == 0);
|
||||
+ }
|
||||
+
|
||||
+ for (i=-2; i<min_idx; i++)
|
||||
+ checki (i);
|
||||
+ for (i=max_idx+1; i<max_idx+3; i++)
|
||||
+ checki (i);
|
||||
+
|
||||
+ /* Check that a known-invalid name returns 0. */
|
||||
+
|
||||
+ for (i=0; test_names[i] != NULL; i++)
|
||||
+ {
|
||||
+ /* Make sure our "invalid" name is really invalid. */
|
||||
+ for (ifp = if_ni; !(ifp->if_index == 0 && ifp->if_name == NULL); ifp++)
|
||||
+ if (strcmp (test_names[i], ifp->if_name) == 0)
|
||||
+ goto not_this_one;
|
||||
+
|
||||
+ printf ("Testing if_nametoindex (%s) == 0\n", test_names[i]);
|
||||
+
|
||||
+ unsigned int idx = if_nametoindex (test_names[i]);
|
||||
+ TEST_VERIFY (idx == 0);
|
||||
+ TEST_VERIFY (errno == ENODEV);
|
||||
+
|
||||
+ not_this_one:
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if_freenameindex (if_ni);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
79
glibc-RHEL-106562-9.patch
Normal file
79
glibc-RHEL-106562-9.patch
Normal file
@ -0,0 +1,79 @@
|
||||
commit 55cd51d971b84fbb2cc0fe8140cc8581f98582c7
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Thu Aug 22 11:25:14 2024 +0000
|
||||
|
||||
Test mkdirat use of mode argument
|
||||
|
||||
The test io/tst-mkdirat doesn't verify the permissions on the created
|
||||
directory (thus, doesn't verify at all anything about how mkdirat uses
|
||||
the mode argument). Add checks of this to the existing test.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/io/tst-mkdirat.c b/io/tst-mkdirat.c
|
||||
index 605e51ef1e966b42..b97bc3ca6d0cdf23 100644
|
||||
--- a/io/tst-mkdirat.c
|
||||
+++ b/io/tst-mkdirat.c
|
||||
@@ -53,6 +53,10 @@ prepare (void)
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
+ /* Find the current umask. */
|
||||
+ mode_t mask = umask (022);
|
||||
+ umask (mask);
|
||||
+
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
@@ -107,6 +111,13 @@ do_test (void)
|
||||
puts ("mkdirat did not create a directory");
|
||||
return 1;
|
||||
}
|
||||
+ if ((st1.st_mode & 01777) != (~mask & 0777))
|
||||
+ {
|
||||
+ printf ("mkdirat created directory with wrong mode %o, expected %o\n",
|
||||
+ (unsigned int) (st1.st_mode & 01777),
|
||||
+ (unsigned int) (~mask & 0777));
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
@@ -156,6 +167,37 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ /* Test again with a different mode. */
|
||||
+ umask (0);
|
||||
+ e = mkdirat (dir_fd, "some-dir", 01755);
|
||||
+ umask (mask);
|
||||
+ if (e == -1)
|
||||
+ {
|
||||
+ puts ("directory creation (different mode) failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (fstatat64 (dir_fd, "some-dir", &st1, 0) != 0)
|
||||
+ {
|
||||
+ puts ("fstat64 (different mode) failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (!S_ISDIR (st1.st_mode))
|
||||
+ {
|
||||
+ puts ("mkdirat (different mode) did not create a directory");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if ((st1.st_mode & 01777) != 01755)
|
||||
+ {
|
||||
+ printf ("mkdirat (different mode) created directory with wrong mode %o\n",
|
||||
+ (unsigned int) (st1.st_mode & 01777));
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (unlinkat (dir_fd, "some-dir", AT_REMOVEDIR) != 0)
|
||||
+ {
|
||||
+ puts ("unlinkat (different mode) failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
close (dir_fd);
|
||||
|
||||
return 0;
|
29
glibc.spec
29
glibc.spec
@ -145,7 +145,7 @@ Version: %{glibcversion}
|
||||
# - It allows using the Release number without the %%dist tag in the dependency
|
||||
# generator to make the generated requires interchangeable between Rawhide
|
||||
# and ELN (.elnYY < .fcXX).
|
||||
%global baserelease 49
|
||||
%global baserelease 50
|
||||
Release: %{baserelease}%{?dist}
|
||||
|
||||
# Licenses:
|
||||
@ -591,6 +591,30 @@ Patch267: glibc-RHEL-72564-2.patch
|
||||
Patch268: glibc-RHEL-107540-1.patch
|
||||
Patch269: glibc-RHEL-107540-2.patch
|
||||
Patch270: glibc-RHEL-107540-3.patch
|
||||
Patch271: glibc-RHEL-106562-1.patch
|
||||
Patch272: glibc-RHEL-106562-2.patch
|
||||
Patch273: glibc-RHEL-106562-3.patch
|
||||
Patch274: glibc-RHEL-106562-4.patch
|
||||
Patch275: glibc-RHEL-106562-5.patch
|
||||
Patch276: glibc-RHEL-106562-6.patch
|
||||
Patch277: glibc-RHEL-106562-7.patch
|
||||
Patch278: glibc-RHEL-106562-8.patch
|
||||
Patch279: glibc-RHEL-106562-9.patch
|
||||
Patch280: glibc-RHEL-106562-10.patch
|
||||
Patch281: glibc-RHEL-106562-11.patch
|
||||
Patch282: glibc-RHEL-106562-12.patch
|
||||
Patch283: glibc-RHEL-106562-13.patch
|
||||
Patch284: glibc-RHEL-106562-14.patch
|
||||
Patch285: glibc-RHEL-106562-15.patch
|
||||
Patch286: glibc-RHEL-106562-16.patch
|
||||
Patch287: glibc-RHEL-106562-17.patch
|
||||
Patch288: glibc-RHEL-106562-18.patch
|
||||
Patch289: glibc-RHEL-106562-19.patch
|
||||
Patch290: glibc-RHEL-106562-20.patch
|
||||
Patch291: glibc-RHEL-106562-21.patch
|
||||
Patch292: glibc-RHEL-106562-22.patch
|
||||
Patch293: glibc-RHEL-106562-23.patch
|
||||
Patch294: glibc-RHEL-106562-24.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -2603,6 +2627,9 @@ update_gconv_modules_cache ()
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Aug 06 2025 Arjun Shankar <arjun@redhat.com> - 2.39-50
|
||||
- Improve test coverage (RHEL-106562)
|
||||
|
||||
* Tue Aug 05 2025 Florian Weimer <fweimer@redhat.com> - 2.39-49
|
||||
- x86_64, aarch64: More CPU output in ld.so --list-diagnostics (RHEL-107540)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user