From a91df5db11b44703c6f74c86c142c22cdc2768d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 2 Apr 2024 15:13:14 +0200 Subject: [PATCH 01/29] rebase to latest upstream version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sync i18n patch with SUSE (Kudos to Berny Völker!) - add some test dependencies to execute additional part of the upstream test-suite Resolves: rhbz#2272063 --- coreutils-9.4-CVE-2024-0684.patch | 31 - coreutils-9.4-systemd-coredump.patch | 28 - coreutils-9.4-tail-64k-pages.patch | 205 ---- coreutils-df-direct.patch | 24 +- coreutils-i18n.patch | 1453 ++++++++++---------------- coreutils-python3.patch | 65 ++ coreutils-selinux.patch | 12 +- coreutils.spec | 34 +- sources | 4 +- 9 files changed, 648 insertions(+), 1208 deletions(-) delete mode 100644 coreutils-9.4-CVE-2024-0684.patch delete mode 100644 coreutils-9.4-systemd-coredump.patch delete mode 100644 coreutils-9.4-tail-64k-pages.patch create mode 100644 coreutils-python3.patch diff --git a/coreutils-9.4-CVE-2024-0684.patch b/coreutils-9.4-CVE-2024-0684.patch deleted file mode 100644 index 64583af..0000000 --- a/coreutils-9.4-CVE-2024-0684.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c4c5ed8f4e9cd55a12966d4f520e3a13101637d9 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 16 Jan 2024 13:48:32 -0800 -Subject: [PATCH] split: do not shrink hold buffer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* src/split.c (line_bytes_split): Do not shrink hold buffer. -If it’s large for this batch it’s likely to be large for the next -batch, and for ‘split’ it’s not worth the complexity/CPU hassle to -shrink it. Do not assume hold_size can be bufsize. ---- - src/split.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/src/split.c b/src/split.c -index 64020c859..037960a59 100644 ---- a/src/split.c -+++ b/src/split.c -@@ -809,10 +809,7 @@ line_bytes_split (intmax_t n_bytes, char *buf, idx_t bufsize) - { - cwrite (n_out == 0, hold, n_hold); - n_out += n_hold; -- if (n_hold > bufsize) -- hold = xirealloc (hold, bufsize); - n_hold = 0; -- hold_size = bufsize; - } - - /* Output to eol if present. */ diff --git a/coreutils-9.4-systemd-coredump.patch b/coreutils-9.4-systemd-coredump.patch deleted file mode 100644 index 13f69e0..0000000 --- a/coreutils-9.4-systemd-coredump.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2616c6be1c244424617997151c67bcab2dacbcfe Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Thu, 31 Aug 2023 14:34:05 +0200 -Subject: [PATCH] coreutils-9.4-systemd-coredump.patch - -Cherry picked from gnulib upstream commits: -* 1e6a26f9312bb47e070f94b17b14dc1a6ffbb74f ("readutmp: fix core dump if --enable-systemd") -* 3af1d7b0ce3a8e3ae565e7cea10cee6fd7cb8109 ("readutmp: Fix memory leak introduced by last commit.") ---- - lib/readutmp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/readutmp.c b/lib/readutmp.c -index 0173b7e..ec09feb 100644 ---- a/lib/readutmp.c -+++ b/lib/readutmp.c -@@ -795,7 +795,7 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) - { - char **sessions; - int num_sessions = sd_get_sessions (&sessions); -- if (num_sessions >= 0) -+ if (num_sessions >= 0 && sessions != NULL) - { - char **session_ptr; - for (session_ptr = sessions; *session_ptr != NULL; session_ptr++) --- -2.41.0 - diff --git a/coreutils-9.4-tail-64k-pages.patch b/coreutils-9.4-tail-64k-pages.patch deleted file mode 100644 index 1165f7b..0000000 --- a/coreutils-9.4-tail-64k-pages.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a Mon Sep 17 00:00:00 2001 -From: dann frazier -Date: Wed, 29 Nov 2023 18:32:34 -0700 -Subject: [PATCH] tail: fix tailing sysfs files where PAGE_SIZE > BUFSIZ - -* src/tail.c (file_lines): Ensure we use a buffer size >= PAGE_SIZE when -searching backwards to avoid seeking within a file, -which on sysfs files is accepted but also returns no data. -* tests/tail/tail-sysfs.sh: Add a new test. -* tests/local.mk: Reference the new test. -* NEWS: Mention the bug fix. -Fixes https://bugs.gnu.org/67490 - -Upstream-commit: 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a -Cherry-picked-by: Lukáš Zaoral ---- - src/tail.c | 57 +++++++++++++++++++++++++++++----------- - tests/local.mk | 1 + - tests/tail/tail-sysfs.sh | 34 ++++++++++++++++++++++++ - 3 files changed, 77 insertions(+), 15 deletions(-) - create mode 100755 tests/tail/tail-sysfs.sh - -diff --git a/src/tail.c b/src/tail.c -index c45f3b65a..6979e0ba3 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -208,6 +208,9 @@ static int nbpids = 0; - that is writing to all followed files. */ - static pid_t pid; - -+/* Used to determine the buffer size when scanning backwards in a file. */ -+static idx_t page_size; -+ - /* True if we have ever read standard input. */ - static bool have_read_stdin; - -@@ -515,22 +518,40 @@ xlseek (int fd, off_t offset, int whence, char const *filename) - Return true if successful. */ - - static bool --file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, -- off_t start_pos, off_t end_pos, uintmax_t *read_pos) -+file_lines (char const *pretty_filename, int fd, struct stat const *sb, -+ uintmax_t n_lines, off_t start_pos, off_t end_pos, -+ uintmax_t *read_pos) - { -- char buffer[BUFSIZ]; -+ char *buffer; - size_t bytes_read; -+ blksize_t bufsize = BUFSIZ; - off_t pos = end_pos; -+ bool ok = true; - - if (n_lines == 0) - return true; - -+ /* Be careful with files with sizes that are a multiple of the page size, -+ as on /proc or /sys file systems these files accept seeking to within -+ the file, but then return no data when read. So use a buffer that's -+ at least PAGE_SIZE to avoid seeking within such files. -+ -+ We could also indirectly use a large enough buffer through io_blksize() -+ however this would be less efficient in the common case, as it would -+ generally pick a larger buffer size, resulting in reading more data -+ from the end of the file. */ -+ affirm (S_ISREG (sb->st_mode)); -+ if (sb->st_size % page_size == 0) -+ bufsize = MAX (BUFSIZ, page_size); -+ -+ buffer = xmalloc (bufsize); -+ - /* Set 'bytes_read' to the size of the last, probably partial, buffer; -- 0 < 'bytes_read' <= 'BUFSIZ'. */ -- bytes_read = (pos - start_pos) % BUFSIZ; -+ 0 < 'bytes_read' <= 'bufsize'. */ -+ bytes_read = (pos - start_pos) % bufsize; - if (bytes_read == 0) -- bytes_read = BUFSIZ; -- /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all -+ bytes_read = bufsize; -+ /* Make 'pos' a multiple of 'bufsize' (0 if the file is short), so that all - reads will be on block boundaries, which might increase efficiency. */ - pos -= bytes_read; - xlseek (fd, pos, SEEK_SET, pretty_filename); -@@ -538,7 +559,8 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - if (bytes_read == SAFE_READ_ERROR) - { - error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); -- return false; -+ ok = false; -+ goto free_buffer; - } - *read_pos = pos + bytes_read; - -@@ -565,7 +587,7 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - xwrite_stdout (nl + 1, bytes_read - (n + 1)); - *read_pos += dump_remainder (false, pretty_filename, fd, - end_pos - (pos + bytes_read)); -- return true; -+ goto free_buffer; - } - } - -@@ -577,23 +599,26 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - xlseek (fd, start_pos, SEEK_SET, pretty_filename); - *read_pos = start_pos + dump_remainder (false, pretty_filename, fd, - end_pos); -- return true; -+ goto free_buffer; - } -- pos -= BUFSIZ; -+ pos -= bufsize; - xlseek (fd, pos, SEEK_SET, pretty_filename); - -- bytes_read = safe_read (fd, buffer, BUFSIZ); -+ bytes_read = safe_read (fd, buffer, bufsize); - if (bytes_read == SAFE_READ_ERROR) - { - error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); -- return false; -+ ok = false; -+ goto free_buffer; - } - - *read_pos = pos + bytes_read; - } - while (bytes_read > 0); - -- return true; -+free_buffer: -+ free (buffer); -+ return ok; - } - - /* Print the last N_LINES lines from the end of the standard input, -@@ -1915,7 +1940,7 @@ tail_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - { - *read_pos = end_pos; - if (end_pos != 0 -- && ! file_lines (pretty_filename, fd, n_lines, -+ && ! file_lines (pretty_filename, fd, &stats, n_lines, - start_pos, end_pos, read_pos)) - return false; - } -@@ -2337,6 +2362,8 @@ main (int argc, char **argv) - - atexit (close_stdout); - -+ page_size = getpagesize (); -+ - have_read_stdin = false; - - count_lines = true; -diff --git a/tests/local.mk b/tests/local.mk -index db4ee7ed8..bf03238c3 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -257,6 +257,7 @@ all_tests = \ - tests/seq/seq-precision.sh \ - tests/head/head.pl \ - tests/head/head-elide-tail.pl \ -+ tests/tail/tail-sysfs.sh \ - tests/tail/tail-n0f.sh \ - tests/ls/ls-misc.pl \ - tests/date/date.pl \ -diff --git a/tests/tail/tail-sysfs.sh b/tests/tail/tail-sysfs.sh -new file mode 100755 -index 000000000..00874b3dc ---- /dev/null -+++ b/tests/tail/tail-sysfs.sh -@@ -0,0 +1,34 @@ -+#!/bin/sh -+# sysfs files have weird properties that can be influenced by page size -+ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program 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 General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ tail -+ -+file='/sys/kernel/profiling' -+ -+test -r "$file" || skip_ "No $file file" -+ -+cp -f "$file" exp || framework_failure_ -+ -+tail -n1 "$file" > out || fail=1 -+compare exp out || fail=1 -+ -+tail -c2 "$file" > out || fail=1 -+compare exp out || fail=1 -+ -+Exit $fail diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 9e3434a..f29a065 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From 6e36198f10a2f63b89c89ebb5d5c185b20fb3a63 Mon Sep 17 00:00:00 2001 +From f072852456c545bd89296bc88cf59ccd63287a68 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 5b9a597..6810c15 100644 +index 8f7f43e..230f1f1 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12074,6 +12074,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12427,6 +12427,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index 5b9a597..6810c15 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 48025b9..c8efa5b 100644 +index 994f0e3..ceee209 100644 --- a/src/df.c +++ b/src/df.c -@@ -125,6 +125,9 @@ static bool print_type; +@@ -121,6 +121,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index 48025b9..c8efa5b 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -252,13 +255,15 @@ enum +@@ -247,13 +250,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,7 +59,7 @@ index 48025b9..c8efa5b 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -583,7 +588,10 @@ get_header (void) +@@ -574,7 +579,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = nullptr; @@ -71,7 +71,7 @@ index 48025b9..c8efa5b 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1486,6 +1494,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1471,6 +1479,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 48025b9..c8efa5b 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1556,6 +1575,7 @@ or all file systems by default.\n\ +@@ -1541,6 +1560,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 48025b9..c8efa5b 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1646,6 +1666,9 @@ main (int argc, char **argv) +@@ -1631,6 +1651,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 48025b9..c8efa5b 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1742,6 +1765,13 @@ main (int argc, char **argv) +@@ -1727,6 +1750,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.31.1 +2.44.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index be8e0b1..aa21a35 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,66 +1,69 @@ -From 3a1b92e80708319bcc89852e3da1029c3d1ff6b3 Mon Sep 17 00:00:00 2001 +From 94cf02dfcb1be23dedf8a39af295f28ee2de6013 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch --- - bootstrap.conf | 1 + + bootstrap.conf | 2 + configure.ac | 6 + lib/linebuffer.h | 8 + + lib/mbchar.c | 23 ++ + lib/mbchar.h | 373 +++++++++++++++++ lib/mbfile.c | 20 + lib/mbfile.h | 267 ++++++++++++ + m4/mbchar.m4 | 13 + m4/mbfile.m4 | 14 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- src/fold.c | 312 ++++++++++++-- - src/join.c | 359 ++++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 102 ++++- - src/uniq.c | 119 +++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ tests/misc/fold.pl | 50 ++- - tests/misc/join.pl | 50 +++ tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - tests/uniq/uniq.pl | 55 +++ - 31 files changed, 3732 insertions(+), 242 deletions(-) + 30 files changed, 3605 insertions(+), 196 deletions(-) + create mode 100644 lib/mbchar.c + create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h + create mode 100644 m4/mbchar.m4 create mode 100644 m4/mbfile.m4 - create mode 100755 tests/expand/mb.sh - create mode 100755 tests/i18n/sort.sh - create mode 100755 tests/misc/sort-mb-tests.sh - create mode 100755 tests/unexpand/mb.sh + create mode 100644 tests/expand/mb.sh + create mode 100644 tests/i18n/sort.sh + create mode 100644 tests/misc/sort-mb-tests.sh + create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index bd73ff2..0e450cd 100644 +index 126e1e8..b4ccebf 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -167,6 +167,7 @@ gnulib_modules=" +@@ -163,6 +163,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings ++ mbchar + mbfile mbrlen + mbrtoc32 mbrtowc - mbsalign diff --git a/configure.ac b/configure.ac -index 8ffc0b7..ca3305d 100644 +index 9cb6ee1..1131ce3 100644 --- a/configure.ac +++ b/configure.ac -@@ -448,6 +448,12 @@ fi +@@ -504,6 +504,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -74,7 +77,7 @@ index 8ffc0b7..ca3305d 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index b4cc8e4..f2bbb52 100644 +index ae0d55d..5bf5350 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ @@ -99,6 +102,414 @@ index b4cc8e4..f2bbb52 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ +diff --git a/lib/mbchar.c b/lib/mbchar.c +new file mode 100644 +index 0000000..d94b7c3 +--- /dev/null ++++ b/lib/mbchar.c +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2001, 2006, 2009-2024 Free Software Foundation, Inc. ++ ++ This file 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. ++ ++ This file 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 this program. If not, see . */ ++ ++ ++#include ++ ++#define MBCHAR_INLINE _GL_EXTERN_INLINE ++ ++#include ++ ++#include "mbchar.h" +diff --git a/lib/mbchar.h b/lib/mbchar.h +new file mode 100644 +index 0000000..c06ef11 +--- /dev/null ++++ b/lib/mbchar.h +@@ -0,0 +1,373 @@ ++/* Multibyte character data type. ++ Copyright (C) 2001, 2005-2007, 2009-2024 Free Software Foundation, Inc. ++ ++ This file 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. ++ ++ This file 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 this program. If not, see . */ ++ ++/* Written by Bruno Haible . */ ++ ++/* A multibyte character is a short subsequence of a char* string, ++ representing a single 32-bit wide character. ++ ++ We use multibyte characters instead of 32-bit wide characters because ++ of the following goals: ++ 1) correct multibyte handling, i.e. operate according to the LC_CTYPE ++ locale, ++ 2) ease of maintenance, i.e. the maintainer needs not know all details ++ of the ISO C 99 standard, ++ 3) don't fail grossly if the input is not in the encoding set by the ++ locale, because often different encodings are in use in the same ++ countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), ++ 4) fast in the case of ASCII characters. ++ ++ Multibyte characters are only accessed through the mb* macros. ++ ++ mb_ptr (mbc) ++ return a pointer to the beginning of the multibyte sequence. ++ ++ mb_len (mbc) ++ returns the number of bytes occupied by the multibyte sequence. ++ Always > 0. ++ ++ mb_iseq (mbc, sc) ++ returns true if mbc is the standard ASCII character sc. ++ ++ mb_isnul (mbc) ++ returns true if mbc is the nul character. ++ ++ mb_cmp (mbc1, mbc2) ++ returns a positive, zero, or negative value depending on whether mbc1 ++ sorts after, same or before mbc2. ++ ++ mb_casecmp (mbc1, mbc2) ++ returns a positive, zero, or negative value depending on whether mbc1 ++ sorts after, same or before mbc2, modulo upper/lowercase conversion. ++ ++ mb_equal (mbc1, mbc2) ++ returns true if mbc1 and mbc2 are equal. ++ ++ mb_caseequal (mbc1, mbc2) ++ returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. ++ ++ mb_isalnum (mbc) ++ returns true if mbc is alphanumeric. ++ ++ mb_isalpha (mbc) ++ returns true if mbc is alphabetic. ++ ++ mb_isascii(mbc) ++ returns true if mbc is plain ASCII. ++ ++ mb_isblank (mbc) ++ returns true if mbc is a blank. ++ ++ mb_iscntrl (mbc) ++ returns true if mbc is a control character. ++ ++ mb_isdigit (mbc) ++ returns true if mbc is a decimal digit. ++ ++ mb_isgraph (mbc) ++ returns true if mbc is a graphic character. ++ ++ mb_islower (mbc) ++ returns true if mbc is lowercase. ++ ++ mb_isprint (mbc) ++ returns true if mbc is a printable character. ++ ++ mb_ispunct (mbc) ++ returns true if mbc is a punctuation character. ++ ++ mb_isspace (mbc) ++ returns true if mbc is a space character. ++ ++ mb_isupper (mbc) ++ returns true if mbc is uppercase. ++ ++ mb_isxdigit (mbc) ++ returns true if mbc is a hexadecimal digit. ++ ++ mb_width (mbc) ++ returns the number of columns on the output device occupied by mbc. ++ Always >= 0. ++ ++ mb_putc (mbc, stream) ++ outputs mbc on stream, a byte oriented FILE stream opened for output. ++ ++ mb_setascii (&mbc, sc) ++ assigns the standard ASCII character sc to mbc. ++ (Only available if the 'mbfile' module is in use.) ++ ++ mb_copy (&destmbc, &srcmbc) ++ copies srcmbc to destmbc. ++ ++ Here are the function prototypes of the macros. ++ ++ extern const char * mb_ptr (const mbchar_t mbc); ++ extern size_t mb_len (const mbchar_t mbc); ++ extern bool mb_iseq (const mbchar_t mbc, char sc); ++ extern bool mb_isnul (const mbchar_t mbc); ++ extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_isalnum (const mbchar_t mbc); ++ extern bool mb_isalpha (const mbchar_t mbc); ++ extern bool mb_isascii (const mbchar_t mbc); ++ extern bool mb_isblank (const mbchar_t mbc); ++ extern bool mb_iscntrl (const mbchar_t mbc); ++ extern bool mb_isdigit (const mbchar_t mbc); ++ extern bool mb_isgraph (const mbchar_t mbc); ++ extern bool mb_islower (const mbchar_t mbc); ++ extern bool mb_isprint (const mbchar_t mbc); ++ extern bool mb_ispunct (const mbchar_t mbc); ++ extern bool mb_isspace (const mbchar_t mbc); ++ extern bool mb_isupper (const mbchar_t mbc); ++ extern bool mb_isxdigit (const mbchar_t mbc); ++ extern int mb_width (const mbchar_t mbc); ++ extern void mb_putc (const mbchar_t mbc, FILE *stream); ++ extern void mb_setascii (mbchar_t *new, char sc); ++ extern void mb_copy (mbchar_t *new, const mbchar_t *old); ++ */ ++ ++#ifndef _MBCHAR_H ++#define _MBCHAR_H 1 ++ ++/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ ++#if !_GL_CONFIG_H_INCLUDED ++ #error "Please include config.h first." ++#endif ++ ++#include ++#include ++ ++_GL_INLINE_HEADER_BEGIN ++#ifndef MBCHAR_INLINE ++# define MBCHAR_INLINE _GL_INLINE ++#endif ++ ++/* The longest multibyte characters, nowadays, are 4 bytes long. ++ Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ ++#define MBCHAR_BUF_SIZE 4 ++ ++struct mbchar ++{ ++ const char *ptr; /* pointer to current character */ ++ size_t bytes; /* number of bytes of current character, > 0 */ ++ bool wc_valid; /* true if wc is a valid 32-bit wide character */ ++ char32_t wc; /* if wc_valid: the current character */ ++#if defined GNULIB_MBFILE ++ char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ ++#endif ++}; ++ ++/* EOF (not a real character) is represented with bytes = 0 and ++ wc_valid = false. */ ++ ++typedef struct mbchar mbchar_t; ++ ++/* Access the current character. */ ++#define mb_ptr(mbc) ((mbc).ptr) ++#define mb_len(mbc) ((mbc).bytes) ++ ++/* Comparison of characters. */ ++#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) ++#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) ++#define mb_cmp(mbc1, mbc2) \ ++ ((mbc1).wc_valid \ ++ ? ((mbc2).wc_valid \ ++ ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ ++ : -1) \ ++ : ((mbc2).wc_valid \ ++ ? 1 \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ ++ : (mbc1).bytes < (mbc2).bytes \ ++ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ ++ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) ++#define mb_casecmp(mbc1, mbc2) \ ++ ((mbc1).wc_valid \ ++ ? ((mbc2).wc_valid \ ++ ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ ++ : -1) \ ++ : ((mbc2).wc_valid \ ++ ? 1 \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ ++ : (mbc1).bytes < (mbc2).bytes \ ++ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ ++ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) ++#define mb_equal(mbc1, mbc2) \ ++ ((mbc1).wc_valid && (mbc2).wc_valid \ ++ ? (mbc1).wc == (mbc2).wc \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) ++#define mb_caseequal(mbc1, mbc2) \ ++ ((mbc1).wc_valid && (mbc2).wc_valid \ ++ ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) ++ ++/* , classification. */ ++#define mb_isascii(mbc) \ ++ ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) ++#define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) ++#define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) ++#define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) ++#define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) ++#define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) ++#define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) ++#define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) ++#define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) ++#define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) ++#define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) ++#define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) ++#define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) ++ ++/* Extra function. */ ++ ++/* Unprintable characters appear as a small box of width 1. */ ++#define MB_UNPRINTABLE_WIDTH 1 ++ ++MBCHAR_INLINE int ++mb_width_aux (char32_t wc) ++{ ++ int w = c32width (wc); ++ /* For unprintable characters, arbitrarily return 0 for control characters ++ and MB_UNPRINTABLE_WIDTH otherwise. */ ++ return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); ++} ++ ++#define mb_width(mbc) \ ++ ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) ++ ++/* Output. */ ++#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) ++ ++#if defined GNULIB_MBFILE ++/* Assignment. */ ++# define mb_setascii(mbc, sc) \ ++ ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ ++ (mbc)->wc = (mbc)->buf[0] = (sc)) ++#endif ++ ++/* Copying a character. */ ++MBCHAR_INLINE void ++mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) ++{ ++#if defined GNULIB_MBFILE ++ if (old_mbc->ptr == &old_mbc->buf[0]) ++ { ++ memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); ++ new_mbc->ptr = &new_mbc->buf[0]; ++ } ++ else ++#endif ++ new_mbc->ptr = old_mbc->ptr; ++ new_mbc->bytes = old_mbc->bytes; ++ if ((new_mbc->wc_valid = old_mbc->wc_valid)) ++ new_mbc->wc = old_mbc->wc; ++} ++ ++ ++/* is_basic(c) tests whether the single-byte character c is ++ - in the ISO C "basic character set" or is one of '@', '$', and '`' ++ which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in ++ practice are safe to treat as basic in the execution character set, ++ or ++ - in the POSIX "portable character set", which ++ ++ equally guarantees to be single-byte. ++ This is a convenience function, and is in this file only to share code ++ between mbiter.h, mbuiter.h, and mbfile.h. */ ++#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ ++ && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ ++ && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ ++ && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ ++ && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ ++ && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ ++ && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ ++ && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ ++ && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ ++ && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ ++ && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ ++ && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ ++ && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ ++ && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ ++ && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ ++ && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ ++ && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ ++ && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ ++ && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ ++ && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ ++ && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ ++ && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ ++ && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ ++ && ('|' == 124) && ('}' == 125) && ('~' == 126) ++/* The character set is ISO-646, not EBCDIC. */ ++# define IS_BASIC_ASCII 1 ++ ++/* All locale encodings (see localcharset.h) map the characters 0x00..0x7F ++ to U+0000..U+007F, like ASCII, except for ++ CP864 different mapping of '%' ++ SHIFT_JIS different mappings of 0x5C, 0x7E ++ JOHAB different mapping of 0x5C ++ However, these characters in the range 0x20..0x7E are in the ISO C ++ "basic character set" and in the POSIX "portable character set", which ++ ISO C and POSIX guarantee to be single-byte. Thus, locales with these ++ encodings are not POSIX compliant. And they are most likely not in use ++ any more (as of 2023). */ ++# define is_basic(c) ((unsigned char) (c) < 0x80) ++ ++#else ++ ++MBCHAR_INLINE bool ++is_basic (char c) ++{ ++ switch (c) ++ { ++ case '\0': ++ case '\007': case '\010': ++ case '\t': case '\n': case '\v': case '\f': case '\r': ++ case ' ': case '!': case '"': case '#': case '$': case '%': ++ case '&': case '\'': case '(': case ')': case '*': ++ case '+': case ',': case '-': case '.': case '/': ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ case ':': case ';': case '<': case '=': case '>': ++ case '?': case '@': ++ case 'A': case 'B': case 'C': case 'D': case 'E': ++ case 'F': case 'G': case 'H': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': ++ case 'P': case 'Q': case 'R': case 'S': case 'T': ++ case 'U': case 'V': case 'W': case 'X': case 'Y': ++ case 'Z': ++ case '[': case '\\': case ']': case '^': case '_': case '`': ++ case 'a': case 'b': case 'c': case 'd': case 'e': ++ case 'f': case 'g': case 'h': case 'i': case 'j': ++ case 'k': case 'l': case 'm': case 'n': case 'o': ++ case 'p': case 'q': case 'r': case 's': case 't': ++ case 'u': case 'v': case 'w': case 'x': case 'y': ++ case 'z': case '{': case '|': case '}': case '~': ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++#endif ++ ++_GL_INLINE_HEADER_END ++ ++#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 index 0000000..8d2957b @@ -398,6 +809,25 @@ index 0000000..ad61c19 +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ +diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 +new file mode 100644 +index 0000000..471e8c4 +--- /dev/null ++++ b/m4/mbchar.m4 +@@ -0,0 +1,13 @@ ++# mbchar.m4 serial 9 ++dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl autoconf tests required for use of mbchar.m4 ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBCHAR], ++[ ++ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) ++]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 index 0000000..83068a9 @@ -419,7 +849,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index b4edbab..65e4658 100644 +index 061e09c..6d10425 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1079,18 +1509,18 @@ index b4edbab..65e4658 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 89fa56a..c102e6e 100644 +index c95998d..d4386fe 100644 --- a/src/expand-common.c +++ b/src/expand-common.c -@@ -18,6 +18,7 @@ - +@@ -19,6 +19,7 @@ + #include #include #include +#include #include "system.h" #include "fadvise.h" #include "quote.h" -@@ -122,6 +123,119 @@ set_increment_size (uintmax_t tabval) +@@ -123,6 +124,119 @@ set_increment_size (uintmax_t tabval) return ok; } @@ -1211,7 +1641,7 @@ index 89fa56a..c102e6e 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index daed31e..f6b2f68 100644 +index 1a57108..6025652 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; @@ -1234,10 +1664,10 @@ index daed31e..f6b2f68 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index 0e74d0c..7080c51 100644 +index a6176a9..60b1b8e 100644 --- a/src/expand.c +++ b/src/expand.c -@@ -37,6 +37,9 @@ +@@ -38,6 +38,9 @@ #include #include #include @@ -1247,7 +1677,7 @@ index 0e74d0c..7080c51 100644 #include "system.h" #include "expand-common.h" -@@ -95,19 +98,41 @@ expand (void) +@@ -96,19 +99,41 @@ expand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -1293,7 +1723,7 @@ index 0e74d0c..7080c51 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -117,17 +142,48 @@ expand (void) +@@ -118,17 +143,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -1346,7 +1776,7 @@ index 0e74d0c..7080c51 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -146,32 +202,34 @@ expand (void) +@@ -147,32 +203,34 @@ expand (void) if (putchar (' ') < 0) write_error (); @@ -1390,10 +1820,10 @@ index 0e74d0c..7080c51 100644 } diff --git a/src/fold.c b/src/fold.c -index 5c0428d..2372047 100644 +index 941ad11..cf1e747 100644 --- a/src/fold.c +++ b/src/fold.c -@@ -22,10 +22,32 @@ +@@ -23,10 +23,32 @@ #include #include @@ -1426,7 +1856,7 @@ index 5c0428d..2372047 100644 #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -33,20 +55,41 @@ +@@ -34,20 +56,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1472,7 +1902,7 @@ index 5c0428d..2372047 100644 {"spaces", no_argument, nullptr, 's'}, {"width", required_argument, nullptr, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -74,6 +117,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -1480,7 +1910,7 @@ index 5c0428d..2372047 100644 -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -91,7 +135,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -1489,7 +1919,7 @@ index 5c0428d..2372047 100644 { if (c == '\b') { -@@ -114,30 +158,14 @@ adjust_column (size_t column, char c) +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1522,7 +1952,7 @@ index 5c0428d..2372047 100644 fadvise (istream, FADVISE_SEQUENTIAL); -@@ -167,6 +195,15 @@ fold_file (char const *filename, size_t width) +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -1538,7 +1968,7 @@ index 5c0428d..2372047 100644 /* Look for the last blank. */ while (logical_end) { -@@ -213,13 +250,225 @@ fold_file (char const *filename, size_t width) +@@ -214,13 +251,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1766,7 +2196,7 @@ index 5c0428d..2372047 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -250,7 +499,8 @@ main (int argc, char **argv) +@@ -251,7 +500,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1776,7 +2206,7 @@ index 5c0428d..2372047 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -259,7 +509,15 @@ main (int argc, char **argv) +@@ -260,7 +510,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1793,520 +2223,28 @@ index 5c0428d..2372047 100644 break; case 's': /* Break at word boundaries. */ -diff --git a/src/join.c b/src/join.c -index 0bcfa75..8a3bcf1 100644 ---- a/src/join.c -+++ b/src/join.c -@@ -21,18 +21,32 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswblank(), towupper. */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "assure.h" - #include "fadvise.h" - #include "hard-locale.h" - #include "linebuffer.h" --#include "memcasecmp.h" - #include "quote.h" - #include "stdio--.h" - #include "xmemcoll.h" - #include "xstrtol.h" - #include "argmatch.h" - -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "join" - -@@ -134,10 +148,12 @@ static struct outlist outlist_head; - /* Last element in 'outlist', where a new element can be added. */ - static struct outlist *outlist_end = &outlist_head; - --/* Tab character separating fields. If negative, fields are separated -- by any nonempty string of blanks, otherwise by exactly one -- tab character whose value (when cast to unsigned char) equals TAB. */ --static int tab = -1; -+/* Tab character separating fields. If NULL, fields are separated -+ by any nonempty string of blanks. */ -+static char *tab = NULL; -+ -+/* The number of bytes used for tab. */ -+static size_t tablen = 0; - - /* If nonzero, check that the input is correctly ordered. */ - static enum -@@ -277,13 +293,14 @@ xfields (struct line *line) - if (ptr == lim) - return; - -- if (0 <= tab && tab != '\n') -+ if (tab != NULL) - { -+ unsigned char t = tab[0]; - char *sep; -- for (; (sep = memchr (ptr, tab, lim - ptr)) != nullptr; ptr = sep + 1) -+ for (; (sep = memchr (ptr, t, lim - ptr)) != nullptr; ptr = sep + 1) - extract_field (line, ptr, sep - ptr); - } -- else if (tab < 0) -+ else - { - /* Skip leading blanks before the first field. */ - while (field_sep (*ptr)) -@@ -307,6 +324,147 @@ xfields (struct line *line) - extract_field (line, ptr, lim - ptr); - } - -+#if HAVE_MBRTOWC -+static void -+xfields_multibyte (struct line *line) -+{ -+ char *ptr = line->buf.buffer; -+ char const *lim = ptr + line->buf.length - 1; -+ wchar_t wc = 0; -+ size_t mblength = 1; -+ mbstate_t state, state_bak; -+ -+ memset (&state, 0, sizeof (mbstate_t)); -+ -+ if (ptr >= lim) -+ return; -+ -+ if (tab != NULL) -+ { -+ char *sep = ptr; -+ for (; ptr < lim; ptr = sep + mblength) -+ { -+ sep = ptr; -+ while (sep < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (mblength == tablen && !memcmp (sep, tab, mblength)) -+ break; -+ else -+ { -+ sep += mblength; -+ continue; -+ } -+ } -+ -+ if (sep >= lim) -+ break; -+ -+ extract_field (line, ptr, sep - ptr); -+ } -+ } -+ else -+ { -+ /* Skip leading blanks before the first field. */ -+ while(ptr < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (!iswblank(wc) && wc != '\n') -+ break; -+ ptr += mblength; -+ } -+ -+ do -+ { -+ char *sep; -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ sep = ptr + mblength; -+ while (sep < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (iswblank (wc) || wc == '\n') -+ break; -+ -+ sep += mblength; -+ } -+ -+ extract_field (line, ptr, sep - ptr); -+ if (sep >= lim) -+ return; -+ -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ ptr = sep + mblength; -+ while (ptr < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (!iswblank (wc) && wc != '\n') -+ break; -+ -+ ptr += mblength; -+ } -+ } -+ while (ptr < lim); -+ } -+ -+ extract_field (line, ptr, lim - ptr); -+} -+#endif -+ - static void - freeline (struct line *line) - { -@@ -328,56 +486,133 @@ keycmp (struct line const *line1, struct line const *line2, - idx_t jf_1, idx_t jf_2) - { - /* Start of field to compare in each file. */ -- char *beg1; -- char *beg2; -- -- idx_t len1; -- idx_t len2; /* Length of fields to compare. */ -+ char *beg[2]; -+ char *copy[2]; -+ idx_t len[2]; /* Length of fields to compare. */ - int diff; -+ int i, j; -+ int mallocd = 0; - - if (jf_1 < line1->nfields) - { -- beg1 = line1->fields[jf_1].beg; -- len1 = line1->fields[jf_1].len; -+ beg[0] = line1->fields[jf_1].beg; -+ len[0] = line1->fields[jf_1].len; - } - else - { -- beg1 = nullptr; -- len1 = 0; -+ beg[0] = nullptr; -+ len[0] = 0; - } - - if (jf_2 < line2->nfields) - { -- beg2 = line2->fields[jf_2].beg; -- len2 = line2->fields[jf_2].len; -+ beg[1] = line2->fields[jf_2].beg; -+ len[1] = line2->fields[jf_2].len; - } - else - { -- beg2 = nullptr; -- len2 = 0; -+ beg[1] = nullptr; -+ len[1] = 0; - } - -- if (len1 == 0) -- return len2 == 0 ? 0 : -1; -- if (len2 == 0) -+ if (len[0] == 0) -+ return len[1] == 0 ? 0 : -1; -+ if (len[1] == 0) - return 1; - - if (ignore_case) - { -- /* FIXME: ignore_case does not work with NLS (in particular, -- with multibyte chars). */ -- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); -+#ifdef HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ size_t mblength; -+ wchar_t wc, uwc; -+ mbstate_t state, state_bak; -+ -+ memset (&state, '\0', sizeof (mbstate_t)); -+ -+ for (i = 0; i < 2; i++) -+ { -+ mallocd = 1; -+ copy[i] = xmalloc (len[i] + 1); -+ memset (copy[i], '\0',len[i] + 1); -+ -+ for (j = 0; j < MIN (len[0], len[1]);) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); -+ -+ switch (mblength) -+ { -+ case (size_t) -1: -+ case (size_t) -2: -+ state = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; -+ -+ default: -+ uwc = towupper (wc); -+ -+ if (uwc != wc) -+ { -+ mbstate_t state_wc; -+ size_t mblen; -+ -+ memset (&state_wc, '\0', sizeof (mbstate_t)); -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); -+ assert (mblen != (size_t)-1); -+ } -+ else -+ memcpy (copy[i] + j, beg[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ } -+ } -+ else -+#endif -+ { -+ for (i = 0; i < 2; i++) -+ { -+ mallocd = 1; -+ copy[i] = xmalloc (len[i] + 1); -+ -+ for (j = 0; j < MIN (len[0], len[1]); j++) -+ copy[i][j] = toupper (beg[i][j]); -+ -+ copy[i][j] = '\0'; -+ } -+ } - } - else - { -- if (hard_LC_COLLATE) -- return xmemcoll (beg1, len1, beg2, len2); -- diff = memcmp (beg1, beg2, MIN (len1, len2)); -+ copy[0] = beg[0]; -+ copy[1] = beg[1]; - } - -+ if (hard_LC_COLLATE) -+ { -+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); -+ -+ if (mallocd) -+ for (i = 0; i < 2; i++) -+ free (copy[i]); -+ -+ return diff; -+ } -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); -+ -+ if (mallocd) -+ for (i = 0; i < 2; i++) -+ free (copy[i]); -+ -+ - if (diff) - return diff; -- return (len1 > len2) - (len1 < len2); -+ return len[0] - len[1]; - } - - /* Check that successive input lines PREV and CURRENT from input file -@@ -469,6 +704,11 @@ get_line (FILE *fp, struct line **linep, int which) - } - ++line_no[which - 1]; - -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ xfields_multibyte (line); -+ else -+#endif - xfields (line); - - if (prevline[which - 1]) -@@ -562,21 +802,28 @@ prfield (idx_t n, struct line const *line) - - /* Output all the fields in line, other than the join field. */ - -+#define PUT_TAB_CHAR \ -+ do \ -+ { \ -+ (tab != NULL) ? \ -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ -+ } \ -+ while (0) -+ - static void - prfields (struct line const *line, idx_t join_field, idx_t autocount) - { - idx_t i; - idx_t nfields = autoformat ? autocount : line->nfields; -- char output_separator = tab < 0 ? ' ' : tab; - - for (i = 0; i < join_field && i < nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line); - } - for (i = join_field + 1; i < nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line); - } - } -@@ -587,7 +834,6 @@ static void - prjoin (struct line const *line1, struct line const *line2) - { - const struct outlist *outlist; -- char output_separator = tab < 0 ? ' ' : tab; - idx_t field; - struct line const *line; - -@@ -621,7 +867,7 @@ prjoin (struct line const *line1, struct line const *line2) - o = o->next; - if (o == nullptr) - break; -- putchar (output_separator); -+ PUT_TAB_CHAR; - } - putchar (eolchar); - } -@@ -1086,20 +1332,43 @@ main (int argc, char **argv) - - case 't': - { -- unsigned char newtab = optarg[0]; -+ char *newtab = NULL; -+ size_t newtablen; -+ newtab = xstrdup (optarg); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ mbstate_t state; -+ -+ memset (&state, 0, sizeof (mbstate_t)); -+ newtablen = mbrtowc (NULL, newtab, -+ strnlen (newtab, MB_LEN_MAX), -+ &state); -+ if (newtablen == (size_t) 0 -+ || newtablen == (size_t) -1 -+ || newtablen == (size_t) -2) -+ newtablen = 1; -+ } -+ else -+#endif -+ newtablen = 1; - if (! newtab) -- newtab = '\n'; /* '' => process the whole line. */ -+ newtab = (char*)"\n"; /* '' => process the whole line. */ - else if (optarg[1]) - { -- if (STREQ (optarg, "\\0")) -- newtab = '\0'; -- else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); -+ if (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ } -+ if (tab != NULL && strcmp (tab, newtab)) -+ { -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); - } -- if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; -+ tablen = newtablen; - } - break; - diff --git a/src/local.mk b/src/local.mk -index f45b911..6f7036a 100644 +index 96ee941..8fdb8fc 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -447,8 +447,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -450,8 +450,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) -src_expand_SOURCES = src/expand.c src/expand-common.c -src_unexpand_SOURCES = src/unexpand.c src/expand-common.c -+src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c -+src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c ++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c lib/mbchar.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 419545c..702e025 100644 +index 09c6fa8..7552b62 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ + #include #include - #include #include + +/* Get MB_LEN_MAX. */ @@ -2831,7 +2769,7 @@ index 419545c..702e025 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2496,9 +2695,9 @@ read_line (COLUMN *p) +@@ -2495,9 +2694,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2843,7 +2781,7 @@ index 419545c..702e025 100644 padding_not_printed = ANYWHERE; } -@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) +@@ -2566,7 +2765,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2852,7 +2790,7 @@ index 419545c..702e025 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2579,7 +2778,7 @@ print_stored (COLUMN *p) +@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2861,7 +2799,7 @@ index 419545c..702e025 100644 pad_vertically = true; -@@ -2599,9 +2798,9 @@ print_stored (COLUMN *p) +@@ -2598,9 +2797,9 @@ print_stored (COLUMN *p) } } @@ -2873,7 +2811,7 @@ index 419545c..702e025 100644 padding_not_printed = ANYWHERE; } -@@ -2614,8 +2813,8 @@ print_stored (COLUMN *p) +@@ -2613,8 +2812,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2884,7 +2822,7 @@ index 419545c..702e025 100644 } return true; -@@ -2634,7 +2833,7 @@ print_stored (COLUMN *p) +@@ -2633,7 +2832,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2893,7 +2831,7 @@ index 419545c..702e025 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2644,10 +2843,10 @@ char_to_clump (char c) +@@ -2643,10 +2842,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2906,7 +2844,7 @@ index 419545c..702e025 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2728,6 +2927,164 @@ char_to_clump (char c) +@@ -2727,6 +2926,164 @@ char_to_clump (char c) return chars; } @@ -3072,10 +3010,10 @@ index 419545c..702e025 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index e779845..1f5c337 100644 +index 2d8324c..46331b8 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -28,6 +28,14 @@ +@@ -29,6 +29,14 @@ #include #include #include @@ -3148,7 +3086,7 @@ index e779845..1f5c337 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -803,6 +834,46 @@ reap_all (void) +@@ -804,6 +835,46 @@ reap_all (void) reap (-1); } @@ -3195,7 +3133,7 @@ index e779845..1f5c337 100644 /* Clean up any remaining temporary files. */ static void -@@ -1270,7 +1341,7 @@ zaptemp (char const *name) +@@ -1271,7 +1342,7 @@ zaptemp (char const *name) free (node); } @@ -3204,7 +3142,7 @@ index e779845..1f5c337 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1286,7 +1357,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3213,7 +3151,7 @@ index e779845..1f5c337 100644 { size_t i; -@@ -1297,7 +1368,7 @@ inittables (void) +@@ -1298,7 +1369,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3222,7 +3160,7 @@ index e779845..1f5c337 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3307,7 +3245,7 @@ index e779845..1f5c337 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3316,7 +3254,7 @@ index e779845..1f5c337 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3329,7 +3267,7 @@ index e779845..1f5c337 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1648,12 +1797,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3402,7 +3340,7 @@ index e779845..1f5c337 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1668,10 +1876,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3415,7 +3353,7 @@ index e779845..1f5c337 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1717,10 +1925,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3428,7 +3366,7 @@ index e779845..1f5c337 100644 if (newlim) lim = newlim; } -@@ -1751,6 +1959,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3559,7 +3497,7 @@ index e779845..1f5c337 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1837,8 +2169,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3584,7 +3522,7 @@ index e779845..1f5c337 100644 line->keybeg = line_start; } } -@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) +@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3600,7 +3538,7 @@ index e779845..1f5c337 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) +@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3609,7 +3547,7 @@ index e779845..1f5c337 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) +@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3635,7 +3573,7 @@ index e779845..1f5c337 100644 static int nan_compare (long double a, long double b) { -@@ -2044,7 +2407,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3644,7 +3582,7 @@ index e779845..1f5c337 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2320,15 +2683,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2372,15 +2735,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3662,7 +3600,7 @@ index e779845..1f5c337 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2474,7 +2836,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2526,7 +2888,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3671,7 +3609,7 @@ index e779845..1f5c337 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2522,9 +2884,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2574,9 +2936,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3684,7 +3622,7 @@ index e779845..1f5c337 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2535,9 +2897,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3697,7 +3635,7 @@ index e779845..1f5c337 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2545,19 +2907,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2597,19 +2959,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3721,7 +3659,7 @@ index e779845..1f5c337 100644 } } -@@ -2568,7 +2930,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2620,7 +2982,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3730,7 +3668,7 @@ index e779845..1f5c337 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2610,11 +2972,87 @@ diff_reversed (int diff, bool reversed) +@@ -2662,11 +3024,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3819,7 +3757,7 @@ index e779845..1f5c337 100644 { struct keyfield *key = keylist; -@@ -2695,7 +3133,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2747,7 +3185,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3828,7 +3766,7 @@ index e779845..1f5c337 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2805,6 +3243,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2857,6 +3295,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -4040,7 +3978,7 @@ index e779845..1f5c337 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2832,7 +3475,7 @@ compare (struct line const *a, struct line const *b) +@@ -2884,7 +3527,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4049,7 +3987,7 @@ index e779845..1f5c337 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4220,6 +4863,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4272,6 +4915,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4057,7 +3995,7 @@ index e779845..1f5c337 100644 break; case 'g': key->general_numeric = true; -@@ -4299,7 +4943,7 @@ main (int argc, char **argv) +@@ -4351,7 +4995,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4066,7 +4004,7 @@ index e779845..1f5c337 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4322,6 +4966,29 @@ main (int argc, char **argv) +@@ -4374,6 +5018,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4096,7 +4034,7 @@ index e779845..1f5c337 100644 have_read_stdin = false; inittables (); -@@ -4592,13 +5259,34 @@ main (int argc, char **argv) +@@ -4644,13 +5311,34 @@ main (int argc, char **argv) case 't': { @@ -4135,7 +4073,7 @@ index e779845..1f5c337 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4609,9 +5297,11 @@ main (int argc, char **argv) +@@ -4661,9 +5349,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4150,10 +4088,10 @@ index e779845..1f5c337 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index 5a2283f..f24ef76 100644 +index aca67dd..f79c808 100644 --- a/src/unexpand.c +++ b/src/unexpand.c -@@ -38,6 +38,9 @@ +@@ -39,6 +39,9 @@ #include #include #include @@ -4163,7 +4101,7 @@ index 5a2283f..f24ef76 100644 #include "system.h" #include "expand-common.h" -@@ -104,24 +107,47 @@ unexpand (void) +@@ -105,24 +108,47 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -4214,7 +4152,7 @@ index 5a2283f..f24ef76 100644 /* If true, perform translations. */ bool convert = true; -@@ -155,12 +181,44 @@ unexpand (void) +@@ -156,12 +182,44 @@ unexpand (void) do { @@ -4262,7 +4200,7 @@ index 5a2283f..f24ef76 100644 if (blank) { -@@ -177,16 +235,16 @@ unexpand (void) +@@ -178,16 +236,16 @@ unexpand (void) if (next_tab_column < column) error (EXIT_FAILURE, 0, _("input line is too long")); @@ -4282,7 +4220,7 @@ index 5a2283f..f24ef76 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -194,13 +252,14 @@ unexpand (void) +@@ -195,13 +253,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4299,7 +4237,7 @@ index 5a2283f..f24ef76 100644 } /* Discard pending blanks, unless it was a single -@@ -208,7 +267,7 @@ unexpand (void) +@@ -209,7 +268,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4308,7 +4246,7 @@ index 5a2283f..f24ef76 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -218,16 +277,20 @@ unexpand (void) +@@ -219,16 +278,20 @@ unexpand (void) } else { @@ -4333,7 +4271,7 @@ index 5a2283f..f24ef76 100644 write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -237,16 +300,17 @@ unexpand (void) +@@ -238,16 +301,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4354,173 +4292,8 @@ index 5a2283f..f24ef76 100644 } } -diff --git a/src/uniq.c b/src/uniq.c -index fab04de..2e96dcb 100644 ---- a/src/uniq.c -+++ b/src/uniq.c -@@ -21,6 +21,17 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get isw* functions. */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+#include -+ - #include "system.h" - #include "argmatch.h" - #include "linebuffer.h" -@@ -31,6 +42,18 @@ - #include "memcasecmp.h" - #include "quote.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "uniq" - -@@ -137,6 +160,10 @@ enum - GROUP_OPTION = CHAR_MAX + 1 - }; - -+/* Function pointers. */ -+static char * -+(*find_field) (struct linebuffer *line); -+ - static struct option const longopts[] = - { - {"count", no_argument, nullptr, 'c'}, -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) - - ATTRIBUTE_PURE - static char * --find_field (struct linebuffer const *line) -+find_field_uni (struct linebuffer *line) - { - size_t count; - char const *lp = line->buffer; -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) - return line->buffer + i; - } - -+#if HAVE_MBRTOWC -+ -+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ -+ do \ -+ { \ -+ mbstate_t state_bak; \ -+ \ -+ CONVFAIL = 0; \ -+ state_bak = *STATEP; \ -+ \ -+ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ -+ \ -+ switch (MBLENGTH) \ -+ { \ -+ case (size_t)-2: \ -+ case (size_t)-1: \ -+ *STATEP = state_bak; \ -+ CONVFAIL++; \ -+ /* Fall through */ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ } \ -+ } \ -+ while (0) -+ -+static char * -+find_field_multi (struct linebuffer *line) -+{ -+ size_t count; -+ char *lp = line->buffer; -+ size_t size = line->length - 1; -+ size_t pos; -+ size_t mblength; -+ wchar_t wc; -+ mbstate_t *statep; -+ int convfail = 0; -+ -+ pos = 0; -+ statep = &(line->state); -+ -+ /* skip fields. */ -+ for (count = 0; count < skip_fields && pos < size; count++) -+ { -+ while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ -+ if (convfail || !(iswblank (wc) || wc == '\n')) -+ { -+ pos += mblength; -+ break; -+ } -+ pos += mblength; -+ } -+ -+ while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ -+ if (!convfail && (iswblank (wc) || wc == '\n')) -+ break; -+ -+ pos += mblength; -+ } -+ } -+ -+ /* skip fields. */ -+ for (count = 0; count < skip_chars && pos < size; count++) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ pos += mblength; -+ } -+ -+ return lp + pos; -+} -+#endif -+ - /* Return false if two strings OLD and NEW match, true if not. - OLD and NEW point not to the beginnings of the lines - but rather to the beginnings of the fields to compare. -@@ -495,6 +599,19 @@ main (int argc, char **argv) - - atexit (close_stdout); - -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ find_field = find_field_multi; -+ } -+ else -+#endif -+ { -+ find_field = find_field_uni; -+ } -+ -+ -+ - skip_chars = 0; - skip_fields = 0; - check_chars = SIZE_MAX; diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index f147401..3ce5da9 100644 +index 18e7bea..24a141b 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4534,7 +4307,7 @@ index f147401..3ce5da9 100644 { warn "$program_name: $test_name: test name is too long (> $max)\n"; diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -new file mode 100755 +new file mode 100644 index 0000000..dd6007c --- /dev/null +++ b/tests/expand/mb.sh @@ -4723,7 +4496,7 @@ index 0000000..dd6007c + +exit $fail diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh -new file mode 100755 +new file mode 100644 index 0000000..26c95de --- /dev/null +++ b/tests/i18n/sort.sh @@ -4758,10 +4531,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index b74a4a2..fe6e557 100644 +index fdbf369..a6ce49c 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -384,6 +384,8 @@ all_tests = \ +@@ -387,6 +387,8 @@ all_tests = \ tests/sort/sort-discrim.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4770,7 +4543,7 @@ index b74a4a2..fe6e557 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -585,6 +587,7 @@ all_tests = \ +@@ -590,6 +592,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4778,7 +4551,7 @@ index b74a4a2..fe6e557 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -738,6 +741,7 @@ all_tests = \ +@@ -746,6 +749,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4787,7 +4560,7 @@ index b74a4a2..fe6e557 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 06261ac..7dd813e 100755 +index 11f3fc4..d609a2c 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4854,7 +4627,7 @@ index 06261ac..7dd813e 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index a94072f..136a82e 100755 +index 00b4362..7d51bea 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -4926,78 +4699,8 @@ index a94072f..136a82e 100755 -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 2ca8567..1d01a3d 100755 ---- a/tests/misc/join.pl -+++ b/tests/misc/join.pl -@@ -25,6 +25,15 @@ my $limits = getlimits (); - - my $prog = 'join'; - -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ -+my $mb_locale; -+#Comment out next line to disable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - my $delim = chr 0247; - sub t_subst ($) - { -@@ -333,8 +342,49 @@ foreach my $t (@tv) - push @Tests, $new_ent; - } - -+# Add _POSIX2_VERSION=199209 to the environment of each test -+# that uses an old-style option like +1. -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether join is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ #Adjust the output some error messages including test_name for mb -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} -+ (@new_t)) -+ { -+ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; -+ push @new_t, $sub2; -+ push @$t, $sub2; -+ } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ - @Tests = triple_test \@Tests; - -+#skip invalid-j-mb test, it is failing because of the format -+@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh -new file mode 100755 +new file mode 100644 index 0000000..11836ba --- /dev/null +++ b/tests/misc/sort-mb-tests.sh @@ -5048,7 +4751,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index d78a1bc..2b9137d 100755 +index 76bcbd4..59eb819 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -5105,7 +4808,7 @@ index d78a1bc..2b9137d 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index eafc13d..c1eca2a 100755 +index 6b34e0b..34b4aeb 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -5174,7 +4877,7 @@ index eafc13d..c1eca2a 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl -index bd439ef..2ccdf87 100755 +index 89eed0c..b855d73 100755 --- a/tests/sort/sort-merge.pl +++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -5234,7 +4937,7 @@ index bd439ef..2ccdf87 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index 46f1d7a..bb38f5b 100755 +index d49f65f..ebba925 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5302,7 +5005,7 @@ index 46f1d7a..bb38f5b 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -new file mode 100755 +new file mode 100644 index 0000000..8a82d74 --- /dev/null +++ b/tests/unexpand/mb.sh @@ -5479,82 +5182,6 @@ index 0000000..8a82d74 + +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -diff --git a/tests/uniq/uniq.pl b/tests/uniq/uniq.pl -index a6354dc..e43cd6e 100755 ---- a/tests/uniq/uniq.pl -+++ b/tests/uniq/uniq.pl -@@ -23,9 +23,17 @@ my $limits = getlimits (); - my $prog = 'uniq'; - my $try = "Try '$prog --help' for more information.\n"; - -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - -+my $mb_locale; -+#Comment out next line to disable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - # When possible, create a "-z"-testing variant of each test. - sub add_z_variants($) - { -@@ -262,6 +270,53 @@ foreach my $t (@Tests) - and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; - } - -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether uniq is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ # In test #145, replace the each ‘...’ by '...'. -+ if ($test_name =~ "145") -+ { -+ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ next if ( $test_name =~ "schar" -+ or $test_name =~ "^obs-plus" -+ or $test_name =~ "119"); -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+ -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - @Tests = add_z_variants \@Tests; - @Tests = triple_test \@Tests; - -- -2.43.0 +2.44.0 diff --git a/coreutils-python3.patch b/coreutils-python3.patch new file mode 100644 index 0000000..98fc642 --- /dev/null +++ b/coreutils-python3.patch @@ -0,0 +1,65 @@ +From cef9cccce395cd80cd5ac42a4fe6c3909be1c0b5 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 2 Apr 2024 14:11:26 +0100 +Subject: [PATCH] coreutils-python3.patch + +--- + init.cfg | 4 ++-- + tests/d_type-check | 2 +- + tests/du/move-dir-while-traversing.sh | 6 +++--- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/init.cfg b/init.cfg +index b06965a..08413ee 100644 +--- a/init.cfg ++++ b/init.cfg +@@ -581,10 +581,10 @@ seek_data_capable_() + # Skip the current test if "." lacks d_type support. + require_dirent_d_type_() + { +- python < /dev/null \ ++ python3 < /dev/null \ + || skip_ python missing: assuming no d_type support + +- python "$abs_srcdir"/tests/d_type-check \ ++ python3 "$abs_srcdir"/tests/d_type-check \ + || skip_ requires d_type support + } + +diff --git a/tests/d_type-check b/tests/d_type-check +index 1a2f76f..42d3924 100644 +--- a/tests/d_type-check ++++ b/tests/d_type-check +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + # Exit 0 if "." and "./tempfile" have useful d_type information, else 1. + # Intended to exit 0 only on Linux/GNU systems. + import os +diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh +index 830a69e..7344ddf 100755 +--- a/tests/du/move-dir-while-traversing.sh ++++ b/tests/du/move-dir-while-traversing.sh +@@ -21,8 +21,8 @@ print_ver_ du + require_trap_signame_ + + # We use a python-inotify script, so... +-python -m pyinotify -h > /dev/null \ +- || skip_ 'python inotify package not installed' ++python3 -m pyinotify -h > /dev/null \ ++ || skip_ 'python3 inotify package not installed' + + # Move a directory "up" while du is processing its sub-directories. + # While du is processing a hierarchy .../B/C/D/... this script +@@ -33,7 +33,7 @@ python -m pyinotify -h > /dev/null \ + # rename syscall before du finishes processing the subtree under D/. + + cat <<'EOF' > inotify-watch-for-dir-access.py +-#!/usr/bin/env python ++#!/usr/bin/env python3 + import pyinotify as pn + import os,sys + +-- +2.44.0 + diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 66e06e1..a31c3af 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,4 +1,4 @@ -From 88ba186955add2b230c017749d5622f7a0d62177 Mon Sep 17 00:00:00 2001 +From 78970c915b8556fcec4622e948a37dd8e34efe6d Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-selinux.patch @@ -9,10 +9,10 @@ Subject: [PATCH] coreutils-selinux.patch 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cp.c b/src/cp.c -index 04a5cbe..7a364e5 100644 +index 28b0217..897379f 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -989,7 +989,7 @@ main (int argc, char **argv) +@@ -997,7 +997,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -21,7 +21,7 @@ index 04a5cbe..7a364e5 100644 long_opts, nullptr)) != -1) { -@@ -1041,6 +1041,23 @@ main (int argc, char **argv) +@@ -1049,6 +1049,23 @@ main (int argc, char **argv) copy_contents = true; break; @@ -46,7 +46,7 @@ index 04a5cbe..7a364e5 100644 x.preserve_links = true; x.dereference = DEREF_NEVER; diff --git a/src/install.c b/src/install.c -index 31a48f1..ce9fa2d 100644 +index accd0fd..b686fe9 100644 --- a/src/install.c +++ b/src/install.c @@ -807,7 +807,7 @@ main (int argc, char **argv) @@ -83,5 +83,5 @@ index 31a48f1..ce9fa2d 100644 use_default_selinux_context = false; break; -- -2.41.0 +2.44.0 diff --git a/coreutils.spec b/coreutils.spec index f1d68b3..e72ca20 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.4 -Release: 6%{?dist} +Version: 9.5 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -26,18 +26,12 @@ Patch101: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.32-DIR_COLORS.patch +# use python3 in tests +Patch103: coreutils-python3.patch + # df --direct Patch104: coreutils-df-direct.patch -# fix crash with --enable-systemd -Patch105: coreutils-9.4-systemd-coredump.patch - -# fix buffer overflow in split (CVE-2024-0684) -Patch106: coreutils-9.4-CVE-2024-0684.patch - -# fix tail on kernels with 64k pagesize -Patch107: coreutils-9.4-tail-64k-pages.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -70,13 +64,26 @@ BuildRequires: texinfo BuildRequires: gnupg2 # test-only dependencies +BuildRequires: acl +BuildRequires: gdb BuildRequires: perl-interpreter +BuildRequires: perl(Expect) BuildRequires: perl(FileHandle) +BuildRequires: python3 +%if 0%{?fedora} +BuildRequires: python3-inotify +%endif +BuildRequires: tzdata +%ifarch %valgrind_arches +BuildRequires: valgrind +%endif + %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en BuildRequires: glibc-langpack-fr BuildRequires: glibc-langpack-ko +BuildRequires: glibc-langpack-sv %endif Requires: %{name}-common = %{version}-%{release} @@ -262,6 +269,11 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 02 2024 Lukáš Zaoral - 9.5-1 +- rebase to latest upstream version (rhbz#2272063) +- sync i18n patch with SUSE (Kudos to Berny Völker!) +- add some test dependencies to execute additional part of the upstream test-suite + * Mon Jan 29 2024 Lukáš Zaoral - 9.4-6 - fix tail on kernels with 64k page sizes (RHEL-22866) diff --git a/sources b/sources index ac58478..d9dc6c9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.4.tar.xz) = 7c55ee23b685a0462bbbd118b04d25278c902604a0dcf3bf4f8bf81faa0500dee5a7813cba6f586d676c98e520cafd420f16479619305e94ea6798d8437561f5 -SHA512 (coreutils-9.4.tar.xz.sig) = 9674f783f592c4f3e5c708ff31426ac009bf132fd0005019571bf39c8a1627efb5351c6cecc7faecb1eff8fa2970318666593bffc0eda9c750159e174ef42524 +SHA512 (coreutils-9.5.tar.xz) = 2ca0deac4dc10a80fd0c6fd131252e99d457fd03b7bd626a6bc74fe5a0529c0a3d48ce1f5da1d3b3a7a150a1ce44f0fbb6b68a6ac543dfd5baa3e71f5d65401c +SHA512 (coreutils-9.5.tar.xz.sig) = 029997e0f4ee64e561853cff7c8a124f58cc891598595b44c4a46f9813b4b71c9d677464bc8a26d294e9971832f4b87c23777fea4fac6e8e30f06ad93b9957d5 From 56dd448b2652398ad937655e9426281ca4e973e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 4 Jun 2024 12:56:50 +0200 Subject: [PATCH 02/29] enable LTO on ppc64le --- coreutils.spec | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e72ca20..26a9b6c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -157,11 +157,6 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" -# disable -flto on ppc64le to make test-float pass (#1789115) -%ifarch ppc64le -CFLAGS="$CFLAGS -fno-lto" -%endif - # Upstream suggests to build with -Dlint for static analyzers: # https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html # ... and even for production binary RPMs: @@ -269,6 +264,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jun 04 2024 Lukáš Zaoral - 9.5-2 +- enable LTO on ppc64le + * Tue Apr 02 2024 Lukáš Zaoral - 9.5-1 - rebase to latest upstream version (rhbz#2272063) - sync i18n patch with SUSE (Kudos to Berny Völker!) From 1421739c0cc39be1278749b8f5fda27ef00adf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 4 Jul 2024 13:18:36 +0200 Subject: [PATCH 03/29] do not buildrequire perl(Expect) on ELN --- coreutils.spec | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 26a9b6c..3b2ba13 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -67,17 +67,18 @@ BuildRequires: gnupg2 BuildRequires: acl BuildRequires: gdb BuildRequires: perl-interpreter -BuildRequires: perl(Expect) BuildRequires: perl(FileHandle) BuildRequires: python3 -%if 0%{?fedora} -BuildRequires: python3-inotify -%endif BuildRequires: tzdata %ifarch %valgrind_arches BuildRequires: valgrind %endif +%if 0%{?fedora} +BuildRequires: perl(Expect) +BuildRequires: python3-inotify +%endif + %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en @@ -264,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jul 04 2024 Lukáš Zaoral - 9.5-3 +- do not buildrequire perl(Expect) on ELN + * Tue Jun 04 2024 Lukáš Zaoral - 9.5-2 - enable LTO on ppc64le From ba7b19b5bf29c73dcf7451351d43e28cdab6ef6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Apr 2024 15:42:59 +0200 Subject: [PATCH 04/29] Fix build when %_bindir==%_sbindir - Rebuild for https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 3b2ba13..dfc1efc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -213,14 +213,20 @@ for type in separate single; do fi (cd $type && make DESTDIR=$RPM_BUILD_ROOT/$subdir $install) +%if "%{_sbindir}" != "%{_bindir}" # chroot was in /usr/sbin : - mkdir -p $RPM_BUILD_ROOT/$subdir/{%{_bindir},%{_sbindir}} + mkdir -p $RPM_BUILD_ROOT/$subdir/%_sbindir mv $RPM_BUILD_ROOT/$subdir/{%_bindir,%_sbindir}/chroot +%endif # Move multicall variants to *.single. # RemovePathPostfixes will strip that later. if test $type = 'single'; then - for dir in %{_bindir} %{_sbindir} %{_libexecdir}/%{name}; do + for dir in %{_bindir} \ +%if "%{_sbindir}" != "%{_bindir}" +%{_sbindir} \ +%endif +%{_libexecdir}/%{name}; do for bin in $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/$dir/*; do basebin=$(basename $bin) mv $bin $RPM_BUILD_ROOT/$dir/$basebin.single @@ -248,7 +254,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %files single %{_bindir}/*.single +%if "%{_sbindir}" != "%{_bindir}" %{_sbindir}/chroot.single +%endif %dir %{_libexecdir}/coreutils %{_libexecdir}/coreutils/*.so.single # duplicate the license because coreutils-common does not need to be installed From 7c8ffed47081707708c39c7bcf23bdf08b65564d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Jul 2024 14:13:28 +0200 Subject: [PATCH 05/29] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index dfc1efc..e4a8387 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 3%{?dist} +Release: 4%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 9.5-4 +- Rebuilt for the bin-sbin merge + * Thu Jul 04 2024 Lukáš Zaoral - 9.5-3 - do not buildrequire perl(Expect) on ELN From e02261a471f26a190b9995bcfce73fd868b87019 Mon Sep 17 00:00:00 2001 From: Sohum Mendon Date: Sat, 13 Jul 2024 14:02:20 -0700 Subject: [PATCH 06/29] Fix fold exit status for nonexistent files Resolves: rhbz#2296201 --- coreutils-i18n.patch | 2 +- coreutils.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index aa21a35..214c2ac 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2182,7 +2182,7 @@ index 941ad11..cf1e747 100644 + if (istream == NULL) + { + error (0, errno, "%s", filename); -+ return 1; ++ return false; + } + + /* Define how ISTREAM is being folded. */ diff --git a/coreutils.spec b/coreutils.spec index e4a8387..c2804b5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 4%{?dist} +Release: 5%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 15 2024 Sohum Mendon - 9.5-5 +- fix incorrect exit status when fold is called with a non-existent file + * Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 9.5-4 - Rebuilt for the bin-sbin merge From 6cd5ce1d7ef1def8a5cf6ff954a069b16768d565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 15 Jul 2024 14:16:53 +0200 Subject: [PATCH 07/29] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index c2804b5..5609090 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 5%{?dist} +Release: 6%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 15 2024 Lukáš Zaoral - 9.5-6 +- Rebuilt for the bin-sbin merge + * Mon Jul 15 2024 Sohum Mendon - 9.5-5 - fix incorrect exit status when fold is called with a non-existent file From a09814d13c6034dbee940f05b043b90046518fb5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 20:00:43 +0000 Subject: [PATCH 08/29] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 5609090..f31f9b4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 6%{?dist} +Release: 7%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 9.5-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Mon Jul 15 2024 Lukáš Zaoral - 9.5-6 - Rebuilt for the bin-sbin merge From d3137f0cd04f6c716ef7c64ae35aa653e22aefea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 21 Aug 2024 17:32:11 +0200 Subject: [PATCH 09/29] add missing systemd-devel buildrequires Fixes: bf0817f5a59c71d2a72363e457baa5ff8f80cd27 (new upstream release 9.4) --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f31f9b4..db0bd0d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 7%{?dist} +Release: 8%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -58,6 +58,7 @@ BuildRequires: libselinux-utils BuildRequires: make BuildRequires: openssl-devel BuildRequires: strace +BuildRequires: systemd-devel BuildRequires: texinfo # For gpg verification of source tarball @@ -273,6 +274,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Aug 21 2024 Lukáš Zaoral - 9.5-8 +- add missing systemd-devel buildrequires + * Wed Jul 17 2024 Fedora Release Engineering - 9.5-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From e3b928358bf5ce47aaa8fa855b2df2590eda6c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 26 Aug 2024 13:02:12 +0200 Subject: [PATCH 10/29] tests: remove unmaintained STI tests --- .../Makefile | 63 ------------------- .../PURPOSE | 54 ---------------- .../runtest.sh | 60 ------------------ tests/test-basics | 39 ------------ tests/test_basics.yml | 9 --- tests/tests.yml | 2 - 6 files changed, 227 deletions(-) delete mode 100644 tests/readlink-cannot-handle-recursive-symlinks/Makefile delete mode 100644 tests/readlink-cannot-handle-recursive-symlinks/PURPOSE delete mode 100755 tests/readlink-cannot-handle-recursive-symlinks/runtest.sh delete mode 100755 tests/test-basics delete mode 100644 tests/test_basics.yml delete mode 100644 tests/tests.yml diff --git a/tests/readlink-cannot-handle-recursive-symlinks/Makefile b/tests/readlink-cannot-handle-recursive-symlinks/Makefile deleted file mode 100644 index 49d37a7..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Makefile of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlink s -# Description: Test for readlink cannot handle recursive symlinks -# Author: Jan Scotka -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Copyright (c) 2010 Red Hat, Inc. All rights reserved. -# -# This copyrighted material is made available to anyone wishing -# to use, modify, copy, or redistribute it subject to the terms -# and conditions of the GNU General Public License version 2. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write to the Free -# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -export TEST=/CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -export TESTVERSION=1.0 - -BUILT_FILES= - -FILES=$(METADATA) runtest.sh Makefile PURPOSE - -.PHONY: all install download clean - -run: $(FILES) build - ./runtest.sh - -build: $(BUILT_FILES) - chmod a+x runtest.sh - -clean: - rm -f *~ $(BUILT_FILES) - - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @echo "Owner: Jan Scotka " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "Description: Test for readlink cannot handle recursive symlinks" >> $(METADATA) - @echo "Type: Sanity" >> $(METADATA) - @echo "TestTime: 5m" >> $(METADATA) - @echo "RunFor: coreutils" >> $(METADATA) - @echo "Requires: coreutils" >> $(METADATA) - @echo "Priority: Normal" >> $(METADATA) - @echo "License: GPLv2" >> $(METADATA) - @echo "Confidential: no" >> $(METADATA) - @echo "Destructive: no" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE b/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE deleted file mode 100644 index b9fd740..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE +++ /dev/null @@ -1,54 +0,0 @@ -PURPOSE of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -Description: Test for readlink cannot handle recursive symlinks -Author: Jan Scotka -Bug summary: readlink cannot handle recursive symlinks - -Description: - -Description of problem: -The readlink command fails with an error "Too many levels of symbolic links", even if there are only 2 levels. - -The readlink command from RHEL 3 and RHEL 4 and from Fedora 11 all work fine. - -Among other changes between RHEL 4 and RHEL 5, RHEL 5's coreutils added calls to cycle_check() in lib/canonicalize.c, but in upstream canonicalize.c (now in gnulib instead of coreutils), we see the comment: - /* Detect loops. We cannot use the cycle-check module here, - since it's actually possible to encounter the same symlink - more than once in a given traversal. However, encountering - the same symlink,NAME pair twice does indicate a loop. */ - -http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/canonicalize.c;h=4f348398fd69ae516396313d18ac294a4ca3dde3;hb=b653eda3ac4864de205419d9f41eec267cb89eeb#l262 - -The latest canonicalize.c uses seen_triple() instead of cycle_check(). - - -Version-Release number of selected component (if applicable): -coreutils-5.97-19.el5 - -How reproducible: -every time - -Steps to Reproduce: -1. Create a directory with a symlink to itself - mkdir /tmp/dir - cd /tmp/dir - ln -s ../dir dirlink - -2. Run readlink using the 'dirlink' symlink recursively - readlink -v -f dirlink - readlink -v -f dirlink/dirlink - readlink -v -f dirlink/dirlink/dirlink - -Actual results: -The first readlink command on just dirlink succeeds, but the 2nd and 3rd commands fail with - readlink: dirlink/dirlink: Too many levels of symbolic links - -Expected results: -$ readlink -v -f dirlink -/tmp/dir -$ readlink -v -f dirlink/dirlink -/tmp/dir -$ readlink -v -f dirlink/dirlink/dirlink -/tmp/dir - - -Additional info: diff --git a/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh b/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh deleted file mode 100755 index 6ee251f..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# runtest.sh of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -# Description: Test for readlink cannot handle recursive symlinks -# Author: Jan Scotka -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Copyright (c) 2010 Red Hat, Inc. All rights reserved. -# -# This copyrighted material is made available to anyone wishing -# to use, modify, copy, or redistribute it subject to the terms -# and conditions of the GNU General Public License version 2. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write to the Free -# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -# Include rhts environment -. /usr/bin/rhts-environment.sh -. /usr/lib/beakerlib/beakerlib.sh - -PACKAGE="coreutils" - -rlJournalStart - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory" - rlRun "pushd $TmpDir" - rlRun "mkdir link" 0 "Creating test directory" - rlRun "cd link" 0 "cd to this dir" - rlRun "ln -s ../link link" 0 "creating symlink to ../link -> link" - rlPhaseEnd - - rlPhaseStartTest - rlLog "Test of readlink up to 20 iteration" - export TMPVAR="link" - for foo in `seq 20` - do echo $TMPVAR - rlRun "readlink -v -f $TMPVAR" 0 "readlink of $TMPVAR" - TMPVAR="$TMPVAR/link" - done - rlPhaseEnd - - rlPhaseStartCleanup - rlRun "popd" - rlRun "rm -r $TmpDir" 0 "Removing tmp directory" - rlPhaseEnd -rlJournalPrintText -rlJournalEnd diff --git a/tests/test-basics b/tests/test-basics deleted file mode 100755 index 7324553..0000000 --- a/tests/test-basics +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# Checks that touch ls rm and foo work -# https://www.mankier.com/1/beakerlib#Examples -. /usr/share/beakerlib/beakerlib.sh - -# Set the full test name -TEST="/examples/beakerlib/Sanity/phases" - -# Package being tested -PACKAGE="coreutils" - -rlJournalStart - # Setup phase: Prepare test directory - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun 'TmpDir=$(mktemp -d)' 0 'Creating tmp directory' # no-reboot - rlRun "pushd $TmpDir" - rlPhaseEnd - - # Test phase: Testing touch, ls and rm commands - rlPhaseStartTest - rlRun "touch foo" 0 "Creating the foo test file" - rlAssertExists "foo" - rlRun "ls -l foo" 0 "Listing the foo test file" - rlRun "rm foo" 0 "Removing the foo test file" - rlAssertNotExists "foo" - rlRun "ls -l foo" 2 "Listing foo should now report an error" - rlPhaseEnd - - # Cleanup phase: Remove test directory - rlPhaseStartCleanup - rlRun "popd" - rlRun "rm -r $TmpDir" 0 "Removing tmp directory" - rlPhaseEnd -rlJournalEnd - -# Print the test report -rlJournalPrintText diff --git a/tests/test_basics.yml b/tests/test_basics.yml deleted file mode 100644 index d5727cf..0000000 --- a/tests/test_basics.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# This first play always runs on the local staging system -- hosts: localhost - tags: - - atomic - - classic - - container - roles: - - { role: standard-test-beakerlib, tests: [ test-basics, readlink-cannot-handle-recursive-symlinks ] } diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 529263d..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Fedora Continuous Integration: https://fedoraproject.org/wiki/CI -- include: test_basics.yml From 968cac099dbdfedbc529c2fb2b462ebc29996de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 27 Aug 2024 12:58:15 +0200 Subject: [PATCH 11/29] show web sessions in who output Resolves: rhbz#2307847 --- coreutils-9.5-readutmp-web-session.patch | 39 ++++++++++++++++++++++++ coreutils.spec | 9 +++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.5-readutmp-web-session.patch diff --git a/coreutils-9.5-readutmp-web-session.patch b/coreutils-9.5-readutmp-web-session.patch new file mode 100644 index 0000000..32a87fe --- /dev/null +++ b/coreutils-9.5-readutmp-web-session.patch @@ -0,0 +1,39 @@ +From 43f7f428a1665950233557bd97611bd5e996b5cb Mon Sep 17 00:00:00 2001 +From: Bruno Haible +Date: Tue, 27 Aug 2024 11:46:33 +0200 +Subject: readutmp: In systemd mode, show sessions of type "web". + +Reported by Allison Karlitskaya in +. + +* lib/readutmp.c (read_utmp_from_systemd): For a systemd session of type +"web", add a single USER_PROCESS entry. + +Upstream-commit: 43f7f428a1665950233557bd97611bd5e996b5cb +Cherry-picked-by: Lukáš Zaoral +--- + lib/readutmp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/readutmp.c b/lib/readutmp.c +index 10d79d1..3c4f97b 100644 +--- a/lib/readutmp.c ++++ b/lib/readutmp.c +@@ -867,6 +867,14 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) + else if (pty != NULL) + tty = pty; + } ++ else if (strcmp (type, "web") == 0) ++ { ++ char *service; ++ if (sd_session_get_service (session, &service) < 0) ++ service = NULL; ++ ++ tty = service; ++ } + } + + /* Create up to two USER_PROCESS entries: one for the seat, +-- +cgit v1.1 + diff --git a/coreutils.spec b/coreutils.spec index db0bd0d..e4c3cb4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 8%{?dist} +Release: 9%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,10 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# coreutils no longer lists Cockpit logins in `who` (rhbz#2307847) +# https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb +Patch105: coreutils-9.5-readutmp-web-session.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -274,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Aug 27 2024 Lukáš Zaoral - 9.5-9 +- show web sessions in who output (rhbz#2307847) + * Wed Aug 21 2024 Lukáš Zaoral - 9.5-8 - add missing systemd-devel buildrequires From 8080f5a15a20362c10d4c46c471d4a4a486e9e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 27 Sep 2024 10:31:35 +0200 Subject: [PATCH 12/29] fix fold -b with UTF8 locale Fixes the following incorrect behaviour of fold caused by the i18n patch: ``` $ LC_ALL=en_US.UTF-8 fold -b -w6 <<< $'1234567890\nabcdefghij\n1234567890\n' 123456 7890 a bcdefg hij 12 345678 90 ``` Fixes: 97967f71c8772354f87dfff4edfe24fb213c8557 ("coreutils-i18n.patch: synchronize the patch with openSUSE") Resolves: RHE L-60295 --- coreutils-i18n.patch | 65 ++++++++++++++++++++++---------------------- coreutils.spec | 5 +++- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 214c2ac..92f35b5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From 94cf02dfcb1be23dedf8a39af295f28ee2de6013 Mon Sep 17 00:00:00 2001 +From a54e632beb3a3f1f980103deea1cf9a8bdd164ac Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -17,7 +17,7 @@ Subject: [PATCH] coreutils-i18n.patch src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- - src/fold.c | 312 ++++++++++++-- + src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- @@ -34,7 +34,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3605 insertions(+), 196 deletions(-) + 30 files changed, 3604 insertions(+), 196 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -1820,7 +1820,7 @@ index a6176a9..60b1b8e 100644 } diff --git a/src/fold.c b/src/fold.c -index 941ad11..cf1e747 100644 +index 941ad11..bdc466d 100644 --- a/src/fold.c +++ b/src/fold.c @@ -23,10 +23,32 @@ @@ -1968,7 +1968,7 @@ index 941ad11..cf1e747 100644 /* Look for the last blank. */ while (logical_end) { -@@ -214,13 +251,225 @@ fold_file (char const *filename, size_t width) +@@ -214,13 +251,224 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -2066,39 +2066,38 @@ index 941ad11..cf1e747 100644 + } + +rescan: -+ if (operating_mode == byte_mode) /* byte mode */ ++ if (convfail) ++ increment = 1; ++ else if (wc == L'\n') ++ { ++ /* preserve newline */ ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; ++ } ++ else if (operating_mode == byte_mode) /* byte mode */ + increment = mblength; + else if (operating_mode == character_mode) /* character mode */ + increment = 1; -+ else /* column mode */ ++ else /* column mode */ + { -+ if (convfail) -+ increment = 1; -+ else ++ switch (wc) + { -+ switch (wc) -+ { -+ case L'\n': -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; + -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; ++ case L'\r': ++ increment = -1 * column; ++ break; + -+ case L'\r': -+ increment = -1 * column; -+ break; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; + } + } + @@ -2196,7 +2195,7 @@ index 941ad11..cf1e747 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -251,7 +500,8 @@ main (int argc, char **argv) +@@ -251,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2206,7 +2205,7 @@ index 941ad11..cf1e747 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -260,7 +510,15 @@ main (int argc, char **argv) +@@ -260,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -5183,5 +5182,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.44.0 +2.46.1 diff --git a/coreutils.spec b/coreutils.spec index e4c3cb4..744b454 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 9%{?dist} +Release: 10%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -278,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Sep 27 2024 Lukáš Zaoral - 9.5-10 +- fix fold -b with UTF8 locale (RHEL-60295) + * Tue Aug 27 2024 Lukáš Zaoral - 9.5-9 - show web sessions in who output (rhbz#2307847) From a6d9263e25f2383f18c1f5f949c352a70c33d541 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 11 Nov 2024 11:12:44 +0100 Subject: [PATCH 13/29] Affinity mask handling in nproc for large CPU counts --- coreutils-nproc-affinity.patch | 44 ++++++++++++++++++++++++++++++++++ coreutils.spec | 4 +++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 coreutils-nproc-affinity.patch diff --git a/coreutils-nproc-affinity.patch b/coreutils-nproc-affinity.patch new file mode 100644 index 0000000..8c682d4 --- /dev/null +++ b/coreutils-nproc-affinity.patch @@ -0,0 +1,44 @@ +diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c +--- coreutils-9.5.orig/lib/nproc.c 2024-01-01 14:21:47.000000000 +0100 ++++ coreutils-9.5/lib/nproc.c 2024-11-11 10:48:05.435716502 +0100 +@@ -20,6 +20,7 @@ + #include + #include "nproc.h" + ++#include + #include + #include + #include +@@ -124,6 +125,31 @@ + return count; + } + } ++#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ ++ && defined CPU_COUNT /* glibc >= 2.3.4 */ ++ { ++ unsigned int alloc_count = 1024; ++ while (1) ++ { ++ cpu_set_t *set = CPU_ALLOC (alloc_count); ++ unsigned int size = CPU_ALLOC_SIZE (alloc_count); ++ if (sched_getaffinity (0, size, set) == 0) ++ { ++ unsigned int count = CPU_COUNT_S (size, set); ++ CPU_FREE (set); ++ return count; ++ } ++ if (errno != EINVAL) ++ { ++ CPU_FREE (set); ++ return 0; ++ } ++ CPU_FREE (set); ++ alloc_count *= 2; ++ if (alloc_count == 0) ++ return 0; ++ } ++ } + #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ + { + cpu_set_t set; +Only in coreutils-9.5/lib: nproc.c~ diff --git a/coreutils.spec b/coreutils.spec index 744b454..71334b9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 10%{?dist} +Release: 10%{?dist}.nproc.1 # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,8 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb Patch105: coreutils-9.5-readutmp-web-session.patch +Patch106: coreutils-nproc-affinity.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch From ddff633d0f852db9dc74c6ea6c81a51fd383901e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 13 Nov 2024 09:54:55 +0100 Subject: [PATCH 14/29] Switch to upstream version of nproc affinity mask fix (rhbz#2325167) --- ....patch => coreutils-nproc-affinity-1.patch | 23 +++++-- coreutils-nproc-affinity-2.patch | 64 +++++++++++++++++++ coreutils.spec | 9 ++- 3 files changed, 88 insertions(+), 8 deletions(-) rename coreutils-nproc-affinity.patch => coreutils-nproc-affinity-1.patch (60%) create mode 100644 coreutils-nproc-affinity-2.patch diff --git a/coreutils-nproc-affinity.patch b/coreutils-nproc-affinity-1.patch similarity index 60% rename from coreutils-nproc-affinity.patch rename to coreutils-nproc-affinity-1.patch index 8c682d4..8748d4e 100644 --- a/coreutils-nproc-affinity.patch +++ b/coreutils-nproc-affinity-1.patch @@ -1,6 +1,16 @@ -diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c ---- coreutils-9.5.orig/lib/nproc.c 2024-01-01 14:21:47.000000000 +0100 -+++ coreutils-9.5/lib/nproc.c 2024-11-11 10:48:05.435716502 +0100 +commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357 +Author: Florian Weimer +Date: Mon Nov 11 14:05:53 2024 +0100 + + nproc: Use affinity mask even on systems with more than 1024 CPUs. + + * lib/nproc.c (num_processors_via_affinity_mask): Retry + with larger affinity masks if CPU_ALLOC_SIZE is available. + +diff --git a/lib/nproc.c b/lib/nproc.c +index 92a07e8289..48bc3d06fa 100644 +--- a/lib/nproc.c ++++ b/lib/nproc.c @@ -20,6 +20,7 @@ #include #include "nproc.h" @@ -9,17 +19,19 @@ diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c #include #include #include -@@ -124,6 +125,31 @@ +@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void) return count; } } +#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -+ && defined CPU_COUNT /* glibc >= 2.3.4 */ ++ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ + { + unsigned int alloc_count = 1024; + while (1) + { + cpu_set_t *set = CPU_ALLOC (alloc_count); ++ if (set == NULL) ++ return 0; + unsigned int size = CPU_ALLOC_SIZE (alloc_count); + if (sched_getaffinity (0, size, set) == 0) + { @@ -41,4 +53,3 @@ diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ { cpu_set_t set; -Only in coreutils-9.5/lib: nproc.c~ diff --git a/coreutils-nproc-affinity-2.patch b/coreutils-nproc-affinity-2.patch new file mode 100644 index 0000000..aeca09c --- /dev/null +++ b/coreutils-nproc-affinity-2.patch @@ -0,0 +1,64 @@ +commit ee0bc695303775da5026091a65e8ec2b764f4a26 +Author: Bruno Haible +Date: Mon Nov 11 15:40:52 2024 +0100 + + nproc: Use affinity mask even in out-of-memory situations. + + * lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated + cpu_set_t as fallback. Add comments. + +diff --git a/lib/nproc.c b/lib/nproc.c +index 48bc3d06fa..0b5898d88f 100644 +--- a/lib/nproc.c ++++ b/lib/nproc.c +@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void) + return count; + } + } +-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ +- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ ++#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ ++ /* There are two ways to use the sched_getaffinity() function: ++ - With a statically-sized cpu_set_t. ++ - With a dynamically-sized cpu_set_t. ++ Documentation: ++ ++ ++ The second way has the advantage that it works on systems with more than ++ 1024 CPUs. The first way has the advantage that it works also when memory ++ is tight. */ ++# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ + { + unsigned int alloc_count = 1024; +- while (1) ++ for (;;) + { + cpu_set_t *set = CPU_ALLOC (alloc_count); + if (set == NULL) +- return 0; ++ /* Out of memory. */ ++ break; + unsigned int size = CPU_ALLOC_SIZE (alloc_count); + if (sched_getaffinity (0, size, set) == 0) + { +@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void) + } + if (errno != EINVAL) + { ++ /* Some other error. */ + CPU_FREE (set); + return 0; + } + CPU_FREE (set); ++ /* Retry with some larger cpu_set_t. */ + alloc_count *= 2; + if (alloc_count == 0) ++ /* Integer overflow. Avoid an endless loop. */ + return 0; + } + } +-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ ++# endif + { + cpu_set_t set; + diff --git a/coreutils.spec b/coreutils.spec index 71334b9..759434b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 10%{?dist}.nproc.1 +Release: 11%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,7 +36,9 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb Patch105: coreutils-9.5-readutmp-web-session.patch -Patch106: coreutils-nproc-affinity.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2325167 +Patch106: coreutils-nproc-affinity-1.patch +Patch107: coreutils-nproc-affinity-2.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -280,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Nov 13 2024 Florian Weimer - 9.5-11 +- Affinity mask handling in nproc for large CPU counts (rhbz#2325167) + * Fri Sep 27 2024 Lukáš Zaoral - 9.5-10 - fix fold -b with UTF8 locale (RHEL-60295) From e847b805f8bd1c11e99dc1465a479a5b6cfb1bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:23:54 +0100 Subject: [PATCH 15/29] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 759434b..56c3746 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 11%{?dist} +Release: 12%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 9.5-12 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Wed Nov 13 2024 Florian Weimer - 9.5-11 - Affinity mask handling in nproc for large CPU counts (rhbz#2325167) From c71c8701f4d6f32da90ead63775636ada91e6de1 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 14:32:40 +0000 Subject: [PATCH 16/29] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 56c3746..b6b0f0f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 12%{?dist} +Release: 13%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 9.5-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 9.5-12 - Rebuilt for the bin-sbin merge (2nd attempt) From ec87f84093f49c9ed9484ca2066dbdc8ea1772cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 20 Jan 2025 12:26:44 +0100 Subject: [PATCH 17/29] rebase to latest upstream version Resolves: rhbz#2338620 --- coreutils-8.32-DIR_COLORS.patch | 14 +- coreutils-9.5-readutmp-web-session.patch | 39 --- coreutils-9.6-ls-selinux-crash.patch | 77 ++++++ coreutils-df-direct.patch | 28 +-- coreutils-i18n.patch | 308 +++++++++++------------ coreutils-nproc-affinity-1.patch | 55 ---- coreutils-nproc-affinity-2.patch | 64 ----- coreutils-python3.patch | 10 +- coreutils-selinux.patch | 12 +- coreutils.spec | 22 +- sources | 4 +- 11 files changed, 277 insertions(+), 356 deletions(-) delete mode 100644 coreutils-9.5-readutmp-web-session.patch create mode 100644 coreutils-9.6-ls-selinux-crash.patch delete mode 100644 coreutils-nproc-affinity-1.patch delete mode 100644 coreutils-nproc-affinity-2.patch diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index ee037bf..021d2a5 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -36,9 +36,9 @@ index b465771..ad42b09 100644 ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to +MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 00 # file with capability (very expensive to lookup) + SETUID 37;41 # regular file that is setuid (u+s) + SETGID 30;43 # regular file that is setgid (g+s) + CAPABILITY 00 # regular file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor index eab6258..1627b63 100644 --- a/DIR_COLORS.lightbgcolor @@ -83,13 +83,13 @@ index eab6258..1627b63 100644 ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to +MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 00 # file with capability (very expensive to lookup) + SETUID 37;41 # regular file that is setuid (u+s) + SETGID 30;43 # regular file that is setgid (g+s) + CAPABILITY 00 # regular file with capability (very expensive to lookup) @@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - # This is for files with execute permission: + # This is for regular files with execute permission: -EXEC 01;32 +EXEC 00;32 diff --git a/coreutils-9.5-readutmp-web-session.patch b/coreutils-9.5-readutmp-web-session.patch deleted file mode 100644 index 32a87fe..0000000 --- a/coreutils-9.5-readutmp-web-session.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 43f7f428a1665950233557bd97611bd5e996b5cb Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Tue, 27 Aug 2024 11:46:33 +0200 -Subject: readutmp: In systemd mode, show sessions of type "web". - -Reported by Allison Karlitskaya in -. - -* lib/readutmp.c (read_utmp_from_systemd): For a systemd session of type -"web", add a single USER_PROCESS entry. - -Upstream-commit: 43f7f428a1665950233557bd97611bd5e996b5cb -Cherry-picked-by: Lukáš Zaoral ---- - lib/readutmp.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/lib/readutmp.c b/lib/readutmp.c -index 10d79d1..3c4f97b 100644 ---- a/lib/readutmp.c -+++ b/lib/readutmp.c -@@ -867,6 +867,14 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) - else if (pty != NULL) - tty = pty; - } -+ else if (strcmp (type, "web") == 0) -+ { -+ char *service; -+ if (sd_session_get_service (session, &service) < 0) -+ service = NULL; -+ -+ tty = service; -+ } - } - - /* Create up to two USER_PROCESS entries: one for the seat, --- -cgit v1.1 - diff --git a/coreutils-9.6-ls-selinux-crash.patch b/coreutils-9.6-ls-selinux-crash.patch new file mode 100644 index 0000000..70837cc --- /dev/null +++ b/coreutils-9.6-ls-selinux-crash.patch @@ -0,0 +1,77 @@ +From 915004f403cb25fadb207ddfdbe6a2f43bd44fac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 17 Jan 2025 17:29:34 +0000 +Subject: [PATCH] ls: fix crash with --context + +* src/ls.c (main): Flag that we need to stat() +if we're going to get security context (call file_has_aclinfo_cache). +(file_has_aclinfo_cache): Be defensive and only lookup the device +for the file if the stat has been performed. +(has_capability_cache): Likewise. +* tests/ls/selinux-segfault.sh: Add a test case. +Reported by Bruno Haible. +--- + src/ls.c | 10 +++++----- + tests/ls/selinux-segfault.sh | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/ls.c b/src/ls.c +index 3215360216..f67167f160 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1768,7 +1768,7 @@ main (int argc, char **argv) + + format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size) + | (format == long_format) +- | print_block_size | print_hyperlink); ++ | print_block_size | print_hyperlink | print_scontext); + format_needs_type = ((! format_needs_stat) + & (recursive | print_with_color | print_scontext + | directories_first +@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, + static int unsupported_scontext_err; + static dev_t unsupported_device; + +- if (f->stat.st_dev == unsupported_device) ++ if (f->stat_ok && f->stat.st_dev == unsupported_device) + { + ai->buf = ai->u.__gl_acl_ch; + ai->size = 0; +@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, + errno = 0; + int n = file_has_aclinfo (file, ai, flags); + int err = errno; +- if (n <= 0 && !acl_errno_valid (err)) ++ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)) + { + unsupported_return = n; + unsupported_scontext = ai->scontext; +@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f) + found that has_capability fails indicating lack of support. */ + static dev_t unsupported_device; + +- if (f->stat.st_dev == unsupported_device) ++ if (f->stat_ok && f->stat.st_dev == unsupported_device) + { + errno = ENOTSUP; + return 0; + } + + bool b = has_capability (file); +- if ( !b && !acl_errno_valid (errno)) ++ if (f->stat_ok && !b && !acl_errno_valid (errno)) + unsupported_device = f->stat.st_dev; + return b; + } +diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh +index 11623acb3f..1cac2b5fc0 100755 +--- a/tests/ls/selinux-segfault.sh ++++ b/tests/ls/selinux-segfault.sh +@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_ + ln -sf missing sedir/broken || framework_failure_ + returns_ 1 ls -L -R -Z -m sedir > out || fail=1 + ++# ls 9.6 would segfault with the following ++ls -Z . > out || fail=1 ++ + Exit $fail diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index f29a065..d19ec29 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From f072852456c545bd89296bc88cf59ccd63287a68 Mon Sep 17 00:00:00 2001 +From d179da4730f414069dd2c0ac995a32398718916c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 8f7f43e..230f1f1 100644 +index ec58f6c..17cda80 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12427,6 +12427,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index 8f7f43e..230f1f1 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 994f0e3..ceee209 100644 +index 5c7efd8..52ece19 100644 --- a/src/df.c +++ b/src/df.c -@@ -121,6 +121,9 @@ static bool print_type; +@@ -122,6 +122,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index 994f0e3..ceee209 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -247,13 +250,15 @@ enum +@@ -249,13 +252,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,10 +59,10 @@ index 994f0e3..ceee209 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -574,7 +579,10 @@ get_header (void) - for (col = 0; col < ncolumns; col++) +@@ -571,7 +576,10 @@ get_header (void) + for (idx_t col = 0; col < ncolumns; col++) { - char *cell = nullptr; + char *cell; - char const *header = _(columns[col]->caption); + char const *header = (columns[col]->field == TARGET_FIELD + && direct_statfs)? @@ -71,7 +71,7 @@ index 994f0e3..ceee209 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1471,6 +1479,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1452,6 +1460,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 994f0e3..ceee209 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1541,6 +1560,7 @@ or all file systems by default.\n\ +@@ -1522,6 +1541,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 994f0e3..ceee209 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1631,6 +1651,9 @@ main (int argc, char **argv) +@@ -1616,6 +1636,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 994f0e3..ceee209 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1727,6 +1750,13 @@ main (int argc, char **argv) +@@ -1712,6 +1735,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.44.0 +2.48.1 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 92f35b5..e7699c1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From a54e632beb3a3f1f980103deea1cf9a8bdd164ac Mon Sep 17 00:00:00 2001 +From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -21,20 +21,20 @@ Subject: [PATCH] coreutils-i18n.patch src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- - src/unexpand.c | 102 ++++- + src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 50 ++- + tests/misc/fold.pl | 51 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3604 insertions(+), 196 deletions(-) + 30 files changed, 3603 insertions(+), 197 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -47,10 +47,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 126e1e8..b4ccebf 100644 +index 380fa11..ca80e6f 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -163,6 +163,8 @@ gnulib_modules=" +@@ -165,6 +165,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +60,10 @@ index 126e1e8..b4ccebf 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 9cb6ee1..1131ce3 100644 +index bf6da2a..321016d 100644 --- a/configure.ac +++ b/configure.ac -@@ -504,6 +504,12 @@ fi +@@ -505,6 +505,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -77,12 +77,12 @@ index 9cb6ee1..1131ce3 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index ae0d55d..5bf5350 100644 +index ca56f80..509b7e6 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h -@@ -22,6 +22,11 @@ - # include "idx.h" - # include +@@ -27,6 +27,11 @@ extern "C" { + #endif + +/* Get mbstate_t. */ +# if HAVE_WCHAR_H @@ -92,7 +92,7 @@ index ae0d55d..5bf5350 100644 /* A 'struct linebuffer' holds a line of text. */ struct linebuffer -@@ -29,6 +34,9 @@ struct linebuffer +@@ -34,6 +39,9 @@ struct linebuffer idx_t size; /* Allocated. */ idx_t length; /* Used. */ char *buffer; @@ -849,7 +849,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index 061e09c..6d10425 100644 +index b424997..c9f181c 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1509,7 +1509,7 @@ index 061e09c..6d10425 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index c95998d..d4386fe 100644 +index 2dbbbe4..91a90a3 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1518,9 +1518,9 @@ index c95998d..d4386fe 100644 #include +#include #include "system.h" + #include "c-ctype.h" #include "fadvise.h" - #include "quote.h" -@@ -123,6 +124,119 @@ set_increment_size (uintmax_t tabval) +@@ -123,6 +124,119 @@ set_increment_size (colno tabval) return ok; } @@ -1641,10 +1641,10 @@ index c95998d..d4386fe 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index 1a57108..6025652 100644 +index fe6c8ed..80a1280 100644 --- a/src/expand-common.h +++ b/src/expand-common.h -@@ -25,6 +25,18 @@ extern size_t max_column_width; +@@ -29,6 +29,18 @@ extern idx_t max_column_width; /* The desired exit status. */ extern int exit_status; @@ -1662,9 +1662,9 @@ index 1a57108..6025652 100644 + /* Add tab stop TABVAL to the end of 'tab_list'. */ extern void - add_tab_stop (uintmax_t tabval); + add_tab_stop (colno tabval); diff --git a/src/expand.c b/src/expand.c -index a6176a9..60b1b8e 100644 +index 5ec7ce9..65ac315 100644 --- a/src/expand.c +++ b/src/expand.c @@ -38,6 +38,9 @@ @@ -1725,7 +1725,7 @@ index a6176a9..60b1b8e 100644 @@ -118,17 +143,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ - size_t tab_index = 0; + idx_t tab_index = 0; - /* Convert a line of text. */ @@ -1775,8 +1775,8 @@ index a6176a9..60b1b8e 100644 + if (mb_iseq (c, '\t')) { /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -@@ -147,32 +203,34 @@ expand (void) + bool last_tab; +@@ -139,31 +195,33 @@ expand (void) if (putchar (' ') < 0) write_error (); @@ -1795,14 +1795,13 @@ index a6176a9..60b1b8e 100644 + /* A leading control character could make us trip over. */ + else if (!mb_iscntrl (c)) { -- column++; -+ column += mb_width (c); - if (!column) +- if (ckd_add (&column, column, 1)) ++ if (ckd_add (&column, column, mb_width (c))) error (EXIT_FAILURE, 0, _("input line is too long")); } - convert &= convert_entire_line || !! isblank (c); -+ convert &= convert_entire_line || mb_isblank (c); ++ convert &= convert_entire_line || !! mb_isblank (c); } - if (c < 0) @@ -1820,7 +1819,7 @@ index a6176a9..60b1b8e 100644 } diff --git a/src/fold.c b/src/fold.c -index 941ad11..bdc466d 100644 +index b64aad4..a156337 100644 --- a/src/fold.c +++ b/src/fold.c @@ -23,10 +23,32 @@ @@ -1931,9 +1930,9 @@ index 941ad11..bdc466d 100644 - FILE *istream; int c; size_t column = 0; /* Screen column where next char will go. */ - size_t offset_out = 0; /* Index in 'line_out' for next char. */ + idx_t offset_out = 0; /* Index in 'line_out' for next char. */ static char *line_out = nullptr; - static size_t allocated_out = 0; + static idx_t allocated_out = 0; - int saved_errno; - - if (STREQ (filename, "-")) @@ -1954,7 +1953,7 @@ index 941ad11..bdc466d 100644 @@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; - size_t logical_end = offset_out; + idx_t logical_end = offset_out; + /* If LINE_OUT has no wide character, + put a new wide character in LINE_OUT @@ -1968,7 +1967,7 @@ index 941ad11..bdc466d 100644 /* Look for the last blank. */ while (logical_end) { -@@ -214,13 +251,224 @@ fold_file (char const *filename, size_t width) +@@ -212,13 +249,224 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1979,7 +1978,7 @@ index 941ad11..bdc466d 100644 + *saved_errno = 0; if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + fwrite (line_out, sizeof (char), offset_out, stdout); +} + @@ -1997,8 +1996,8 @@ index 941ad11..bdc466d 100644 + int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ + + static char *line_out = NULL; -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ -+ static size_t allocated_out = 0; ++ idx_t offset_out = 0; /* Index in `line_out' for next char. */ ++ static idx_t allocated_out = 0; + + int increment; + size_t column = 0; @@ -2121,9 +2120,9 @@ index 941ad11..bdc466d 100644 + goto rescan; + } + -+ if (allocated_out < offset_out + mblength) ++ if (allocated_out - offset_out <= mblength) + { -+ line_out = X2REALLOC (line_out, &allocated_out); ++ line_out = xpalloc (line_out, &allocated_out, 1, -1, sizeof *line_out); + } + + memcpy (line_out + offset_out, bufpos, mblength); @@ -2155,14 +2154,14 @@ index 941ad11..bdc466d 100644 + *saved_errno = 0; + + if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ fwrite (line_out, sizeof (char), offset_out, stdout); + +} +#endif + +/* Fold file FILENAME, or standard input if FILENAME is "-", + to stdout, with maximum line length WIDTH. -+ Return 0 if successful, 1 if an error occurs. */ ++ Return true if successful. */ + +static bool +fold_file (char const *filename, size_t width) @@ -2173,12 +2172,12 @@ index 941ad11..bdc466d 100644 + if (STREQ (filename, "-")) + { + istream = stdin; -+ have_read_stdin = 1; ++ have_read_stdin = true; + } + else + istream = fopen (filename, "r"); + -+ if (istream == NULL) ++ if (istream == nullptr) + { + error (0, errno, "%s", filename); + return false; @@ -2195,7 +2194,7 @@ index 941ad11..bdc466d 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -251,7 +499,8 @@ main (int argc, char **argv) +@@ -249,7 +497,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2205,7 +2204,7 @@ index 941ad11..bdc466d 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -260,7 +509,15 @@ main (int argc, char **argv) +@@ -258,7 +507,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -2223,10 +2222,10 @@ index 941ad11..bdc466d 100644 case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index 96ee941..8fdb8fc 100644 +index fd9dc81..5133cc0 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -450,8 +450,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -476,8 +476,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2238,7 +2237,7 @@ index 96ee941..8fdb8fc 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 09c6fa8..7552b62 100644 +index e7081a0..19e0268 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -2264,9 +2263,9 @@ index 09c6fa8..7552b62 100644 +#endif + #include "system.h" + #include "c-ctype.h" #include "fadvise.h" - #include "hard-locale.h" -@@ -324,6 +342,18 @@ +@@ -325,6 +343,18 @@ #include "xstrtol-error.h" #include "xdectoint.h" @@ -2285,7 +2284,7 @@ index 09c6fa8..7552b62 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -416,7 +446,20 @@ struct COLUMN +@@ -417,7 +447,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -2307,9 +2306,9 @@ index 09c6fa8..7552b62 100644 static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); - static void getoptnum (char const *n_str, int min, int *num, - char const *errfmt); +@@ -428,6 +471,7 @@ static void pad_across_to (int position); + static void add_line_number (COLUMN *p); + static int getoptnum (char const *n_str, int min, char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, + int *character_length, int *character_width, int *number); @@ -2442,7 +2441,7 @@ index 09c6fa8..7552b62 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -985,8 +1068,8 @@ main (int argc, char **argv) +@@ -986,8 +1069,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -2453,7 +2452,7 @@ index 09c6fa8..7552b62 100644 break; case 'N': skip_count = false; -@@ -1011,6 +1094,7 @@ main (int argc, char **argv) +@@ -1013,6 +1096,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ col_sep_string = ""; col_sep_length = 0; @@ -2461,7 +2460,7 @@ index 09c6fa8..7552b62 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1165,7 +1249,8 @@ getoptnum (char const *n_str, int min, int *num, char const *err) +@@ -1168,7 +1252,8 @@ getoptnum (char const *n_str, int min, char const *err) a number. */ static void @@ -2471,10 +2470,10 @@ index 09c6fa8..7552b62 100644 { if (!*arg) { -@@ -1174,7 +1259,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) +@@ -1177,7 +1262,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) } - if (!ISDIGIT (*arg)) + if (!c_isdigit (*arg)) - *character = *arg++; + { +#ifdef HAVE_MBRTOWC @@ -2514,7 +2513,7 @@ index 09c6fa8..7552b62 100644 if (*arg) { long int tmp_long; -@@ -1203,6 +1322,11 @@ static void +@@ -1206,6 +1325,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2526,7 +2525,7 @@ index 09c6fa8..7552b62 100644 lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1240,7 +1364,7 @@ init_parameters (int number_of_files) +@@ -1243,7 +1367,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2535,7 +2534,7 @@ index 09c6fa8..7552b62 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1272,11 +1396,11 @@ init_parameters (int number_of_files) +@@ -1275,11 +1399,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ /* Estimate chars_per_text without any margin and keep it constant. */ @@ -2549,7 +2548,7 @@ index 09c6fa8..7552b62 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1285,7 +1409,7 @@ init_parameters (int number_of_files) +@@ -1288,7 +1412,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -2558,7 +2557,7 @@ index 09c6fa8..7552b62 100644 sep_chars = INT_MAX; if (ckd_sub (&useful_chars, chars_per_line - chars_used_by_number, sep_chars)) -@@ -1308,7 +1432,7 @@ init_parameters (int number_of_files) +@@ -1311,7 +1435,7 @@ init_parameters (int number_of_files) We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 to expand a tab which is not an input_tab-char. */ free (clump_buff); @@ -2567,7 +2566,7 @@ index 09c6fa8..7552b62 100644 } /* Open the necessary files, -@@ -1414,7 +1538,7 @@ init_funcs (void) +@@ -1417,7 +1541,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2576,7 +2575,7 @@ index 09c6fa8..7552b62 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1448,7 +1572,7 @@ init_funcs (void) +@@ -1451,7 +1575,7 @@ init_funcs (void) } else { @@ -2585,7 +2584,7 @@ index 09c6fa8..7552b62 100644 h_next = h + chars_per_column; } } -@@ -1745,9 +1869,9 @@ static void +@@ -1748,9 +1872,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2597,9 +2596,9 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2021,13 +2145,13 @@ store_char (char c) +@@ -2024,13 +2148,13 @@ store_char (char c) /* May be too generous. */ - buff = X2REALLOC (buff, &buff_allocated); + buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff); } - buff[buff_current++] = c; + buff[buff_current++] = (unsigned char) c; @@ -2613,7 +2612,7 @@ index 09c6fa8..7552b62 100644 char *s; int num_width; -@@ -2044,22 +2168,24 @@ add_line_number (COLUMN *p) +@@ -2047,22 +2171,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -2642,7 +2641,7 @@ index 09c6fa8..7552b62 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2218,7 +2344,7 @@ print_white_space (void) +@@ -2221,7 +2347,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2651,7 +2650,7 @@ index 09c6fa8..7552b62 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2238,6 +2364,7 @@ print_sep_string (void) +@@ -2241,6 +2367,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2659,7 +2658,7 @@ index 09c6fa8..7552b62 100644 if (separators_not_printed <= 0) { -@@ -2249,6 +2376,7 @@ print_sep_string (void) +@@ -2252,6 +2379,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2667,7 +2666,7 @@ index 09c6fa8..7552b62 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2262,12 +2390,15 @@ print_sep_string (void) +@@ -2265,12 +2393,15 @@ print_sep_string (void) } else { @@ -2684,7 +2683,7 @@ index 09c6fa8..7552b62 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2295,7 +2426,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2298,7 +2429,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2693,7 +2692,7 @@ index 09c6fa8..7552b62 100644 { if (tabify_output) { -@@ -2319,6 +2450,74 @@ print_char (char c) +@@ -2322,6 +2453,74 @@ print_char (char c) putchar (c); } @@ -2768,7 +2767,7 @@ index 09c6fa8..7552b62 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2495,9 +2694,9 @@ read_line (COLUMN *p) +@@ -2498,9 +2697,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2780,7 +2779,7 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2566,7 +2765,7 @@ print_stored (COLUMN *p) +@@ -2569,7 +2768,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2789,7 +2788,7 @@ index 09c6fa8..7552b62 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) +@@ -2581,7 +2780,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2798,7 +2797,7 @@ index 09c6fa8..7552b62 100644 pad_vertically = true; -@@ -2598,9 +2797,9 @@ print_stored (COLUMN *p) +@@ -2601,9 +2800,9 @@ print_stored (COLUMN *p) } } @@ -2810,7 +2809,7 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2613,8 +2812,8 @@ print_stored (COLUMN *p) +@@ -2616,8 +2815,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2821,7 +2820,7 @@ index 09c6fa8..7552b62 100644 } return true; -@@ -2633,7 +2832,7 @@ print_stored (COLUMN *p) +@@ -2636,7 +2835,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2830,7 +2829,7 @@ index 09c6fa8..7552b62 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2643,10 +2842,10 @@ char_to_clump (char c) +@@ -2646,10 +2845,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2843,7 +2842,7 @@ index 09c6fa8..7552b62 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2727,6 +2926,164 @@ char_to_clump (char c) +@@ -2730,6 +2929,164 @@ char_to_clump (char c) return chars; } @@ -3009,7 +3008,7 @@ index 09c6fa8..7552b62 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 2d8324c..46331b8 100644 +index 0928fd5..8c43fd4 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3027,7 +3026,7 @@ index 2d8324c..46331b8 100644 #include "system.h" #include "argmatch.h" #include "assure.h" -@@ -157,14 +165,39 @@ static int thousands_sep; +@@ -158,14 +166,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -3068,7 +3067,7 @@ index 2d8324c..46331b8 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -341,13 +374,11 @@ static bool stable; +@@ -342,13 +375,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -3085,7 +3084,7 @@ index 2d8324c..46331b8 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -804,6 +835,46 @@ reap_all (void) +@@ -807,6 +838,46 @@ reap_all (void) reap (-1); } @@ -3132,7 +3131,7 @@ index 2d8324c..46331b8 100644 /* Clean up any remaining temporary files. */ static void -@@ -1271,7 +1342,7 @@ zaptemp (char const *name) +@@ -1274,7 +1345,7 @@ zaptemp (char const *name) free (node); } @@ -3141,7 +3140,7 @@ index 2d8324c..46331b8 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1286,7 +1357,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3150,7 +3149,7 @@ index 2d8324c..46331b8 100644 { size_t i; -@@ -1298,7 +1369,7 @@ inittables (void) +@@ -1301,7 +1372,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3159,7 +3158,7 @@ index 2d8324c..46331b8 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3244,7 +3243,7 @@ index 2d8324c..46331b8 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3253,7 +3252,7 @@ index 2d8324c..46331b8 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3266,7 +3265,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3339,7 +3338,7 @@ index 2d8324c..46331b8 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3352,7 +3351,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3365,7 +3364,7 @@ index 2d8324c..46331b8 100644 if (newlim) lim = newlim; } -@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3496,7 +3495,7 @@ index 2d8324c..46331b8 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3521,7 +3520,7 @@ index 2d8324c..46331b8 100644 line->keybeg = line_start; } } -@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) +@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3537,7 +3536,7 @@ index 2d8324c..46331b8 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) +@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3546,7 +3545,7 @@ index 2d8324c..46331b8 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) +@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3572,7 +3571,7 @@ index 2d8324c..46331b8 100644 static int nan_compare (long double a, long double b) { -@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3581,7 +3580,7 @@ index 2d8324c..46331b8 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2372,15 +2735,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3599,7 +3598,7 @@ index 2d8324c..46331b8 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2526,7 +2888,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3608,7 +3607,7 @@ index 2d8324c..46331b8 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2574,9 +2936,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3621,7 +3620,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3634,7 +3633,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2597,19 +2959,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3658,7 +3657,7 @@ index 2d8324c..46331b8 100644 } } -@@ -2620,7 +2982,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3667,7 +3666,7 @@ index 2d8324c..46331b8 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2662,11 +3024,87 @@ diff_reversed (int diff, bool reversed) +@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3756,7 +3755,7 @@ index 2d8324c..46331b8 100644 { struct keyfield *key = keylist; -@@ -2747,7 +3185,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3765,7 +3764,7 @@ index 2d8324c..46331b8 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2857,6 +3295,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3977,7 +3976,7 @@ index 2d8324c..46331b8 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2884,7 +3527,7 @@ compare (struct line const *a, struct line const *b) +@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3986,7 +3985,7 @@ index 2d8324c..46331b8 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4272,6 +4915,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3994,7 +3993,7 @@ index 2d8324c..46331b8 100644 break; case 'g': key->general_numeric = true; -@@ -4351,7 +4995,7 @@ main (int argc, char **argv) +@@ -4364,7 +5008,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4003,7 +4002,7 @@ index 2d8324c..46331b8 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4374,6 +5018,29 @@ main (int argc, char **argv) +@@ -4387,6 +5031,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4033,7 +4032,7 @@ index 2d8324c..46331b8 100644 have_read_stdin = false; inittables (); -@@ -4644,13 +5311,34 @@ main (int argc, char **argv) +@@ -4657,13 +5324,34 @@ main (int argc, char **argv) case 't': { @@ -4072,7 +4071,7 @@ index 2d8324c..46331b8 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4661,9 +5349,11 @@ main (int argc, char **argv) +@@ -4674,9 +5362,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4087,7 +4086,7 @@ index 2d8324c..46331b8 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index aca67dd..f79c808 100644 +index ff234d7..7c36ef6 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -39,6 +39,9 @@ @@ -4100,7 +4099,7 @@ index aca67dd..f79c808 100644 #include "system.h" #include "expand-common.h" -@@ -105,24 +108,47 @@ unexpand (void) +@@ -105,24 +108,46 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -4120,28 +4119,27 @@ index aca67dd..f79c808 100644 if (!fp) return; + + mbf_init (mbf, fp); + found_bom=check_bom(fp,&mbf); + + if (using_utf_locale == false && found_bom == true) -+ { -+ /*try using some predefined locale */ - -+ if (set_utf_locale () != 0) + { -+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ /* Try using some predefined locale */ ++ if (set_utf_locale () != 0) ++ { ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } + } -+ } ++ /* The worst case is a non-blank character, then one blank, then a tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ -- pending_blank = xmalloc (max_column_width); -+ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); +- pending_blank = ximalloc (max_column_width); ++ pending_blank = ximalloc (max_column_width * sizeof (mbf_char_t)); + + if (found_bom == true) -+ { + print_bom(); -+ } while (true) { @@ -4151,7 +4149,7 @@ index aca67dd..f79c808 100644 /* If true, perform translations. */ bool convert = true; -@@ -156,12 +182,44 @@ unexpand (void) +@@ -156,12 +181,44 @@ unexpand (void) do { @@ -4199,10 +4197,10 @@ index aca67dd..f79c808 100644 if (blank) { -@@ -178,16 +236,16 @@ unexpand (void) - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); +@@ -175,16 +232,16 @@ unexpand (void) + if (convert) + { - if (c == '\t') + if (mb_iseq (c, '\t')) { @@ -4219,7 +4217,7 @@ index aca67dd..f79c808 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -195,13 +253,14 @@ unexpand (void) +@@ -192,13 +249,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4236,7 +4234,7 @@ index aca67dd..f79c808 100644 } /* Discard pending blanks, unless it was a single -@@ -209,7 +268,7 @@ unexpand (void) +@@ -206,7 +264,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4245,7 +4243,7 @@ index aca67dd..f79c808 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -219,16 +278,20 @@ unexpand (void) +@@ -216,16 +274,20 @@ unexpand (void) } else { @@ -4270,7 +4268,7 @@ index aca67dd..f79c808 100644 write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -238,16 +301,17 @@ unexpand (void) +@@ -235,16 +297,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4292,7 +4290,7 @@ index aca67dd..f79c808 100644 } diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index 18e7bea..24a141b 100644 +index b55fb9d..ac80f49 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4530,10 +4528,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index fdbf369..a6ce49c 100644 +index 12e30b4..1529db6 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -387,6 +387,8 @@ all_tests = \ +@@ -390,6 +390,8 @@ all_tests = \ tests/sort/sort-discrim.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4542,7 +4540,7 @@ index fdbf369..a6ce49c 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -590,6 +592,7 @@ all_tests = \ +@@ -593,6 +595,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4550,7 +4548,7 @@ index fdbf369..a6ce49c 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -746,6 +749,7 @@ all_tests = \ +@@ -749,6 +752,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4559,7 +4557,7 @@ index fdbf369..a6ce49c 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 11f3fc4..d609a2c 100755 +index 4b07210..68b9ea1 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4626,10 +4624,10 @@ index 11f3fc4..d609a2c 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 00b4362..7d51bea 100755 +index 0981ec9..ba889c8 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl -@@ -20,9 +20,18 @@ use strict; +@@ -20,9 +20,17 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4639,17 +4637,17 @@ index 00b4362..7d51bea 100755 + # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - +-my $prog = 'fold'; ++ +# uncommented to enable multibyte paths +my $mb_locale = $ENV{LOCALE_FR_UTF8}; +! defined $mb_locale || $mb_locale eq 'none' + and $mb_locale = 'C'; -+ + my @Tests = ( - ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], -@@ -31,9 +40,48 @@ my @Tests = - ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], +@@ -44,9 +52,48 @@ my @Tests = + {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], ); +# Add _POSIX2_VERSION=199209 to the environment of each test @@ -4750,7 +4748,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 76bcbd4..59eb819 100755 +index 27d9c17..4976335 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -4807,7 +4805,7 @@ index 76bcbd4..59eb819 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index 6b34e0b..34b4aeb 100755 +index 60e6106..3c64a08 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -4876,7 +4874,7 @@ index 6b34e0b..34b4aeb 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl -index 89eed0c..b855d73 100755 +index a3204d3..40942a5 100755 --- a/tests/sort/sort-merge.pl +++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -4936,7 +4934,7 @@ index 89eed0c..b855d73 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index d49f65f..ebba925 100755 +index 2ee92c4..96c7965 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5182,5 +5180,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.46.1 +2.48.1 diff --git a/coreutils-nproc-affinity-1.patch b/coreutils-nproc-affinity-1.patch deleted file mode 100644 index 8748d4e..0000000 --- a/coreutils-nproc-affinity-1.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357 -Author: Florian Weimer -Date: Mon Nov 11 14:05:53 2024 +0100 - - nproc: Use affinity mask even on systems with more than 1024 CPUs. - - * lib/nproc.c (num_processors_via_affinity_mask): Retry - with larger affinity masks if CPU_ALLOC_SIZE is available. - -diff --git a/lib/nproc.c b/lib/nproc.c -index 92a07e8289..48bc3d06fa 100644 ---- a/lib/nproc.c -+++ b/lib/nproc.c -@@ -20,6 +20,7 @@ - #include - #include "nproc.h" - -+#include - #include - #include - #include -@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void) - return count; - } - } -+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -+ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ -+ { -+ unsigned int alloc_count = 1024; -+ while (1) -+ { -+ cpu_set_t *set = CPU_ALLOC (alloc_count); -+ if (set == NULL) -+ return 0; -+ unsigned int size = CPU_ALLOC_SIZE (alloc_count); -+ if (sched_getaffinity (0, size, set) == 0) -+ { -+ unsigned int count = CPU_COUNT_S (size, set); -+ CPU_FREE (set); -+ return count; -+ } -+ if (errno != EINVAL) -+ { -+ CPU_FREE (set); -+ return 0; -+ } -+ CPU_FREE (set); -+ alloc_count *= 2; -+ if (alloc_count == 0) -+ return 0; -+ } -+ } - #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ - { - cpu_set_t set; diff --git a/coreutils-nproc-affinity-2.patch b/coreutils-nproc-affinity-2.patch deleted file mode 100644 index aeca09c..0000000 --- a/coreutils-nproc-affinity-2.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit ee0bc695303775da5026091a65e8ec2b764f4a26 -Author: Bruno Haible -Date: Mon Nov 11 15:40:52 2024 +0100 - - nproc: Use affinity mask even in out-of-memory situations. - - * lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated - cpu_set_t as fallback. Add comments. - -diff --git a/lib/nproc.c b/lib/nproc.c -index 48bc3d06fa..0b5898d88f 100644 ---- a/lib/nproc.c -+++ b/lib/nproc.c -@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void) - return count; - } - } --#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ -+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ -+ /* There are two ways to use the sched_getaffinity() function: -+ - With a statically-sized cpu_set_t. -+ - With a dynamically-sized cpu_set_t. -+ Documentation: -+ -+ -+ The second way has the advantage that it works on systems with more than -+ 1024 CPUs. The first way has the advantage that it works also when memory -+ is tight. */ -+# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ - { - unsigned int alloc_count = 1024; -- while (1) -+ for (;;) - { - cpu_set_t *set = CPU_ALLOC (alloc_count); - if (set == NULL) -- return 0; -+ /* Out of memory. */ -+ break; - unsigned int size = CPU_ALLOC_SIZE (alloc_count); - if (sched_getaffinity (0, size, set) == 0) - { -@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void) - } - if (errno != EINVAL) - { -+ /* Some other error. */ - CPU_FREE (set); - return 0; - } - CPU_FREE (set); -+ /* Retry with some larger cpu_set_t. */ - alloc_count *= 2; - if (alloc_count == 0) -+ /* Integer overflow. Avoid an endless loop. */ - return 0; - } - } --#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ -+# endif - { - cpu_set_t set; - diff --git a/coreutils-python3.patch b/coreutils-python3.patch index 98fc642..e6ff471 100644 --- a/coreutils-python3.patch +++ b/coreutils-python3.patch @@ -1,4 +1,4 @@ -From cef9cccce395cd80cd5ac42a4fe6c3909be1c0b5 Mon Sep 17 00:00:00 2001 +From f1a6e8d840a28eb2ab7a488e0d06450b7192c76d Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 2 Apr 2024 14:11:26 +0100 Subject: [PATCH] coreutils-python3.patch @@ -10,10 +10,10 @@ Subject: [PATCH] coreutils-python3.patch 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/init.cfg b/init.cfg -index b06965a..08413ee 100644 +index 612d287..9a6fa2d 100644 --- a/init.cfg +++ b/init.cfg -@@ -581,10 +581,10 @@ seek_data_capable_() +@@ -597,10 +597,10 @@ seek_data_capable_() # Skip the current test if "." lacks d_type support. require_dirent_d_type_() { @@ -37,7 +37,7 @@ index 1a2f76f..42d3924 100644 # Intended to exit 0 only on Linux/GNU systems. import os diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh -index 830a69e..7344ddf 100755 +index 1d0a359..bd03542 100755 --- a/tests/du/move-dir-while-traversing.sh +++ b/tests/du/move-dir-while-traversing.sh @@ -21,8 +21,8 @@ print_ver_ du @@ -61,5 +61,5 @@ index 830a69e..7344ddf 100755 import os,sys -- -2.44.0 +2.48.1 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index a31c3af..91bc5b5 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,4 +1,4 @@ -From 78970c915b8556fcec4622e948a37dd8e34efe6d Mon Sep 17 00:00:00 2001 +From fc96cab095d704e8bf9934812dd8d6f87fbf4be4 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-selinux.patch @@ -9,10 +9,10 @@ Subject: [PATCH] coreutils-selinux.patch 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cp.c b/src/cp.c -index 28b0217..897379f 100644 +index a0ec067..1169c6a 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -997,7 +997,7 @@ main (int argc, char **argv) +@@ -996,7 +996,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -21,7 +21,7 @@ index 28b0217..897379f 100644 long_opts, nullptr)) != -1) { -@@ -1049,6 +1049,23 @@ main (int argc, char **argv) +@@ -1048,6 +1048,23 @@ main (int argc, char **argv) copy_contents = true; break; @@ -46,7 +46,7 @@ index 28b0217..897379f 100644 x.preserve_links = true; x.dereference = DEREF_NEVER; diff --git a/src/install.c b/src/install.c -index accd0fd..b686fe9 100644 +index b3b26ab..2d2f072 100644 --- a/src/install.c +++ b/src/install.c @@ -807,7 +807,7 @@ main (int argc, char **argv) @@ -83,5 +83,5 @@ index accd0fd..b686fe9 100644 use_default_selinux_context = false; break; -- -2.44.0 +2.48.1 diff --git a/coreutils.spec b/coreutils.spec index b6b0f0f..79bf510 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.5 -Release: 13%{?dist} +Version: 9.6 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,13 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# coreutils no longer lists Cockpit logins in `who` (rhbz#2307847) -# https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb -Patch105: coreutils-9.5-readutmp-web-session.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=2325167 -Patch106: coreutils-nproc-affinity-1.patch -Patch107: coreutils-nproc-affinity-2.patch +# ls: fix crash with --context +# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac +Patch105: coreutils-9.6-ls-selinux-crash.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -162,6 +158,10 @@ sed src/dircolors.hin \ find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' (echo "<<< done") 2>/dev/null +# FIXME: Force a newer gettext version to workaround `autoreconf -i` errors +# with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel. +sed -i 's/0.19.2/0.22.5/' bootstrap.conf configure.ac + autoreconf -fiv %build @@ -282,6 +282,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jan 20 2025 Lukáš Zaoral - 9.6-1 +- rebase to latest upstream version (rhbz#2338620) +- sync i18n patch with SUSE (Kudos to Berny Völker!) + * Thu Jan 16 2025 Fedora Release Engineering - 9.5-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index d9dc6c9..498bfd9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.5.tar.xz) = 2ca0deac4dc10a80fd0c6fd131252e99d457fd03b7bd626a6bc74fe5a0529c0a3d48ce1f5da1d3b3a7a150a1ce44f0fbb6b68a6ac543dfd5baa3e71f5d65401c -SHA512 (coreutils-9.5.tar.xz.sig) = 029997e0f4ee64e561853cff7c8a124f58cc891598595b44c4a46f9813b4b71c9d677464bc8a26d294e9971832f4b87c23777fea4fac6e8e30f06ad93b9957d5 +SHA512 (coreutils-9.6.tar.xz) = 398391d7f9d77e6117b750abb8711eebdd9cd2549e7846cab26884fb2dd522b6bcfb8bf7fef35a12683e213ada7f89b817bf615628628d42aee3fa3102647b28 +SHA512 (coreutils-9.6.tar.xz.sig) = a8e578b5e1d053b49e3e2c5dc94431d17c6a14662f459b2174cea23865ccca32e5ae5c13fedb0a8345d25269a9b98cb7f463a897c9663f9f9bcaf61e5c781378 From f0604fd61acae429a38c2f1a2e257b6417f81c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 25 Feb 2025 17:02:12 +0100 Subject: [PATCH 18/29] fix 'who -m' with guessed tty names Resolves: rhbz#2343998 --- coreutils-9.6-who-m-systemd.patch | 25 +++++++++++++++++++++++++ coreutils.spec | 9 ++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.6-who-m-systemd.patch diff --git a/coreutils-9.6-who-m-systemd.patch b/coreutils-9.6-who-m-systemd.patch new file mode 100644 index 0000000..5d43364 --- /dev/null +++ b/coreutils-9.6-who-m-systemd.patch @@ -0,0 +1,25 @@ +From 24450e5eecf012bc1ea8cab8d677a45fa42c1778 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= +Date: Mon, 24 Feb 2025 10:36:35 +0100 +Subject: who: fix -m with guessed tty names + +* who.c (scan_entries): Account for guessed tty names (e.g. +'sshd pts/1') from the readutmp module when using the systemd backend. +Addresses https://bugzilla.redhat.com/2343998 +--- + src/who.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/who.c b/src/who.c +index b56a1ac..17c1e34 100644 +--- a/src/who.c ++++ b/src/who.c +@@ -583,7 +583,7 @@ scan_entries (idx_t n, struct gl_utmp const *utmp_buf) + while (n--) + { + if (!my_line_only +- || STREQ (ttyname_b, utmp_buf->ut_line)) ++ || str_endswith (utmp_buf->ut_line, ttyname_b)) + { + if (need_users && IS_USER_PROCESS (utmp_buf)) + print_user (utmp_buf, boottime); diff --git a/coreutils.spec b/coreutils.spec index 79bf510..23eb924 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.6 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,10 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac Patch105: coreutils-9.6-ls-selinux-crash.patch +# who: fix -m with guessed tty names (rhbz#2343998) +# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778 +Patch106: coreutils-9.6-who-m-systemd.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -282,6 +286,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Feb 25 2025 Lukáš Zaoral - 9.6-2 +- fix 'who -m' with guessed tty names (rhbz#2343998) + * Mon Jan 20 2025 Lukáš Zaoral - 9.6-1 - rebase to latest upstream version (rhbz#2338620) - sync i18n patch with SUSE (Kudos to Berny Völker!) From fdfe50c891adab069561406a15b3a7917e679c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 10 Apr 2025 10:40:14 +0200 Subject: [PATCH 19/29] rebase to latest upstream release Resolves: rhbz#2358624 --- coreutils-8.32-DIR_COLORS.patch | 14 +- coreutils-9.6-ls-selinux-crash.patch | 77 ---------- coreutils-9.6-who-m-systemd.patch | 25 ---- coreutils-df-direct.patch | 18 +-- coreutils-i18n.patch | 204 +++++++++++++++------------ coreutils.spec | 15 +- 6 files changed, 132 insertions(+), 221 deletions(-) delete mode 100644 coreutils-9.6-ls-selinux-crash.patch delete mode 100644 coreutils-9.6-who-m-systemd.patch diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 021d2a5..37ce3e6 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -1,4 +1,4 @@ -From c7b13f5e1a7ad012c510a8bdd5a8943ab4b55833 Mon Sep 17 00:00:00 2001 +From bca11e30e8a6281a8cbddc9fb196dd86ab09c955 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS @@ -9,7 +9,7 @@ Subject: [PATCH] downstream changes to default DIR_COLORS 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS -index b465771..ad42b09 100644 +index 540f6cd..b4785b6 100644 --- a/DIR_COLORS +++ b/DIR_COLORS @@ -1,3 +1,7 @@ @@ -30,7 +30,7 @@ index b465771..ad42b09 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -69,7 +76,7 @@ DOOR 01;35 # door +@@ -70,7 +77,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -40,7 +40,7 @@ index b465771..ad42b09 100644 SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index eab6258..1627b63 100644 +index e3b0ec3..39a0a4c 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor @@ -1,3 +1,9 @@ @@ -63,7 +63,7 @@ index eab6258..1627b63 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -59,17 +68,17 @@ TERM xterm* +@@ -60,17 +69,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -86,7 +86,7 @@ index eab6258..1627b63 100644 SETUID 37;41 # regular file that is setuid (u+s) SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) -@@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -79,7 +88,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for regular files with execute permission: @@ -96,5 +96,5 @@ index eab6258..1627b63 100644 # =================================================================== # File extension attributes -- -2.34.1 +2.49.0 diff --git a/coreutils-9.6-ls-selinux-crash.patch b/coreutils-9.6-ls-selinux-crash.patch deleted file mode 100644 index 70837cc..0000000 --- a/coreutils-9.6-ls-selinux-crash.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 915004f403cb25fadb207ddfdbe6a2f43bd44fac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 17 Jan 2025 17:29:34 +0000 -Subject: [PATCH] ls: fix crash with --context - -* src/ls.c (main): Flag that we need to stat() -if we're going to get security context (call file_has_aclinfo_cache). -(file_has_aclinfo_cache): Be defensive and only lookup the device -for the file if the stat has been performed. -(has_capability_cache): Likewise. -* tests/ls/selinux-segfault.sh: Add a test case. -Reported by Bruno Haible. ---- - src/ls.c | 10 +++++----- - tests/ls/selinux-segfault.sh | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 3215360216..f67167f160 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1768,7 +1768,7 @@ main (int argc, char **argv) - - format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size) - | (format == long_format) -- | print_block_size | print_hyperlink); -+ | print_block_size | print_hyperlink | print_scontext); - format_needs_type = ((! format_needs_stat) - & (recursive | print_with_color | print_scontext - | directories_first -@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - static int unsupported_scontext_err; - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - ai->buf = ai->u.__gl_acl_ch; - ai->size = 0; -@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - errno = 0; - int n = file_has_aclinfo (file, ai, flags); - int err = errno; -- if (n <= 0 && !acl_errno_valid (err)) -+ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)) - { - unsupported_return = n; - unsupported_scontext = ai->scontext; -@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f) - found that has_capability fails indicating lack of support. */ - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - errno = ENOTSUP; - return 0; - } - - bool b = has_capability (file); -- if ( !b && !acl_errno_valid (errno)) -+ if (f->stat_ok && !b && !acl_errno_valid (errno)) - unsupported_device = f->stat.st_dev; - return b; - } -diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh -index 11623acb3f..1cac2b5fc0 100755 ---- a/tests/ls/selinux-segfault.sh -+++ b/tests/ls/selinux-segfault.sh -@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_ - ln -sf missing sedir/broken || framework_failure_ - returns_ 1 ls -L -R -Z -m sedir > out || fail=1 - -+# ls 9.6 would segfault with the following -+ls -Z . > out || fail=1 -+ - Exit $fail diff --git a/coreutils-9.6-who-m-systemd.patch b/coreutils-9.6-who-m-systemd.patch deleted file mode 100644 index 5d43364..0000000 --- a/coreutils-9.6-who-m-systemd.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 24450e5eecf012bc1ea8cab8d677a45fa42c1778 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= -Date: Mon, 24 Feb 2025 10:36:35 +0100 -Subject: who: fix -m with guessed tty names - -* who.c (scan_entries): Account for guessed tty names (e.g. -'sshd pts/1') from the readutmp module when using the systemd backend. -Addresses https://bugzilla.redhat.com/2343998 ---- - src/who.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/who.c b/src/who.c -index b56a1ac..17c1e34 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -583,7 +583,7 @@ scan_entries (idx_t n, struct gl_utmp const *utmp_buf) - while (n--) - { - if (!my_line_only -- || STREQ (ttyname_b, utmp_buf->ut_line)) -+ || str_endswith (utmp_buf->ut_line, ttyname_b)) - { - if (need_users && IS_USER_PROCESS (utmp_buf)) - print_user (utmp_buf, boottime); diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index d19ec29..f5e3d73 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From d179da4730f414069dd2c0ac995a32398718916c Mon Sep 17 00:00:00 2001 +From d3117ae1bb422f771f1c19af54f81d5151f55065 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,7 +11,7 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index ec58f6c..17cda80 100644 +index d1c282f..6d1ee11 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, @@ -29,7 +29,7 @@ index ec58f6c..17cda80 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 5c7efd8..52ece19 100644 +index a969c5c..c465a3f 100644 --- a/src/df.c +++ b/src/df.c @@ -122,6 +122,9 @@ static bool print_type; @@ -59,7 +59,7 @@ index 5c7efd8..52ece19 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -571,7 +576,10 @@ get_header (void) +@@ -572,7 +577,10 @@ get_header (void) for (idx_t col = 0; col < ncolumns; col++) { char *cell; @@ -71,7 +71,7 @@ index 5c7efd8..52ece19 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1452,6 +1460,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1454,6 +1462,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 5c7efd8..52ece19 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1522,6 +1541,7 @@ or all file systems by default.\n\ +@@ -1524,6 +1543,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 5c7efd8..52ece19 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1616,6 +1636,9 @@ main (int argc, char **argv) +@@ -1618,6 +1638,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 5c7efd8..52ece19 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1712,6 +1735,13 @@ main (int argc, char **argv) +@@ -1714,6 +1737,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.48.1 +2.49.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e7699c1..38b871c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001 +From 3d25791ec9cc357a34620516d1c024ef17a4dd75 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -8,11 +8,11 @@ Subject: [PATCH] coreutils-i18n.patch configure.ac | 6 + lib/linebuffer.h | 8 + lib/mbchar.c | 23 ++ - lib/mbchar.h | 373 +++++++++++++++++ + lib/mbchar.h | 383 +++++++++++++++++ lib/mbfile.c | 20 + - lib/mbfile.h | 267 ++++++++++++ - m4/mbchar.m4 | 13 + - m4/mbfile.m4 | 14 + + lib/mbfile.h | 283 +++++++++++++ + m4/mbchar.m4 | 15 + + m4/mbfile.m4 | 16 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + @@ -20,21 +20,21 @@ Subject: [PATCH] coreutils-i18n.patch src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- - src/sort.c | 792 +++++++++++++++++++++++++++++++++--- + src/sort.c | 790 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 51 ++- + tests/misc/fold.pl | 50 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3603 insertions(+), 197 deletions(-) + 30 files changed, 3632 insertions(+), 195 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -47,10 +47,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 380fa11..ca80e6f 100644 +index 94c164e..cecbf26 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -165,6 +165,8 @@ gnulib_modules=" +@@ -166,6 +166,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +60,10 @@ index 380fa11..ca80e6f 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index bf6da2a..321016d 100644 +index 775c4cc..e6b5c9c 100644 --- a/configure.ac +++ b/configure.ac -@@ -505,6 +505,12 @@ fi +@@ -504,6 +504,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -104,11 +104,11 @@ index ca56f80..509b7e6 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/lib/mbchar.c b/lib/mbchar.c new file mode 100644 -index 0000000..d94b7c3 +index 0000000..713c2f7 --- /dev/null +++ b/lib/mbchar.c @@ -0,0 +1,23 @@ -+/* Copyright (C) 2001, 2006, 2009-2024 Free Software Foundation, Inc. ++/* Copyright (C) 2001, 2006, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -133,12 +133,12 @@ index 0000000..d94b7c3 +#include "mbchar.h" diff --git a/lib/mbchar.h b/lib/mbchar.h new file mode 100644 -index 0000000..c06ef11 +index 0000000..d77168e --- /dev/null +++ b/lib/mbchar.h -@@ -0,0 +1,373 @@ +@@ -0,0 +1,383 @@ +/* Multibyte character data type. -+ Copyright (C) 2001, 2005-2007, 2009-2024 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005-2007, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -296,6 +296,11 @@ index 0000000..c06ef11 +# define MBCHAR_INLINE _GL_INLINE +#endif + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ +/* The longest multibyte characters, nowadays, are 4 bytes long. + Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ +#define MBCHAR_BUF_SIZE 4 @@ -507,17 +512,22 @@ index 0000000..c06ef11 + +#endif + ++ ++#ifdef __cplusplus ++} ++#endif ++ +_GL_INLINE_HEADER_END + +#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..8d2957b +index 0000000..f4e3e77 --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,20 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ Copyright (C) 2012-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -538,12 +548,12 @@ index 0000000..8d2957b +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..ad61c19 +index 0000000..c852f31 --- /dev/null +++ b/lib/mbfile.h -@@ -0,0 +1,267 @@ +@@ -0,0 +1,283 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2001, 2005, 2009-2023 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -598,6 +608,7 @@ index 0000000..ad61c19 + +#include +#include ++#include +#include +#include + @@ -608,14 +619,22 @@ index 0000000..ad61c19 +# define MBFILE_INLINE _GL_INLINE +#endif + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* Guarantee two characters of pushback. */ ++#define MBFILE_MAX_PUSHBACK 2 ++ +struct mbfile_multi { + FILE *fp; + bool eof_seen; -+ bool have_pushback; ++ unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */ + mbstate_t state; + unsigned int bufcount; + char buf[MBCHAR_BUF_SIZE]; -+ struct mbchar pushback; ++ struct mbchar pushback[MBFILE_MAX_PUSHBACK]; +}; + +MBFILE_INLINE void @@ -624,19 +643,19 @@ index 0000000..ad61c19 + unsigned int new_bufcount; + size_t bytes; + ++ /* Return character pushed back, if there is one. */ ++ if (mbf->pushback_count > 0) ++ { ++ mb_copy (mbc, &mbf->pushback[mbf->pushback_count - 1]); ++ mbf->pushback_count--; ++ return; ++ } ++ + /* If EOF has already been seen, don't use getc. This matters if + mbf->fp is connected to an interactive tty. */ + if (mbf->eof_seen) + goto eof; + -+ /* Return character pushed back, if there is one. */ -+ if (mbf->have_pushback) -+ { -+ mb_copy (mbc, &mbf->pushback); -+ mbf->have_pushback = false; -+ return; -+ } -+ + new_bufcount = mbf->bufcount; + + /* If mbf->state is not in an initial state, some more 32-bit wide character @@ -785,8 +804,10 @@ index 0000000..ad61c19 +MBFILE_INLINE void +mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) +{ -+ mb_copy (&mbf->pushback, mbc); -+ mbf->have_pushback = true; ++ if (mbf->pushback_count == MBFILE_MAX_PUSHBACK) ++ abort (); ++ mb_copy (&mbf->pushback[mbf->pushback_count], mbc); ++ mbf->pushback_count++; +} + +typedef struct mbfile_multi mb_file_t; @@ -796,7 +817,7 @@ index 0000000..ad61c19 +#define mbf_init(mbf, stream) \ + ((mbf).fp = (stream), \ + (mbf).eof_seen = false, \ -+ (mbf).have_pushback = false, \ ++ (mbf).pushback_count = 0, \ + mbszero (&(mbf).state), \ + (mbf).bufcount = 0) + @@ -806,20 +827,27 @@ index 0000000..ad61c19 + +#define mb_iseof(mbc) ((mbc).bytes == 0) + ++ ++#ifdef __cplusplus ++} ++#endif ++ +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 new file mode 100644 -index 0000000..471e8c4 +index 0000000..b76f1d7 --- /dev/null +++ b/m4/mbchar.m4 -@@ -0,0 +1,13 @@ -+# mbchar.m4 serial 9 -+dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. +@@ -0,0 +1,15 @@ ++# mbchar.m4 ++# serial 9 ++dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. ++dnl This file is offered as-is, without any warranty. + +dnl autoconf tests required for use of mbchar.m4 +dnl From Bruno Haible. @@ -830,15 +858,17 @@ index 0000000..471e8c4 +]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..83068a9 +index 0000000..1d126e0 --- /dev/null +++ b/m4/mbfile.m4 -@@ -0,0 +1,14 @@ -+# mbfile.m4 serial 7 -+dnl Copyright (C) 2005, 2008-2023 Free Software Foundation, Inc. +@@ -0,0 +1,16 @@ ++# mbfile.m4 ++# serial 7 ++dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. ++dnl This file is offered as-is, without any warranty. + +dnl autoconf tests required for use of mbfile.h +dnl From Bruno Haible. @@ -1509,7 +1539,7 @@ index b424997..c9f181c 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 2dbbbe4..91a90a3 100644 +index 732123f..fdbef3f 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -3008,7 +3038,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 0928fd5..8c43fd4 100644 +index b10183b..fbf325b 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3084,7 +3114,7 @@ index 0928fd5..8c43fd4 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -807,6 +838,46 @@ reap_all (void) +@@ -806,6 +837,46 @@ reap_all (void) reap (-1); } @@ -3131,7 +3161,7 @@ index 0928fd5..8c43fd4 100644 /* Clean up any remaining temporary files. */ static void -@@ -1274,7 +1345,7 @@ zaptemp (char const *name) +@@ -1273,7 +1344,7 @@ zaptemp (char const *name) free (node); } @@ -3140,7 +3170,7 @@ index 0928fd5..8c43fd4 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1288,7 +1359,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3149,7 +3179,7 @@ index 0928fd5..8c43fd4 100644 { size_t i; -@@ -1301,7 +1372,7 @@ inittables (void) +@@ -1300,7 +1371,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3158,7 +3188,7 @@ index 0928fd5..8c43fd4 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3243,7 +3273,7 @@ index 0928fd5..8c43fd4 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3252,7 +3282,7 @@ index 0928fd5..8c43fd4 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3265,7 +3295,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3338,7 +3368,7 @@ index 0928fd5..8c43fd4 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3351,7 +3381,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3364,7 +3394,7 @@ index 0928fd5..8c43fd4 100644 if (newlim) lim = newlim; } -@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3495,7 +3525,7 @@ index 0928fd5..8c43fd4 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3520,7 +3550,7 @@ index 0928fd5..8c43fd4 100644 line->keybeg = line_start; } } -@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) +@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3536,7 +3566,7 @@ index 0928fd5..8c43fd4 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) +@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3545,7 +3575,7 @@ index 0928fd5..8c43fd4 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) +@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3571,7 +3601,7 @@ index 0928fd5..8c43fd4 100644 static int nan_compare (long double a, long double b) { -@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3580,7 +3610,7 @@ index 0928fd5..8c43fd4 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2384,15 +2747,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3598,7 +3628,7 @@ index 0928fd5..8c43fd4 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2538,7 +2900,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3607,7 +3637,7 @@ index 0928fd5..8c43fd4 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2586,9 +2948,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3620,7 +3650,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2599,9 +2961,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3633,7 +3663,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2609,19 +2971,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3657,16 +3687,7 @@ index 0928fd5..8c43fd4 100644 } } -@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) - { - error (0, 0, - _("%snumbers use %s as a decimal point in this locale"), -- tab == decimal_point ? "" : _("note "), -+ (tab_length && tab[0] == decimal_point) ? "" : _("note "), - quote (((char []) {decimal_point, 0}))); - - } -@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed) +@@ -2673,11 +3035,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3755,7 +3776,7 @@ index 0928fd5..8c43fd4 100644 { struct keyfield *key = keylist; -@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2758,7 +3196,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3764,7 +3785,7 @@ index 0928fd5..8c43fd4 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2868,6 +3306,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3976,7 +3997,7 @@ index 0928fd5..8c43fd4 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b) +@@ -2895,7 +3538,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3985,7 +4006,7 @@ index 0928fd5..8c43fd4 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4283,6 +4926,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3993,7 +4014,7 @@ index 0928fd5..8c43fd4 100644 break; case 'g': key->general_numeric = true; -@@ -4364,7 +5008,7 @@ main (int argc, char **argv) +@@ -4362,7 +5006,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4002,7 +4023,7 @@ index 0928fd5..8c43fd4 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4387,6 +5031,29 @@ main (int argc, char **argv) +@@ -4385,6 +5029,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4032,7 +4053,7 @@ index 0928fd5..8c43fd4 100644 have_read_stdin = false; inittables (); -@@ -4657,13 +5324,34 @@ main (int argc, char **argv) +@@ -4655,13 +5322,34 @@ main (int argc, char **argv) case 't': { @@ -4071,7 +4092,7 @@ index 0928fd5..8c43fd4 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4674,9 +5362,11 @@ main (int argc, char **argv) +@@ -4672,9 +5360,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4528,7 +4549,7 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 12e30b4..1529db6 100644 +index 4da6756..fcbeef8 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -390,6 +390,8 @@ all_tests = \ @@ -4540,7 +4561,7 @@ index 12e30b4..1529db6 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -593,6 +595,7 @@ all_tests = \ +@@ -594,6 +596,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4548,7 +4569,7 @@ index 12e30b4..1529db6 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -749,6 +752,7 @@ all_tests = \ +@@ -750,6 +753,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4624,7 +4645,7 @@ index 4b07210..68b9ea1 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 0981ec9..ba889c8 100755 +index 877322e..ba889c8 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,17 @@ use strict; @@ -4646,7 +4667,7 @@ index 0981ec9..ba889c8 100755 my @Tests = ( -@@ -44,9 +52,48 @@ my @Tests = +@@ -44,6 +52,46 @@ my @Tests = {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], ); @@ -4693,9 +4714,6 @@ index 0981ec9..ba889c8 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; --my $prog = 'fold'; - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); - exit $fail; diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 index 0000000..11836ba @@ -5180,5 +5198,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.48.1 +2.49.0 diff --git a/coreutils.spec b/coreutils.spec index 23eb924..727da1b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.6 -Release: 2%{?dist} +Version: 9.7 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,14 +32,6 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# ls: fix crash with --context -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac -Patch105: coreutils-9.6-ls-selinux-crash.patch - -# who: fix -m with guessed tty names (rhbz#2343998) -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778 -Patch106: coreutils-9.6-who-m-systemd.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -286,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Apr 09 2025 Lukáš Zaoral - 9.7-1 +- rebase to latest upstream release (rhbz#2358624) + * Tue Feb 25 2025 Lukáš Zaoral - 9.6-2 - fix 'who -m' with guessed tty names (rhbz#2343998) From 386bf34c2e19247b3b4b506588adf7cff5552d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 11 Apr 2025 09:17:07 +0200 Subject: [PATCH 20/29] sources: update for coreutils 9.7 ... which I forgot to commit with the rest of the changes... --- sources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources b/sources index 498bfd9..0e9a66d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.6.tar.xz) = 398391d7f9d77e6117b750abb8711eebdd9cd2549e7846cab26884fb2dd522b6bcfb8bf7fef35a12683e213ada7f89b817bf615628628d42aee3fa3102647b28 -SHA512 (coreutils-9.6.tar.xz.sig) = a8e578b5e1d053b49e3e2c5dc94431d17c6a14662f459b2174cea23865ccca32e5ae5c13fedb0a8345d25269a9b98cb7f463a897c9663f9f9bcaf61e5c781378 +SHA512 (coreutils-9.7.tar.xz) = fe81e6ba4fb492095153d5baac1eca8f07ece0957849de746a2a858cf007893cc2ded595a31a5e5d43d13216cc44b9d74a3245d9f23221ecc8cd00f428f27414 +SHA512 (coreutils-9.7.tar.xz.sig) = 48d86a19cee3c153f01f7478847f4621685c02e59942540bb20b30e314df05230817b87d0e73acd953e79fab35718e5bea57f25fe511a2c275a85ced4b317bae From a0b27bcd5fc64c0a9720e0b8ecc767258bac71de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 19 May 2025 09:47:42 +0200 Subject: [PATCH 21/29] cp/mv: do not fail when copying of trivial NFSv4 ACLs fails Resolves: rhbz#2363149 --- ...ils-9.6-cp-improve-nfsv4-acl-support.patch | 512 ++++++++++++++++++ coreutils.spec | 10 +- 2 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.6-cp-improve-nfsv4-acl-support.patch diff --git a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch new file mode 100644 index 0000000..1b36b1e --- /dev/null +++ b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch @@ -0,0 +1,512 @@ +From 6ad28e2b6627caf7b83bf893027c087b8cea1a97 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 9 May 2025 18:02:29 -0700 +Subject: [PATCH 1/2] qcopy-acl: port better to NFSv4 on GNU/Linux + +Problem reported by Ian Dall in +and by Thomas Clark in . +* lib/file-has-acl.c (smack_new_label_from_file) [!HAVE_SMACK]: +New dummy function. +(has_xattr, get_aclinfo): New arg FD. All callers changed. +Remove some unnecessary MAYBE_UNUSEDs. +(acl_get_fd_np): Fall back on acl_get_fd if this function is +needed but not available. +(acl_get_fdfile): New function, if needed. +(file_has_aclinfo): Reimplement in terms of ... +(fdfile_has_aclinfo): ... this new function, +which also has an FD argument. +* lib/qcopy-acl.c [USE_XATTR]: Include dirent.h, for DT_DIR etc. +(qcopy_acl): If attr_copy_file or attr_copy_fd fail with EOPNOTSUPP, +don’t fail if the source has a trivial ACL (this is the part +that fixes the bug; the rest is optimization). + +(cherry picked from commit 8a356b77717a2e4f735ec06e326880ca1f61aadb) +--- + lib/acl.h | 2 + + lib/copy-acl.c | 1 + + lib/file-has-acl.c | 172 ++++++++++++++++++++++++++++++++------------- + lib/qcopy-acl.c | 29 ++++++-- + 4 files changed, 152 insertions(+), 52 deletions(-) + +diff --git a/lib/acl.h b/lib/acl.h +index 90fd24e..e3c134f 100644 +--- a/lib/acl.h ++++ b/lib/acl.h +@@ -79,6 +79,8 @@ struct aclinfo + bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; + int file_has_acl (char const *, struct stat const *); + int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); ++int fdfile_has_aclinfo (int, char const *restrict, ++ struct aclinfo *restrict, int); + + #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR + bool aclinfo_has_xattr (struct aclinfo const *, char const *) +diff --git a/lib/copy-acl.c b/lib/copy-acl.c +index c36f64e..2fce6c7 100644 +--- a/lib/copy-acl.c ++++ b/lib/copy-acl.c +@@ -33,6 +33,7 @@ + a valid file descriptor, use file descriptor operations, else use + filename based operations on SRC_NAME. Likewise for DEST_DESC and + DST_NAME. ++ MODE should be the source file's st_mode. + If access control lists are not available, fchmod the target file to + MODE. Also sets the non-permission bits of the destination file + (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index 66b920c..a356ee0 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path, + { + return -1; + } ++static ssize_t ++smack_new_label_from_file (MAYBE_UNUSED int fd, ++ MAYBE_UNUSED const char *xattr, ++ MAYBE_UNUSED char **label) ++{ ++ return -1; ++} + # endif + static bool + is_smack_enabled (void) +@@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai) + + static bool + has_xattr (char const *xattr, struct aclinfo const *ai, +- MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) ++ int fd, char const *restrict name, int flags) + { + if (ai && aclinfo_has_xattr (ai, xattr)) + return true; + else if (!ai || aclinfo_may_indicate_xattr (ai)) + { +- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) +- (name, xattr, NULL, 0)); ++ int ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) ++ (name, xattr, NULL, 0)) ++ : fgetxattr (fd, xattr, NULL, 0)); + if (0 <= ret || (errno == ERANGE || errno == E2BIG)) + return true; + } +@@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr) + return false; + } + +-/* Get attributes of the file NAME into AI, if USE_ACL. ++/* Get attributes of the file FD aka NAME into AI, if USE_ACL. ++ Ignore FD if it is negative. + If FLAGS & ACL_GET_SCONTEXT, also get security context. + If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */ + static void +-get_aclinfo (char const *name, struct aclinfo *ai, int flags) ++get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) + { + int scontext_err = ENOTSUP; + ai->buf = ai->u.__gl_acl_ch; +@@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr); + while (true) + { +- ai->size = lsxattr (name, ai->buf, acl_alloc); ++ ai->size = (fd < 0 ++ ? lsxattr (name, ai->buf, acl_alloc) ++ : flistxattr (fd, ai->buf, acl_alloc)); + if (0 < ai->size) + break; + ai->u.err = ai->size < 0 ? errno : 0; +@@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + break; + + /* The buffer was too small. Find how large it should have been. */ +- ssize_t size = lsxattr (name, NULL, 0); ++ ssize_t size = (fd < 0 ++ ? lsxattr (name, NULL, 0) ++ : flistxattr (fd, NULL, 0)); + if (size <= 0) + { + ai->size = size; +@@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + { + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) + { +- ssize_t r = smack_new_label_from_path (name, "security.SMACK64", +- flags & ACL_SYMLINK_FOLLOW, +- &ai->scontext); ++ static char const SMACK64[] = "security.SMACK64"; ++ ssize_t r = ++ (fd < 0 ++ ? smack_new_label_from_path (name, SMACK64, ++ flags & ACL_SYMLINK_FOLLOW, ++ &ai->scontext) ++ : smack_new_label_from_file (fd, SMACK64, &ai->scontext)); + scontext_err = r < 0 ? errno : 0; + } + } +@@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) + { + ssize_t r = +- ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) +- (name, &ai->scontext)); ++ (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) ++ (name, &ai->scontext)) ++ : fgetfilecon (fd, &ai->scontext)); + scontext_err = r < 0 ? errno : 0; + # ifndef SE_SELINUX_INLINE + /* Gnulib's selinux-h module is not in use, so getfilecon and +@@ -362,11 +382,13 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) + } + #endif + +-#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ +- && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ +- && !HAVE_ACL_GET_LINK_NP) +-# include +-# ifdef O_PATH ++#if (!USE_LINUX_XATTR && USE_ACL && !HAVE_ACL_EXTENDED_FILE \ ++ && !HAVE_ACL_TYPE_EXTENDED) ++ ++# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP ++# include ++# ifdef O_PATH ++# define acl_get_fd_np(fd, type) acl_get_fd (fd) + + /* Like acl_get_file, but do not follow symbolic links. */ + static acl_t +@@ -381,8 +403,24 @@ acl_get_link_np (char const *name, acl_type_t type) + errno = err; + return r; + } +-# define HAVE_ACL_GET_LINK_NP 1 ++# define HAVE_ACL_GET_LINK_NP 1 ++# endif + # endif ++ ++static acl_t ++acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags) ++{ ++ acl_t (*get) (char const *, acl_type_t) = acl_get_file; ++# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ ++ if (0 <= fd) ++ return acl_get_fd_np (fd, type); ++ if (! (flags & ACL_SYMLINK_FOLLOW)) ++ get = acl_get_link_np; ++# else ++ /* Ignore FD and FLAGS, unfortunately. */ ++# endif ++ return get (name, type); ++} + #endif + + /* Return 1 if NAME has a nontrivial access control list, +@@ -398,14 +436,35 @@ acl_get_link_np (char const *name, acl_type_t type) + If the d_type value is not known, use DT_UNKNOWN though this may be less + efficient. */ + int +-file_has_aclinfo (MAYBE_UNUSED char const *restrict name, ++file_has_aclinfo (char const *restrict name, + struct aclinfo *restrict ai, int flags) ++{ ++ return fdfile_has_aclinfo (-1, name, ai, flags); ++} ++ ++/* Return 1 if FD aka NAME has a nontrivial access control list, ++ 0 if ACLs are not supported, or if NAME has no or only a base ACL, ++ and -1 (setting errno) on error. Note callers can determine ++ if ACLs are not supported as errno is set in that case also. ++ Ignore FD if it is negative. ++ Set *AI to ACL info regardless of return value. ++ FLAGS should be a d_type value, optionally ORed with ++ - _GL_DT_NOTDIR if it is known that NAME is not a directory, ++ - ACL_GET_SCONTEXT to retrieve security context and return 1 if present, ++ - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link; ++ otherwise do not follow them if possible. ++ If the d_type value is not known, use DT_UNKNOWN though this may be less ++ efficient. */ ++int ++fdfile_has_aclinfo (MAYBE_UNUSED int fd, ++ MAYBE_UNUSED char const *restrict name, ++ struct aclinfo *restrict ai, int flags) + { + MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX; + + #if USE_LINUX_XATTR + int initial_errno = errno; +- get_aclinfo (name, ai, flags); ++ get_aclinfo (fd, name, ai, flags); + + if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) + { +@@ -418,11 +477,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + In earlier Fedora the two types of ACLs were mutually exclusive. + Attempt to work correctly on both kinds of systems. */ + +- if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) ++ if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags)) + return +- (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) ++ (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags) + || ((d_type == DT_DIR || d_type == DT_UNKNOWN) +- && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); ++ && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags))); + + /* A buffer large enough to hold any trivial NFSv4 ACL. + The max length of a trivial NFSv4 ACL is 6 words for owner, +@@ -432,8 +491,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + everyone is another word to hold "EVERYONE@". */ + uint32_t buf[2 * (6 + 6 + 7)]; + +- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) +- (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); ++ int ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) ++ (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)) ++ : fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); + if (ret < 0) + switch (errno) + { +@@ -467,20 +528,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + /* On Linux, acl_extended_file is an optimized function: It only + makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for + ACL_TYPE_DEFAULT. */ +- ret = ((flags & ACL_SYMLINK_FOLLOW +- ? acl_extended_file +- : acl_extended_file_nofollow) +- (name)); ++ ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ++ ? acl_extended_file ++ : acl_extended_file_nofollow) ++ (name)) ++ : acl_extended_fd (fd)); + # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) + and acl_get_file (name, ACL_TYPE_DEFAULT) + always return NULL / EINVAL. There is no point in making + these two useless calls. The real ACL is retrieved through +- acl_get_file (name, ACL_TYPE_EXTENDED). */ +- acl_t acl = ((flags & ACL_SYMLINK_FOLLOW +- ? acl_get_file +- : acl_get_link_np) +- (name, ACL_TYPE_EXTENDED)); ++ ACL_TYPE_EXTENDED. */ ++ acl_t acl = ++ (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np) ++ (name, ACL_TYPE_EXTENDED)) ++ : acl_get_fd_np (fd, ACL_TYPE_EXTENDED)); + if (acl) + { + ret = acl_extended_nontrivial (acl); +@@ -489,13 +553,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + else + ret = -1; + # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ +- acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; +-# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ +- if (! (flags & ACL_SYMLINK_FOLLOW)) +- acl_get_file_or_link = acl_get_link_np; +-# endif + +- acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS); ++ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags); + if (acl) + { + ret = acl_access_nontrivial (acl); +@@ -517,7 +576,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + && (d_type == DT_DIR + || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR)))) + { +- acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT); ++ acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags); + if (acl) + { + # ifdef __CYGWIN__ /* Cygwin >= 2.5 */ +@@ -562,7 +621,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + /* Solaris 10 (newer version), which has additional API declared in + (acl_t) and implemented in libsec (acl_set, acl_trivial, +- acl_fromtext, ...). */ ++ acl_fromtext, ...). ++ ++ Ignore FD, unfortunately. That is better than mishandling ++ ZFS-style ACLs, as the general case code does. */ + return acl_trivial (name); + + # else /* Solaris, Cygwin, general case */ +@@ -586,7 +648,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + for (;;) + { +- count = acl (name, GETACL, alloc, entries); ++ count = (fd < 0 ++ ? acl (name, GETACL, alloc, entries) ++ : facl (fd, GETACL, alloc, entries)); + if (count < 0 && errno == ENOSPC) + { + /* Increase the size of the buffer. */ +@@ -657,7 +721,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + for (;;) + { +- count = acl (name, ACE_GETACL, alloc, entries); ++ count = (fd < 0 ++ ? acl (name, ACE_GETACL, alloc, entries) ++ : facl (fd, ACE_GETACL, alloc, entries)); + if (count < 0 && errno == ENOSPC) + { + /* Increase the size of the buffer. */ +@@ -722,7 +788,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl_entry entries[NACLENTRIES]; + int count; + +- count = getacl (name, NACLENTRIES, entries); ++ count = (fd < 0 ++ ? getacl (name, NACLENTRIES, entries) ++ : fgetacl (fd, NACLENTRIES, entries)); + + if (count < 0) + { +@@ -751,7 +819,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + { + struct stat statbuf; + +- if (stat (name, &statbuf) == -1 && errno != EOVERFLOW) ++ if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0 ++ && errno != EOVERFLOW) + return -1; + + return acl_nontrivial (count, entries); +@@ -765,6 +834,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl entries[NACLVENTRIES]; + int count; + ++ /* Ignore FD, unfortunately. */ + count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); + + if (count < 0) +@@ -809,7 +879,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + /* The docs say that type being 0 is equivalent to ACL_ANY, but it + is not true, in AIX 5.3. */ + type.u64 = ACL_ANY; +- if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) ++ if (0 <= (fd < 0 ++ ? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) ++ : aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode))) + break; + if (errno == ENOSYS) + return 0; +@@ -855,7 +927,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + union { struct acl a; char room[4096]; } u; + +- if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0) ++ if ((fd < 0 ++ ? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u) ++ : fstatacl (fd, STX_NORMAL, &u.a, sizeof u)) ++ < 0) + return -1; + + return acl_nontrivial (&u.a); +@@ -866,6 +941,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl entries[NACLENTRIES]; + int count; + ++ /* Ignore FD, unfortunately. */ + count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); + + if (count < 0) +diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c +index ad79661..282f4b2 100644 +--- a/lib/qcopy-acl.c ++++ b/lib/qcopy-acl.c +@@ -26,6 +26,7 @@ + #if USE_XATTR + + # include ++# include + # include + + # if HAVE_LINUX_XATTR_H +@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx) + a valid file descriptor, use file descriptor operations, else use + filename based operations on SRC_NAME. Likewise for DEST_DESC and + DST_NAME. ++ MODE should be the source file's st_mode. + If access control lists are not available, fchmod the target file to + MODE. Also sets the non-permission bits of the destination file + (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. +@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, + Functions attr_copy_* return 0 in case we copied something OR nothing + to copy */ + if (ret == 0) +- ret = source_desc <= 0 || dest_desc <= 0 +- ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) +- : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, +- is_attr_permissions, NULL); ++ { ++ ret = source_desc <= 0 || dest_desc <= 0 ++ ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) ++ : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, ++ is_attr_permissions, NULL); ++ ++ /* Copying can fail with EOPNOTSUPP even when the source ++ permissions are trivial (Bug#78328). Don't report an error ++ in this case, as the chmod_or_fchmod suffices. */ ++ if (ret < 0 && errno == EOPNOTSUPP) ++ { ++ /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR, ++ and DT_LNK (but DT_LNK is not possible here), ++ so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */ ++ int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN; ++ ++ struct aclinfo ai; ++ if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags)) ++ ret = 0; ++ aclinfo_free (&ai); ++ errno = EOPNOTSUPP; ++ } ++ } + #else + /* no XATTR, so we proceed the old dusty way */ + struct permission_context ctx; +-- +2.49.0 + + +From ed2bda5888829f4ebacd6dc9c86b7494dbf2a3b7 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 9 May 2025 18:48:03 -0700 +Subject: [PATCH 2/2] acl-tests: link with $(FILE_HAS_ACL_LIB) + +* modules/acl-tests (test_copy_acl_LDADD): Add +$(FILE_HAS_ACL_LIB), since qcopy-acl depends on file-has-acl. +Although this suggests that QCOPY_ACL_LIB should contain +FILE_HAS_ACL_LIB, I’m not sure whether that’s the right course of +action and anyway this is good enough for coreutils. + +(cherry picked from commit 955360a66c99bdd9ac3688519a8b521b06958fd3) +--- + gnulib-tests/gnulib.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk +index e222c63..4b78de4 100644 +--- a/gnulib-tests/gnulib.mk ++++ b/gnulib-tests/gnulib.mk +@@ -99,7 +99,7 @@ TESTS += \ + TESTS_ENVIRONMENT += USE_ACL=$(USE_ACL) + check_PROGRAMS += test-set-mode-acl test-copy-acl test-sameacls + test_set_mode_acl_LDADD = $(LDADD) $(LIB_ACL) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) +-test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) ++test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(FILE_HAS_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) + test_sameacls_LDADD = $(LDADD) $(LIB_ACL) @LIBINTL@ $(MBRTOWC_LIB) + EXTRA_DIST += test-set-mode-acl.sh test-set-mode-acl-1.sh test-set-mode-acl-2.sh test-copy-acl.sh test-copy-acl-1.sh test-copy-acl-2.sh test-set-mode-acl.c test-copy-acl.c test-sameacls.c macros.h + +-- +2.49.0 + diff --git a/coreutils.spec b/coreutils.spec index 727da1b..a9bbd58 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,11 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) +# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=8a356b77717a2e4f735ec06e326880ca1f61aadb +# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 +Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -278,6 +283,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon May 19 2025 Lukáš Zaoral - 9.7-2 +- cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) + * Wed Apr 09 2025 Lukáš Zaoral - 9.7-1 - rebase to latest upstream release (rhbz#2358624) From e454479c5cd5c28ccbbc0e3dc5668c33ffd7a683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 28 May 2025 09:40:47 +0200 Subject: [PATCH 22/29] sort: fix buffer under-read Resolves: CVE-2025-5278 --- coreutils-CVE-2025-5278.patch | 107 ++++++++++++++++++++++++++++++++++ coreutils-i18n.patch | 60 +++++++++---------- coreutils.spec | 9 ++- 3 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 coreutils-CVE-2025-5278.patch diff --git a/coreutils-CVE-2025-5278.patch b/coreutils-CVE-2025-5278.patch new file mode 100644 index 0000000..af81286 --- /dev/null +++ b/coreutils-CVE-2025-5278.patch @@ -0,0 +1,107 @@ +From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001 +From: Pádraig Brady +Date: Tue, 20 May 2025 16:03:44 +0100 +Subject: [PATCH] sort: fix buffer under-read (CWE-127) + +* src/sort.c (begfield): Check pointer adjustment +to avoid Out-of-range pointer offset (CWE-823). +(limfield): Likewise. +* tests/sort/sort-field-limit.sh: Add a new test, +which triggers with ASAN or Valgrind. +* tests/local.mk: Reference the new test. +Fixes https://bugs.gnu.org/78507 + +(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633) +--- + src/sort.c | 12 ++++++++++-- + tests/local.mk | 1 + + tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 2 deletions(-) + create mode 100755 tests/sort/sort-field-limit.sh + +diff --git a/src/sort.c b/src/sort.c +index b10183b..7af1a25 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by SCHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + schar); ++ size_t remaining_bytes = lim - ptr; ++ if (schar < remaining_bytes) ++ ptr += schar; ++ else ++ ptr = lim; + + return ptr; + } +@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by ECHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + echar); ++ size_t remaining_bytes = lim - ptr; ++ if (echar < remaining_bytes) ++ ptr += echar; ++ else ++ ptr = lim; + } + + return ptr; +diff --git a/tests/local.mk b/tests/local.mk +index 4da6756..642d225 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -388,6 +388,7 @@ all_tests = \ + tests/sort/sort-debug-keys.sh \ + tests/sort/sort-debug-warn.sh \ + tests/sort/sort-discrim.sh \ ++ tests/sort/sort-field-limit.sh \ + tests/sort/sort-files0-from.pl \ + tests/sort/sort-float.sh \ + tests/sort/sort-h-thousands-sep.sh \ +diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh +new file mode 100755 +index 0000000..52d8e1d +--- /dev/null ++++ b/tests/sort/sort-field-limit.sh +@@ -0,0 +1,35 @@ ++#!/bin/sh ++# From 7.2-9.7, this would trigger an out of bounds mem read ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++getlimits_ ++ ++# This issue triggers with valgrind or ASAN ++valgrind --error-exitcode=1 sort --version 2>/dev/null && ++ VALGRIND='valgrind --error-exitcode=1' ++ ++{ printf '%s\n' aa bb; } > in || framework_failure_ ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++Exit $fail +-- +2.49.0 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 38b871c..755f216 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From 3d25791ec9cc357a34620516d1c024ef17a4dd75 Mon Sep 17 00:00:00 2001 +From c657452b2d716807830c473bf36ef8d97c93cadf Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -3038,7 +3038,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index b10183b..fbf325b 100644 +index 7af1a25..d3dc684 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3295,7 +3295,7 @@ index b10183b..fbf325b 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1653,12 +1802,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3368,7 +3368,7 @@ index b10183b..fbf325b 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1673,10 +1881,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3381,7 +3381,7 @@ index b10183b..fbf325b 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1722,10 +1930,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3394,7 +3394,7 @@ index b10183b..fbf325b 100644 if (newlim) lim = newlim; } -@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1760,6 +1968,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3525,7 +3525,7 @@ index b10183b..fbf325b 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1846,8 +2178,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3550,7 +3550,7 @@ index b10183b..fbf325b 100644 line->keybeg = line_start; } } -@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) +@@ -1985,12 +2331,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3566,7 +3566,7 @@ index b10183b..fbf325b 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) +@@ -2002,7 +2346,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3575,7 +3575,7 @@ index b10183b..fbf325b 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) +@@ -2012,6 +2356,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3601,7 +3601,7 @@ index b10183b..fbf325b 100644 static int nan_compare (long double a, long double b) { -@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3610,7 +3610,7 @@ index b10183b..fbf325b 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2384,15 +2747,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2392,15 +2755,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3628,7 +3628,7 @@ index b10183b..fbf325b 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2538,7 +2900,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2546,7 +2908,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3637,7 +3637,7 @@ index b10183b..fbf325b 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2586,9 +2948,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2594,9 +2956,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3650,7 +3650,7 @@ index b10183b..fbf325b 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2599,9 +2961,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2607,9 +2969,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3663,7 +3663,7 @@ index b10183b..fbf325b 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2609,19 +2971,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2617,19 +2979,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3687,7 +3687,7 @@ index b10183b..fbf325b 100644 } } -@@ -2673,11 +3035,87 @@ diff_reversed (int diff, bool reversed) +@@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3776,7 +3776,7 @@ index b10183b..fbf325b 100644 { struct keyfield *key = keylist; -@@ -2758,7 +3196,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2766,7 +3204,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3785,7 +3785,7 @@ index b10183b..fbf325b 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2868,6 +3306,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2876,6 +3314,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3997,7 +3997,7 @@ index b10183b..fbf325b 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2895,7 +3538,7 @@ compare (struct line const *a, struct line const *b) +@@ -2903,7 +3546,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4006,7 +4006,7 @@ index b10183b..fbf325b 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4283,6 +4926,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4291,6 +4934,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4014,7 +4014,7 @@ index b10183b..fbf325b 100644 break; case 'g': key->general_numeric = true; -@@ -4362,7 +5006,7 @@ main (int argc, char **argv) +@@ -4370,7 +5014,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4023,7 +4023,7 @@ index b10183b..fbf325b 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4385,6 +5029,29 @@ main (int argc, char **argv) +@@ -4393,6 +5037,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4053,7 +4053,7 @@ index b10183b..fbf325b 100644 have_read_stdin = false; inittables (); -@@ -4655,13 +5322,34 @@ main (int argc, char **argv) +@@ -4663,13 +5330,34 @@ main (int argc, char **argv) case 't': { @@ -4092,7 +4092,7 @@ index b10183b..fbf325b 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4672,9 +5360,11 @@ main (int argc, char **argv) +@@ -4680,9 +5368,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4549,11 +4549,11 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 4da6756..fcbeef8 100644 +index 642d225..8e89530 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -390,6 +390,8 @@ all_tests = \ - tests/sort/sort-discrim.sh \ +@@ -391,6 +391,8 @@ all_tests = \ + tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ @@ -4561,7 +4561,7 @@ index 4da6756..fcbeef8 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -594,6 +596,7 @@ all_tests = \ +@@ -595,6 +597,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +4569,7 @@ index 4da6756..fcbeef8 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -750,6 +753,7 @@ all_tests = \ +@@ -751,6 +754,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ diff --git a/coreutils.spec b/coreutils.spec index a9bbd58..af3a17a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -37,6 +37,10 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch +# sort: fix buffer under-read (CVE-2025-5278) +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 +Patch106: coreutils-CVE-2025-5278.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -283,6 +287,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed May 28 2025 Lukáš Zaoral - 9.7-3 +- sort: fix buffer under-read (CVE-2025-5278) + * Mon May 19 2025 Lukáš Zaoral - 9.7-2 - cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) From c3c18147bda34d67a55115f5d5e2ff9b386380a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 30 Jun 2025 12:36:00 +0200 Subject: [PATCH 23/29] stty: add support for arbitrary baud rates Resolves: rhbz#2375439 --- coreutils-9.7-stty-arbitrary-baud-rates.patch | 669 ++++++++++++++++++ coreutils-i18n.patch | 14 +- coreutils.spec | 13 +- 3 files changed, 688 insertions(+), 8 deletions(-) create mode 100644 coreutils-9.7-stty-arbitrary-baud-rates.patch diff --git a/coreutils-9.7-stty-arbitrary-baud-rates.patch b/coreutils-9.7-stty-arbitrary-baud-rates.patch new file mode 100644 index 0000000..20d078b --- /dev/null +++ b/coreutils-9.7-stty-arbitrary-baud-rates.patch @@ -0,0 +1,669 @@ +From 8e5ee22042931bdac6488d61c5d59bcd1b0dba5f Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Mon, 16 Jun 2025 14:58:01 -0700 +Subject: [PATCH 1/5] stty: arbitrary or non-a priori known speed_t support + +Support the case where speed_t is simply a number, and in that case +assume that arbitrary values can be passed. This is assumed to be the +case when all known speed_t macros equal their own value. + +Try to probe for a variety of speed_t constants by trying to coax +$(CC) into emitting macro definitions (-E -dM). If this is not +supported, use a fairly extensive list of constants as a +fallback. This both improves the test for arbitrary speed support, as +well as allowing proper operation in the case where the constants are +not plain numbers and allows for handing enumerated speed constants +that were not known a priori when the source code was written. + +A simple shell script (mostly using sed) is used to turn the list of +constants (probed and predefined) into a pair of conversion functions, +baud_to_value() and value_to_baud(); string_to_baud() is then +reimplemented as a wrapper around the latter. + +* src/local.mk: Generate speedlist.h. +* src/speedgen: Portable shell script to generate speedlist.h. +* src/stty.c: Adjust string_to_baud to +convert from arbitrary numeric values. +* src/termios.c: A helper used when generating speedlist.h + +@lzaoral: This patch was amended to fix build failure in the +"single-binary" mode. + +(cherry picked from commit 357fda90d15fd3f7dba61e1ab322b183a48d0081) +--- + src/local.mk | 15 +++++- + src/speedgen | 85 ++++++++++++++++++++++++++++++ + src/stty.c | 143 +++++++++++++++++++------------------------------- + src/termios.c | 34 ++++++++++++ + 4 files changed, 188 insertions(+), 89 deletions(-) + create mode 100755 src/speedgen + create mode 100644 src/termios.c + +diff --git a/src/local.mk b/src/local.mk +index fd9dc81..3b8a34e 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -71,7 +71,8 @@ EXTRA_DIST += \ + src/dircolors.hin \ + src/primes.h \ + src/tac-pipe.c \ +- src/extract-magic ++ src/extract-magic \ ++ src/speedgen + + CLEANFILES += $(SCRIPTS) + +@@ -672,6 +673,18 @@ src/version.h: Makefile + $(AM_V_at)chmod a-w $@t + $(AM_V_at)mv $@t $@ + ++# Target-specific termios baud rate file. This is opportunistic; ++# if cc -E doesn't support -dM, the speedgen script still includes ++# an extensive fallback list of common constants. ++BUILT_SOURCES += src/speedlist.h ++src/speedlist.h: src/termios.c lib/config.h src/speedgen ++ $(AM_V_GEN)rm -f $@ ++ $(AM_V_at)${MKDIR_P} src ++ $(AM_V_at)$(COMPILE) -E -dM $< 2>/dev/null | \ ++ $(SHELL) $(srcdir)/src/speedgen $@t ++ $(AM_V_at)chmod a-w $@t ++ $(AM_V_at)mv $@t $@ ++ + # Generates a list of macro invocations like: + # SINGLE_BINARY_PROGRAM(program_name_str, main_name) + # once for each program list on $(single_binary_progs). Note that +diff --git a/src/speedgen b/src/speedgen +new file mode 100755 +index 0000000..f1647d9 +--- /dev/null ++++ b/src/speedgen +@@ -0,0 +1,85 @@ ++#!/bin/sh -e ++ ++out="$1" ++tmp="$out.tmp" ++ ++if [ -z "$out" ]; then ++ echo "Usage: $0 outfile" 2>&1 ++ exit 1 ++fi ++ ++s='[[:space:]]' # For brevity's sake ++ ++trap "rm -f '$tmp'" EXIT ++trap "rm -f '$tmp' '$out'" ERR HUP INT QUIT TERM ++ ++# Fallback list of speeds that are always tested for ++defspeeds="0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 7200 9600 \ ++14400 19200 28800 33600 38400 57600 76800 115200 153600 230400 307200 \ ++460800 500000 576000 614400 921600 1000000 1152000 1500000 \ ++2000000 2500000 3000000 3500000 4000000 5000000 10000000" ++( ++ sed -n -e "s/^$s*\#$s*define$s$s*B\\([1-9][0-9]*\\)$s.*\$/\\1/p" ++ for s in $defspeeds; do echo "$s"; done ++) | sort -n | uniq > "$tmp" ++ ++cat > "$out" <<'EOF' ++#ifndef SPEEDLIST_H ++# define SPEEDLIST_H 1 ++ ++# if 1 \ ++EOF ++ ++sed -e 's/^.*$/ \&\& (!defined(B&) || B& == &) \\/' < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ ++# define TERMIOS_SPEED_T_SANE 1 ++ ++# endif ++ ++ATTRIBUTE_CONST ++static unsigned long int ++baud_to_value (speed_t speed) ++{ ++# ifdef TERMIOS_SPEED_T_SANE ++ return speed; ++# else ++ switch (speed) ++ { ++EOF ++ ++sed -e 's/^.*$/# ifdef B&\n case B&: return &;\n# endif/' \ ++ < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ default: return -1; ++ } ++# endif ++} ++ ++ATTRIBUTE_CONST ++static speed_t ++value_to_baud (unsigned long int value) ++{ ++# ifdef TERMIOS_SPEED_T_SANE ++ speed_t speed = value; ++ if (speed != value) ++ speed = (speed_t) -1; /* Unrepresentable (overflow?) */ ++ return speed; ++# else ++ switch (value) ++ { ++EOF ++ ++sed -e 's/^.*$/# ifdef B&\n case &: return B&;\n# endif/' \ ++ < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ default: return (speed_t) -1; ++ } ++# endif ++} ++ ++#endif ++EOF +diff --git a/src/stty.c b/src/stty.c +index 133b33c..561de1c 100644 +--- a/src/stty.c ++++ b/src/stty.c +@@ -55,6 +55,7 @@ + + #include "system.h" + #include "assure.h" ++#include "c-ctype.h" + #include "fd-reopen.h" + #include "quote.h" + #include "xdectoint.h" +@@ -2172,100 +2173,66 @@ recover_mode (char const *arg, struct termios *mode) + return true; + } + +-struct speed_map +-{ +- char const *string; /* ASCII representation. */ +- speed_t speed; /* Internal form. */ +- unsigned long int value; /* Numeric value. */ +-}; +- +-static struct speed_map const speeds[] = +-{ +- {"0", B0, 0}, +- {"50", B50, 50}, +- {"75", B75, 75}, +- {"110", B110, 110}, +- {"134", B134, 134}, +- {"134.5", B134, 134}, +- {"150", B150, 150}, +- {"200", B200, 200}, +- {"300", B300, 300}, +- {"600", B600, 600}, +- {"1200", B1200, 1200}, +- {"1800", B1800, 1800}, +- {"2400", B2400, 2400}, +- {"4800", B4800, 4800}, +- {"9600", B9600, 9600}, +- {"19200", B19200, 19200}, +- {"38400", B38400, 38400}, +- {"exta", B19200, 19200}, +- {"extb", B38400, 38400}, +-#ifdef B57600 +- {"57600", B57600, 57600}, +-#endif +-#ifdef B115200 +- {"115200", B115200, 115200}, +-#endif +-#ifdef B230400 +- {"230400", B230400, 230400}, +-#endif +-#ifdef B460800 +- {"460800", B460800, 460800}, +-#endif +-#ifdef B500000 +- {"500000", B500000, 500000}, +-#endif +-#ifdef B576000 +- {"576000", B576000, 576000}, +-#endif +-#ifdef B921600 +- {"921600", B921600, 921600}, +-#endif +-#ifdef B1000000 +- {"1000000", B1000000, 1000000}, +-#endif +-#ifdef B1152000 +- {"1152000", B1152000, 1152000}, +-#endif +-#ifdef B1500000 +- {"1500000", B1500000, 1500000}, +-#endif +-#ifdef B2000000 +- {"2000000", B2000000, 2000000}, +-#endif +-#ifdef B2500000 +- {"2500000", B2500000, 2500000}, +-#endif +-#ifdef B3000000 +- {"3000000", B3000000, 3000000}, +-#endif +-#ifdef B3500000 +- {"3500000", B3500000, 3500000}, +-#endif +-#ifdef B4000000 +- {"4000000", B4000000, 4000000}, +-#endif +- {nullptr, 0, 0} +-}; ++/* Autogenerated conversion functions to/from speed_t */ ++#include "speedlist.h" + + ATTRIBUTE_PURE + static speed_t + string_to_baud (char const *arg) + { +- for (int i = 0; speeds[i].string != nullptr; ++i) +- if (STREQ (arg, speeds[i].string)) +- return speeds[i].speed; +- return (speed_t) -1; +-} ++ char *ep; ++ unsigned long value; ++ unsigned char c; + +-ATTRIBUTE_PURE +-static unsigned long int +-baud_to_value (speed_t speed) +-{ +- for (int i = 0; speeds[i].string != nullptr; ++i) +- if (speed == speeds[i].speed) +- return speeds[i].value; +- return 0; ++ /* Explicitly disallow negative numbers. */ ++ while (c_isspace (*arg)) ++ arg++; ++ if (*arg == '-') ++ return (speed_t) -1; ++ ++ value = strtoul (arg, &ep, 10); ++ ++ c = *ep++; ++ if (c == '.') ++ { ++ /* Number includes a fraction. Round it to nearest-even. ++ Note in particular that 134.5 must round to 134! */ ++ c = *ep++; ++ if (c) ++ { ++ c -= '0'; ++ if (c > 9) ++ { ++ return (speed_t) -1; /* Garbage after otherwise valid number */ ++ } ++ else if (c > 5) ++ { ++ value++; ++ } ++ else if (c == 5) ++ { ++ while ((c = *ep++) == '0') ++ ; /* Skip zeroes after .5 */ ++ ++ if (c >= '1' && c <= '9') ++ value++; /* Nonzero digit, round up */ ++ else ++ value += (value & 1); /* Exactly in the middle, round even */ ++ } ++ } ++ } ++ else if (c) ++ { ++ /* Not a valid number; check for legacy aliases "exta" and "extb" */ ++ if (STREQ (arg, "exta")) ++ return B19200; ++ else if (STREQ (arg, "extb")) ++ return B38400; ++ else ++ return (speed_t) -1; ++ } ++ ++ return value_to_baud (value); + } + + static void +diff --git a/src/termios.c b/src/termios.c +new file mode 100644 +index 0000000..f17e12e +--- /dev/null ++++ b/src/termios.c +@@ -0,0 +1,34 @@ ++/* termios.c -- coax out Bxxx macros from termios.h ++ ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program 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 General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* This simply #includes headers which may or may not provide Bxxx ++ constant macros. This is run through the C preprocessor and defined ++ macros are extracted. ++ ++ In the case where the C preprocessor isn't capable of doing so, ++ the script this is fed through contains a pre-defined set of common ++ constants. */ ++ ++#include ++ ++#ifdef TERMIOS_NEEDS_XOPEN_SOURCE ++# define _XOPEN_SOURCE ++#endif ++ ++#include ++#include ++#include +-- +2.50.0 + + +From 60c9206391e2fac32639d3a143435d1dd9ec6421 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 17 Jun 2025 23:32:05 +0100 +Subject: [PATCH 2/5] tests: stty: adjust tests for arbitary speeds + +* tests/stty/stty-invalid.sh: Adjust to what is now invalid. +* tests/stty/stty.sh: Add checks for valid speed variants. +* tests/stty/bad-speed.sh: New test to ensure unsupported speeds +are diagnosed. + +(cherry picked from commit efaec8078142996d958b6720b85a13b12497c3d0) +--- + tests/local.mk | 1 + + tests/stty/bad-speed.sh | 50 ++++++++++++++++++++++++++++++++++++++ + tests/stty/stty-invalid.sh | 10 ++++++-- + tests/stty/stty.sh | 10 ++++++++ + 4 files changed, 69 insertions(+), 2 deletions(-) + create mode 100755 tests/stty/bad-speed.sh + +diff --git a/tests/local.mk b/tests/local.mk +index 642d225..b68df41 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -425,6 +425,7 @@ all_tests = \ + tests/stat/stat-printf.pl \ + tests/stat/stat-slash.sh \ + tests/misc/stdbuf.sh \ ++ tests/stty/bad-speed.sh \ + tests/stty/stty.sh \ + tests/stty/stty-invalid.sh \ + tests/stty/stty-pairs.sh \ +diff --git a/tests/stty/bad-speed.sh b/tests/stty/bad-speed.sh +new file mode 100755 +index 0000000..d80d2e7 +--- /dev/null ++++ b/tests/stty/bad-speed.sh +@@ -0,0 +1,50 @@ ++#!/bin/sh ++# Ensure we handle cfsetispeed failing ++# which we did not before coreutils v9.1 ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ stty ++require_gcc_shared_ ++ ++# Replace each cfsetispeed call with a call to these stubs. ++cat > k.c <<'EOF' || framework_failure_ ++#include ++#include ++#include ++#include ++ ++int cfsetispeed(struct termios *termios_p, speed_t speed) ++{ ++ /* Leave a marker so we can identify if the function was intercepted. */ ++ fclose(fopen("preloaded", "w")); ++ ++ errno=EINVAL; ++ return -1; ++} ++EOF ++ ++# Then compile/link it: ++gcc_shared_ k.c k.so \ ++ || skip_ 'failed to build shared library' ++ ++( export LD_PRELOAD=$LD_PRELOAD:./k.so ++ returns_ 1 stty ispeed 9600 ) || fail=1 ++ ++test -e preloaded || skip_ 'LD_PRELOAD interception failed' ++ ++Exit $fail +diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh +index 4b87e2a..a1442a8 100755 +--- a/tests/stty/stty-invalid.sh ++++ b/tests/stty/stty-invalid.sh +@@ -20,6 +20,7 @@ + print_ver_ stty + require_controlling_input_terminal_ + require_trap_signame_ ++getlimits_ + + trap '' TTOU # Ignore SIGTTOU + +@@ -50,8 +51,13 @@ if tty -s = 9.8 supports arbitrary speeds on some systems ++# so restrict tests here to invalid numbers ++# We simulate unsupported numbers in a separate "LD_PRELOAD" test. ++WRAP_9600="$(expr $ULONG_OFLOW - 9600)" ++for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do ++ returns_ 1 stty ispeed "$speed" || fail=1 ++done + + # Just in case either of the above mistakenly succeeds (and changes + # the state of our tty), try to restore the initial state. +diff --git a/tests/stty/stty.sh b/tests/stty/stty.sh +index dab4cd0..c0f7494 100755 +--- a/tests/stty/stty.sh ++++ b/tests/stty/stty.sh +@@ -95,4 +95,14 @@ for W in $(seq 80 90); do + test "$output_width" -le "$W" || fail=1 + done + ++# Ensure we support varied numeric forms ++# with appropriate rounding ++if stty ispeed '9600'; then ++ stty ispeed ' +9600' || fail=1 ++ stty ispeed '9600.49' || fail=1 ++ stty ispeed '9600.50' || fail=1 ++ stty ispeed '9599.51' || fail=1 ++ stty ispeed ' 9600.' || fail=1 ++fi ++ + Exit $fail +-- +2.50.0 + + +From a47c15eea3ffe08662415ae13873b40c7ffcdb43 Mon Sep 17 00:00:00 2001 +From: Collin Funk +Date: Sat, 21 Jun 2025 22:05:19 -0700 +Subject: [PATCH 3/5] build: add src/termios.c to the tarball + +* src/local.mk (EXTRA_DIST): Add src/termios.c. + +(cherry picked from commit b7db7757831e93ca44ae59e1921bc4ebbc87974f) +--- + src/local.mk | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/local.mk b/src/local.mk +index 3b8a34e..188dda1 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -72,7 +72,8 @@ EXTRA_DIST += \ + src/primes.h \ + src/tac-pipe.c \ + src/extract-magic \ +- src/speedgen ++ src/speedgen \ ++ src/termios.c + + CLEANFILES += $(SCRIPTS) + +-- +2.50.0 + + +From caa439bf750193bcbed215a6676053f0b3c96e21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 22 Jun 2025 15:01:21 +0100 +Subject: [PATCH 4/5] doc: stty: adjust description of supported speeds + +* doc/coreutils.texi (stty invocation): Remove now imprecise +list of speeds given we may now support higher or arbitrary speeds. +Mention that we may support higher or arbitrary speeds. + +(cherry picked from commit 8b05eca972f70858749a946ac24f08d0718c1be6) +--- + doc/coreutils.texi | 21 ++------------------- + 1 file changed, 2 insertions(+), 19 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 6d1ee11..c04af2b 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -15932,25 +15932,8 @@ Print the terminal speed. + Set the input and output speeds to @var{n}. @var{n} can be one of: 0 + 50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 + 38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; +-@code{extb} is the same as 38400. Many systems, including GNU/Linux, +-support higher speeds. The @command{stty} command includes support +-for speeds of +-57600, +-115200, +-230400, +-460800, +-500000, +-576000, +-921600, +-1000000, +-1152000, +-1500000, +-2000000, +-2500000, +-3000000, +-3500000, +-or +-4000000 where the system supports these. ++@code{extb} is the same as 38400. Many systems, support arbitrary ++or higher speeds. + 0 hangs up the line if @option{-clocal} is set. + @end table + +-- +2.50.0 + + +From 8e48d56c2aa10f9875ffe1ec051a17f0eab6d2f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 22 Jun 2025 16:40:04 +0100 +Subject: [PATCH 5/5] stty: stricter floating point parsing + +* src/stty.c (string_to_baud): Disallow extraneous characters +after floating point numbers. +* tests/stty/stty-invalid.sh: Add test cases. + +(cherry picked from commit 3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d) +--- + src/stty.c | 27 +++++++++++++-------------- + tests/stty/stty-invalid.sh | 3 ++- + 2 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/src/stty.c b/src/stty.c +index 561de1c..0163ea4 100644 +--- a/src/stty.c ++++ b/src/stty.c +@@ -2200,25 +2200,24 @@ string_to_baud (char const *arg) + c = *ep++; + if (c) + { +- c -= '0'; +- if (c > 9) ++ unsigned char d = c - '0'; ++ if (d > 5) ++ value++; ++ else if (d == 5) + { +- return (speed_t) -1; /* Garbage after otherwise valid number */ +- } +- else if (c > 5) +- { +- value++; +- } +- else if (c == 5) +- { +- while ((c = *ep++) == '0') +- ; /* Skip zeroes after .5 */ ++ while ((c = *ep++) == '0'); /* Skip zeroes after .5 */ + +- if (c >= '1' && c <= '9') +- value++; /* Nonzero digit, round up */ ++ if (c) ++ value++; /* Nonzero, round up */ + else + value += (value & 1); /* Exactly in the middle, round even */ + } ++ ++ while (c_isdigit (c)) /* Skip remaining digits. */ ++ c = *ep++; ++ ++ if (c) ++ return (speed_t) -1; /* Garbage after otherwise valid number */ + } + } + else if (c) +diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh +index a1442a8..868ed1d 100755 +--- a/tests/stty/stty-invalid.sh ++++ b/tests/stty/stty-invalid.sh +@@ -55,7 +55,8 @@ fi + # so restrict tests here to invalid numbers + # We simulate unsupported numbers in a separate "LD_PRELOAD" test. + WRAP_9600="$(expr $ULONG_OFLOW - 9600)" +-for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do ++for speed in 9599.. 9600.. 9600.5. 9600.50. 9600.0. ++9600 \ ++ -$WRAP_9600 --$WRAP_9600 0x2580 96E2 9600,0 '9600.0 '; do + returns_ 1 stty ispeed "$speed" || fail=1 + done + +-- +2.50.0 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 755f216..2917075 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c657452b2d716807830c473bf36ef8d97c93cadf Mon Sep 17 00:00:00 2001 +From c0db8de625ca1ae0e0f4784c4eb2c779eae0047f Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -2252,10 +2252,10 @@ index b64aad4..a156337 100644 case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index fd9dc81..5133cc0 100644 +index 188dda1..7db5753 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -476,8 +476,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -478,8 +478,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -4549,7 +4549,7 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 642d225..8e89530 100644 +index b68df41..0fe8193 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -391,6 +391,8 @@ all_tests = \ @@ -4561,7 +4561,7 @@ index 642d225..8e89530 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -595,6 +597,7 @@ all_tests = \ +@@ -596,6 +598,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +4569,7 @@ index 642d225..8e89530 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -751,6 +754,7 @@ all_tests = \ +@@ -752,6 +755,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -5198,5 +5198,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.49.0 +2.50.0 diff --git a/coreutils.spec b/coreutils.spec index af3a17a..dfe70d7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 3%{?dist} +Release: 4%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -41,6 +41,14 @@ Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch # https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 Patch106: coreutils-CVE-2025-5278.patch +# stty: add support for arbitrary baud rates (rhbz#2375439) +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=357fda90d15fd3f7dba61e1ab322b183a48d0081 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=efaec8078142996d958b6720b85a13b12497c3d0 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=b7db7757831e93ca44ae59e1921bc4ebbc87974f +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8b05eca972f70858749a946ac24f08d0718c1be6 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d +Patch107: coreutils-9.7-stty-arbitrary-baud-rates.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -287,6 +295,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jun 30 2025 Lukáš Zaoral - 9.7-4 +- stty: add support for arbitrary baud rates (rhbz#2375439) + * Wed May 28 2025 Lukáš Zaoral - 9.7-3 - sort: fix buffer under-read (CVE-2025-5278) From c493f607abc435122d1cb12a358a672bee09ee93 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 18:40:40 +0000 Subject: [PATCH 24/29] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index dfe70d7..17e98b3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 4%{?dist} +Release: 5%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 9.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Mon Jun 30 2025 Lukáš Zaoral - 9.7-4 - stty: add support for arbitrary baud rates (rhbz#2375439) From 20976b8be8f329b2ffc60ed31fba89ed8ad2106a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 24 Sep 2025 10:00:43 +0200 Subject: [PATCH 25/29] rebase to latest upstream release - remove downstream patch for selinux options deprecated since 2009 Resolves: rhbz#2397467 --- ...ils-9.6-cp-improve-nfsv4-acl-support.patch | 512 --------- coreutils-9.7-stty-arbitrary-baud-rates.patch | 669 ------------ coreutils-CVE-2025-5278.patch | 107 -- coreutils-df-direct.patch | 24 +- coreutils-i18n.patch | 976 +----------------- coreutils-python3.patch | 10 +- coreutils-selinux.patch | 87 -- coreutils.spec | 28 +- sources | 4 +- 9 files changed, 53 insertions(+), 2364 deletions(-) delete mode 100644 coreutils-9.6-cp-improve-nfsv4-acl-support.patch delete mode 100644 coreutils-9.7-stty-arbitrary-baud-rates.patch delete mode 100644 coreutils-CVE-2025-5278.patch delete mode 100644 coreutils-selinux.patch diff --git a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch deleted file mode 100644 index 1b36b1e..0000000 --- a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch +++ /dev/null @@ -1,512 +0,0 @@ -From 6ad28e2b6627caf7b83bf893027c087b8cea1a97 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 9 May 2025 18:02:29 -0700 -Subject: [PATCH 1/2] qcopy-acl: port better to NFSv4 on GNU/Linux - -Problem reported by Ian Dall in -and by Thomas Clark in . -* lib/file-has-acl.c (smack_new_label_from_file) [!HAVE_SMACK]: -New dummy function. -(has_xattr, get_aclinfo): New arg FD. All callers changed. -Remove some unnecessary MAYBE_UNUSEDs. -(acl_get_fd_np): Fall back on acl_get_fd if this function is -needed but not available. -(acl_get_fdfile): New function, if needed. -(file_has_aclinfo): Reimplement in terms of ... -(fdfile_has_aclinfo): ... this new function, -which also has an FD argument. -* lib/qcopy-acl.c [USE_XATTR]: Include dirent.h, for DT_DIR etc. -(qcopy_acl): If attr_copy_file or attr_copy_fd fail with EOPNOTSUPP, -don’t fail if the source has a trivial ACL (this is the part -that fixes the bug; the rest is optimization). - -(cherry picked from commit 8a356b77717a2e4f735ec06e326880ca1f61aadb) ---- - lib/acl.h | 2 + - lib/copy-acl.c | 1 + - lib/file-has-acl.c | 172 ++++++++++++++++++++++++++++++++------------- - lib/qcopy-acl.c | 29 ++++++-- - 4 files changed, 152 insertions(+), 52 deletions(-) - -diff --git a/lib/acl.h b/lib/acl.h -index 90fd24e..e3c134f 100644 ---- a/lib/acl.h -+++ b/lib/acl.h -@@ -79,6 +79,8 @@ struct aclinfo - bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; - int file_has_acl (char const *, struct stat const *); - int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); -+int fdfile_has_aclinfo (int, char const *restrict, -+ struct aclinfo *restrict, int); - - #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR - bool aclinfo_has_xattr (struct aclinfo const *, char const *) -diff --git a/lib/copy-acl.c b/lib/copy-acl.c -index c36f64e..2fce6c7 100644 ---- a/lib/copy-acl.c -+++ b/lib/copy-acl.c -@@ -33,6 +33,7 @@ - a valid file descriptor, use file descriptor operations, else use - filename based operations on SRC_NAME. Likewise for DEST_DESC and - DST_NAME. -+ MODE should be the source file's st_mode. - If access control lists are not available, fchmod the target file to - MODE. Also sets the non-permission bits of the destination file - (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index 66b920c..a356ee0 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path, - { - return -1; - } -+static ssize_t -+smack_new_label_from_file (MAYBE_UNUSED int fd, -+ MAYBE_UNUSED const char *xattr, -+ MAYBE_UNUSED char **label) -+{ -+ return -1; -+} - # endif - static bool - is_smack_enabled (void) -@@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai) - - static bool - has_xattr (char const *xattr, struct aclinfo const *ai, -- MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) -+ int fd, char const *restrict name, int flags) - { - if (ai && aclinfo_has_xattr (ai, xattr)) - return true; - else if (!ai || aclinfo_may_indicate_xattr (ai)) - { -- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -- (name, xattr, NULL, 0)); -+ int ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -+ (name, xattr, NULL, 0)) -+ : fgetxattr (fd, xattr, NULL, 0)); - if (0 <= ret || (errno == ERANGE || errno == E2BIG)) - return true; - } -@@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr) - return false; - } - --/* Get attributes of the file NAME into AI, if USE_ACL. -+/* Get attributes of the file FD aka NAME into AI, if USE_ACL. -+ Ignore FD if it is negative. - If FLAGS & ACL_GET_SCONTEXT, also get security context. - If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */ - static void --get_aclinfo (char const *name, struct aclinfo *ai, int flags) -+get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) - { - int scontext_err = ENOTSUP; - ai->buf = ai->u.__gl_acl_ch; -@@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr); - while (true) - { -- ai->size = lsxattr (name, ai->buf, acl_alloc); -+ ai->size = (fd < 0 -+ ? lsxattr (name, ai->buf, acl_alloc) -+ : flistxattr (fd, ai->buf, acl_alloc)); - if (0 < ai->size) - break; - ai->u.err = ai->size < 0 ? errno : 0; -@@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - break; - - /* The buffer was too small. Find how large it should have been. */ -- ssize_t size = lsxattr (name, NULL, 0); -+ ssize_t size = (fd < 0 -+ ? lsxattr (name, NULL, 0) -+ : flistxattr (fd, NULL, 0)); - if (size <= 0) - { - ai->size = size; -@@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - { - if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) - { -- ssize_t r = smack_new_label_from_path (name, "security.SMACK64", -- flags & ACL_SYMLINK_FOLLOW, -- &ai->scontext); -+ static char const SMACK64[] = "security.SMACK64"; -+ ssize_t r = -+ (fd < 0 -+ ? smack_new_label_from_path (name, SMACK64, -+ flags & ACL_SYMLINK_FOLLOW, -+ &ai->scontext) -+ : smack_new_label_from_file (fd, SMACK64, &ai->scontext)); - scontext_err = r < 0 ? errno : 0; - } - } -@@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) - { - ssize_t r = -- ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) -- (name, &ai->scontext)); -+ (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) -+ (name, &ai->scontext)) -+ : fgetfilecon (fd, &ai->scontext)); - scontext_err = r < 0 ? errno : 0; - # ifndef SE_SELINUX_INLINE - /* Gnulib's selinux-h module is not in use, so getfilecon and -@@ -362,11 +382,13 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) - } - #endif - --#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ -- && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ -- && !HAVE_ACL_GET_LINK_NP) --# include --# ifdef O_PATH -+#if (!USE_LINUX_XATTR && USE_ACL && !HAVE_ACL_EXTENDED_FILE \ -+ && !HAVE_ACL_TYPE_EXTENDED) -+ -+# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP -+# include -+# ifdef O_PATH -+# define acl_get_fd_np(fd, type) acl_get_fd (fd) - - /* Like acl_get_file, but do not follow symbolic links. */ - static acl_t -@@ -381,8 +403,24 @@ acl_get_link_np (char const *name, acl_type_t type) - errno = err; - return r; - } --# define HAVE_ACL_GET_LINK_NP 1 -+# define HAVE_ACL_GET_LINK_NP 1 -+# endif - # endif -+ -+static acl_t -+acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags) -+{ -+ acl_t (*get) (char const *, acl_type_t) = acl_get_file; -+# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ -+ if (0 <= fd) -+ return acl_get_fd_np (fd, type); -+ if (! (flags & ACL_SYMLINK_FOLLOW)) -+ get = acl_get_link_np; -+# else -+ /* Ignore FD and FLAGS, unfortunately. */ -+# endif -+ return get (name, type); -+} - #endif - - /* Return 1 if NAME has a nontrivial access control list, -@@ -398,14 +436,35 @@ acl_get_link_np (char const *name, acl_type_t type) - If the d_type value is not known, use DT_UNKNOWN though this may be less - efficient. */ - int --file_has_aclinfo (MAYBE_UNUSED char const *restrict name, -+file_has_aclinfo (char const *restrict name, - struct aclinfo *restrict ai, int flags) -+{ -+ return fdfile_has_aclinfo (-1, name, ai, flags); -+} -+ -+/* Return 1 if FD aka NAME has a nontrivial access control list, -+ 0 if ACLs are not supported, or if NAME has no or only a base ACL, -+ and -1 (setting errno) on error. Note callers can determine -+ if ACLs are not supported as errno is set in that case also. -+ Ignore FD if it is negative. -+ Set *AI to ACL info regardless of return value. -+ FLAGS should be a d_type value, optionally ORed with -+ - _GL_DT_NOTDIR if it is known that NAME is not a directory, -+ - ACL_GET_SCONTEXT to retrieve security context and return 1 if present, -+ - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link; -+ otherwise do not follow them if possible. -+ If the d_type value is not known, use DT_UNKNOWN though this may be less -+ efficient. */ -+int -+fdfile_has_aclinfo (MAYBE_UNUSED int fd, -+ MAYBE_UNUSED char const *restrict name, -+ struct aclinfo *restrict ai, int flags) - { - MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX; - - #if USE_LINUX_XATTR - int initial_errno = errno; -- get_aclinfo (name, ai, flags); -+ get_aclinfo (fd, name, ai, flags); - - if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) - { -@@ -418,11 +477,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - In earlier Fedora the two types of ACLs were mutually exclusive. - Attempt to work correctly on both kinds of systems. */ - -- if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) -+ if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags)) - return -- (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) -+ (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags) - || ((d_type == DT_DIR || d_type == DT_UNKNOWN) -- && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); -+ && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags))); - - /* A buffer large enough to hold any trivial NFSv4 ACL. - The max length of a trivial NFSv4 ACL is 6 words for owner, -@@ -432,8 +491,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - everyone is another word to hold "EVERYONE@". */ - uint32_t buf[2 * (6 + 6 + 7)]; - -- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -- (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); -+ int ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -+ (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)) -+ : fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); - if (ret < 0) - switch (errno) - { -@@ -467,20 +528,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - /* On Linux, acl_extended_file is an optimized function: It only - makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for - ACL_TYPE_DEFAULT. */ -- ret = ((flags & ACL_SYMLINK_FOLLOW -- ? acl_extended_file -- : acl_extended_file_nofollow) -- (name)); -+ ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW -+ ? acl_extended_file -+ : acl_extended_file_nofollow) -+ (name)) -+ : acl_extended_fd (fd)); - # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) - and acl_get_file (name, ACL_TYPE_DEFAULT) - always return NULL / EINVAL. There is no point in making - these two useless calls. The real ACL is retrieved through -- acl_get_file (name, ACL_TYPE_EXTENDED). */ -- acl_t acl = ((flags & ACL_SYMLINK_FOLLOW -- ? acl_get_file -- : acl_get_link_np) -- (name, ACL_TYPE_EXTENDED)); -+ ACL_TYPE_EXTENDED. */ -+ acl_t acl = -+ (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np) -+ (name, ACL_TYPE_EXTENDED)) -+ : acl_get_fd_np (fd, ACL_TYPE_EXTENDED)); - if (acl) - { - ret = acl_extended_nontrivial (acl); -@@ -489,13 +553,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - else - ret = -1; - # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ -- acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; --# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ -- if (! (flags & ACL_SYMLINK_FOLLOW)) -- acl_get_file_or_link = acl_get_link_np; --# endif - -- acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS); -+ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags); - if (acl) - { - ret = acl_access_nontrivial (acl); -@@ -517,7 +576,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - && (d_type == DT_DIR - || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR)))) - { -- acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT); -+ acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags); - if (acl) - { - # ifdef __CYGWIN__ /* Cygwin >= 2.5 */ -@@ -562,7 +621,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - /* Solaris 10 (newer version), which has additional API declared in - (acl_t) and implemented in libsec (acl_set, acl_trivial, -- acl_fromtext, ...). */ -+ acl_fromtext, ...). -+ -+ Ignore FD, unfortunately. That is better than mishandling -+ ZFS-style ACLs, as the general case code does. */ - return acl_trivial (name); - - # else /* Solaris, Cygwin, general case */ -@@ -586,7 +648,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - for (;;) - { -- count = acl (name, GETACL, alloc, entries); -+ count = (fd < 0 -+ ? acl (name, GETACL, alloc, entries) -+ : facl (fd, GETACL, alloc, entries)); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ -@@ -657,7 +721,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - for (;;) - { -- count = acl (name, ACE_GETACL, alloc, entries); -+ count = (fd < 0 -+ ? acl (name, ACE_GETACL, alloc, entries) -+ : facl (fd, ACE_GETACL, alloc, entries)); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ -@@ -722,7 +788,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl_entry entries[NACLENTRIES]; - int count; - -- count = getacl (name, NACLENTRIES, entries); -+ count = (fd < 0 -+ ? getacl (name, NACLENTRIES, entries) -+ : fgetacl (fd, NACLENTRIES, entries)); - - if (count < 0) - { -@@ -751,7 +819,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - { - struct stat statbuf; - -- if (stat (name, &statbuf) == -1 && errno != EOVERFLOW) -+ if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0 -+ && errno != EOVERFLOW) - return -1; - - return acl_nontrivial (count, entries); -@@ -765,6 +834,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl entries[NACLVENTRIES]; - int count; - -+ /* Ignore FD, unfortunately. */ - count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); - - if (count < 0) -@@ -809,7 +879,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - /* The docs say that type being 0 is equivalent to ACL_ANY, but it - is not true, in AIX 5.3. */ - type.u64 = ACL_ANY; -- if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) -+ if (0 <= (fd < 0 -+ ? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) -+ : aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode))) - break; - if (errno == ENOSYS) - return 0; -@@ -855,7 +927,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - union { struct acl a; char room[4096]; } u; - -- if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0) -+ if ((fd < 0 -+ ? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u) -+ : fstatacl (fd, STX_NORMAL, &u.a, sizeof u)) -+ < 0) - return -1; - - return acl_nontrivial (&u.a); -@@ -866,6 +941,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl entries[NACLENTRIES]; - int count; - -+ /* Ignore FD, unfortunately. */ - count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); - - if (count < 0) -diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c -index ad79661..282f4b2 100644 ---- a/lib/qcopy-acl.c -+++ b/lib/qcopy-acl.c -@@ -26,6 +26,7 @@ - #if USE_XATTR - - # include -+# include - # include - - # if HAVE_LINUX_XATTR_H -@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx) - a valid file descriptor, use file descriptor operations, else use - filename based operations on SRC_NAME. Likewise for DEST_DESC and - DST_NAME. -+ MODE should be the source file's st_mode. - If access control lists are not available, fchmod the target file to - MODE. Also sets the non-permission bits of the destination file - (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. -@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, - Functions attr_copy_* return 0 in case we copied something OR nothing - to copy */ - if (ret == 0) -- ret = source_desc <= 0 || dest_desc <= 0 -- ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) -- : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, -- is_attr_permissions, NULL); -+ { -+ ret = source_desc <= 0 || dest_desc <= 0 -+ ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) -+ : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, -+ is_attr_permissions, NULL); -+ -+ /* Copying can fail with EOPNOTSUPP even when the source -+ permissions are trivial (Bug#78328). Don't report an error -+ in this case, as the chmod_or_fchmod suffices. */ -+ if (ret < 0 && errno == EOPNOTSUPP) -+ { -+ /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR, -+ and DT_LNK (but DT_LNK is not possible here), -+ so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */ -+ int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN; -+ -+ struct aclinfo ai; -+ if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags)) -+ ret = 0; -+ aclinfo_free (&ai); -+ errno = EOPNOTSUPP; -+ } -+ } - #else - /* no XATTR, so we proceed the old dusty way */ - struct permission_context ctx; --- -2.49.0 - - -From ed2bda5888829f4ebacd6dc9c86b7494dbf2a3b7 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 9 May 2025 18:48:03 -0700 -Subject: [PATCH 2/2] acl-tests: link with $(FILE_HAS_ACL_LIB) - -* modules/acl-tests (test_copy_acl_LDADD): Add -$(FILE_HAS_ACL_LIB), since qcopy-acl depends on file-has-acl. -Although this suggests that QCOPY_ACL_LIB should contain -FILE_HAS_ACL_LIB, I’m not sure whether that’s the right course of -action and anyway this is good enough for coreutils. - -(cherry picked from commit 955360a66c99bdd9ac3688519a8b521b06958fd3) ---- - gnulib-tests/gnulib.mk | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk -index e222c63..4b78de4 100644 ---- a/gnulib-tests/gnulib.mk -+++ b/gnulib-tests/gnulib.mk -@@ -99,7 +99,7 @@ TESTS += \ - TESTS_ENVIRONMENT += USE_ACL=$(USE_ACL) - check_PROGRAMS += test-set-mode-acl test-copy-acl test-sameacls - test_set_mode_acl_LDADD = $(LDADD) $(LIB_ACL) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) --test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) -+test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(FILE_HAS_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) - test_sameacls_LDADD = $(LDADD) $(LIB_ACL) @LIBINTL@ $(MBRTOWC_LIB) - EXTRA_DIST += test-set-mode-acl.sh test-set-mode-acl-1.sh test-set-mode-acl-2.sh test-copy-acl.sh test-copy-acl-1.sh test-copy-acl-2.sh test-set-mode-acl.c test-copy-acl.c test-sameacls.c macros.h - --- -2.49.0 - diff --git a/coreutils-9.7-stty-arbitrary-baud-rates.patch b/coreutils-9.7-stty-arbitrary-baud-rates.patch deleted file mode 100644 index 20d078b..0000000 --- a/coreutils-9.7-stty-arbitrary-baud-rates.patch +++ /dev/null @@ -1,669 +0,0 @@ -From 8e5ee22042931bdac6488d61c5d59bcd1b0dba5f Mon Sep 17 00:00:00 2001 -From: "H. Peter Anvin" -Date: Mon, 16 Jun 2025 14:58:01 -0700 -Subject: [PATCH 1/5] stty: arbitrary or non-a priori known speed_t support - -Support the case where speed_t is simply a number, and in that case -assume that arbitrary values can be passed. This is assumed to be the -case when all known speed_t macros equal their own value. - -Try to probe for a variety of speed_t constants by trying to coax -$(CC) into emitting macro definitions (-E -dM). If this is not -supported, use a fairly extensive list of constants as a -fallback. This both improves the test for arbitrary speed support, as -well as allowing proper operation in the case where the constants are -not plain numbers and allows for handing enumerated speed constants -that were not known a priori when the source code was written. - -A simple shell script (mostly using sed) is used to turn the list of -constants (probed and predefined) into a pair of conversion functions, -baud_to_value() and value_to_baud(); string_to_baud() is then -reimplemented as a wrapper around the latter. - -* src/local.mk: Generate speedlist.h. -* src/speedgen: Portable shell script to generate speedlist.h. -* src/stty.c: Adjust string_to_baud to -convert from arbitrary numeric values. -* src/termios.c: A helper used when generating speedlist.h - -@lzaoral: This patch was amended to fix build failure in the -"single-binary" mode. - -(cherry picked from commit 357fda90d15fd3f7dba61e1ab322b183a48d0081) ---- - src/local.mk | 15 +++++- - src/speedgen | 85 ++++++++++++++++++++++++++++++ - src/stty.c | 143 +++++++++++++++++++------------------------------- - src/termios.c | 34 ++++++++++++ - 4 files changed, 188 insertions(+), 89 deletions(-) - create mode 100755 src/speedgen - create mode 100644 src/termios.c - -diff --git a/src/local.mk b/src/local.mk -index fd9dc81..3b8a34e 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -71,7 +71,8 @@ EXTRA_DIST += \ - src/dircolors.hin \ - src/primes.h \ - src/tac-pipe.c \ -- src/extract-magic -+ src/extract-magic \ -+ src/speedgen - - CLEANFILES += $(SCRIPTS) - -@@ -672,6 +673,18 @@ src/version.h: Makefile - $(AM_V_at)chmod a-w $@t - $(AM_V_at)mv $@t $@ - -+# Target-specific termios baud rate file. This is opportunistic; -+# if cc -E doesn't support -dM, the speedgen script still includes -+# an extensive fallback list of common constants. -+BUILT_SOURCES += src/speedlist.h -+src/speedlist.h: src/termios.c lib/config.h src/speedgen -+ $(AM_V_GEN)rm -f $@ -+ $(AM_V_at)${MKDIR_P} src -+ $(AM_V_at)$(COMPILE) -E -dM $< 2>/dev/null | \ -+ $(SHELL) $(srcdir)/src/speedgen $@t -+ $(AM_V_at)chmod a-w $@t -+ $(AM_V_at)mv $@t $@ -+ - # Generates a list of macro invocations like: - # SINGLE_BINARY_PROGRAM(program_name_str, main_name) - # once for each program list on $(single_binary_progs). Note that -diff --git a/src/speedgen b/src/speedgen -new file mode 100755 -index 0000000..f1647d9 ---- /dev/null -+++ b/src/speedgen -@@ -0,0 +1,85 @@ -+#!/bin/sh -e -+ -+out="$1" -+tmp="$out.tmp" -+ -+if [ -z "$out" ]; then -+ echo "Usage: $0 outfile" 2>&1 -+ exit 1 -+fi -+ -+s='[[:space:]]' # For brevity's sake -+ -+trap "rm -f '$tmp'" EXIT -+trap "rm -f '$tmp' '$out'" ERR HUP INT QUIT TERM -+ -+# Fallback list of speeds that are always tested for -+defspeeds="0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 7200 9600 \ -+14400 19200 28800 33600 38400 57600 76800 115200 153600 230400 307200 \ -+460800 500000 576000 614400 921600 1000000 1152000 1500000 \ -+2000000 2500000 3000000 3500000 4000000 5000000 10000000" -+( -+ sed -n -e "s/^$s*\#$s*define$s$s*B\\([1-9][0-9]*\\)$s.*\$/\\1/p" -+ for s in $defspeeds; do echo "$s"; done -+) | sort -n | uniq > "$tmp" -+ -+cat > "$out" <<'EOF' -+#ifndef SPEEDLIST_H -+# define SPEEDLIST_H 1 -+ -+# if 1 \ -+EOF -+ -+sed -e 's/^.*$/ \&\& (!defined(B&) || B& == &) \\/' < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ -+# define TERMIOS_SPEED_T_SANE 1 -+ -+# endif -+ -+ATTRIBUTE_CONST -+static unsigned long int -+baud_to_value (speed_t speed) -+{ -+# ifdef TERMIOS_SPEED_T_SANE -+ return speed; -+# else -+ switch (speed) -+ { -+EOF -+ -+sed -e 's/^.*$/# ifdef B&\n case B&: return &;\n# endif/' \ -+ < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ default: return -1; -+ } -+# endif -+} -+ -+ATTRIBUTE_CONST -+static speed_t -+value_to_baud (unsigned long int value) -+{ -+# ifdef TERMIOS_SPEED_T_SANE -+ speed_t speed = value; -+ if (speed != value) -+ speed = (speed_t) -1; /* Unrepresentable (overflow?) */ -+ return speed; -+# else -+ switch (value) -+ { -+EOF -+ -+sed -e 's/^.*$/# ifdef B&\n case &: return B&;\n# endif/' \ -+ < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ default: return (speed_t) -1; -+ } -+# endif -+} -+ -+#endif -+EOF -diff --git a/src/stty.c b/src/stty.c -index 133b33c..561de1c 100644 ---- a/src/stty.c -+++ b/src/stty.c -@@ -55,6 +55,7 @@ - - #include "system.h" - #include "assure.h" -+#include "c-ctype.h" - #include "fd-reopen.h" - #include "quote.h" - #include "xdectoint.h" -@@ -2172,100 +2173,66 @@ recover_mode (char const *arg, struct termios *mode) - return true; - } - --struct speed_map --{ -- char const *string; /* ASCII representation. */ -- speed_t speed; /* Internal form. */ -- unsigned long int value; /* Numeric value. */ --}; -- --static struct speed_map const speeds[] = --{ -- {"0", B0, 0}, -- {"50", B50, 50}, -- {"75", B75, 75}, -- {"110", B110, 110}, -- {"134", B134, 134}, -- {"134.5", B134, 134}, -- {"150", B150, 150}, -- {"200", B200, 200}, -- {"300", B300, 300}, -- {"600", B600, 600}, -- {"1200", B1200, 1200}, -- {"1800", B1800, 1800}, -- {"2400", B2400, 2400}, -- {"4800", B4800, 4800}, -- {"9600", B9600, 9600}, -- {"19200", B19200, 19200}, -- {"38400", B38400, 38400}, -- {"exta", B19200, 19200}, -- {"extb", B38400, 38400}, --#ifdef B57600 -- {"57600", B57600, 57600}, --#endif --#ifdef B115200 -- {"115200", B115200, 115200}, --#endif --#ifdef B230400 -- {"230400", B230400, 230400}, --#endif --#ifdef B460800 -- {"460800", B460800, 460800}, --#endif --#ifdef B500000 -- {"500000", B500000, 500000}, --#endif --#ifdef B576000 -- {"576000", B576000, 576000}, --#endif --#ifdef B921600 -- {"921600", B921600, 921600}, --#endif --#ifdef B1000000 -- {"1000000", B1000000, 1000000}, --#endif --#ifdef B1152000 -- {"1152000", B1152000, 1152000}, --#endif --#ifdef B1500000 -- {"1500000", B1500000, 1500000}, --#endif --#ifdef B2000000 -- {"2000000", B2000000, 2000000}, --#endif --#ifdef B2500000 -- {"2500000", B2500000, 2500000}, --#endif --#ifdef B3000000 -- {"3000000", B3000000, 3000000}, --#endif --#ifdef B3500000 -- {"3500000", B3500000, 3500000}, --#endif --#ifdef B4000000 -- {"4000000", B4000000, 4000000}, --#endif -- {nullptr, 0, 0} --}; -+/* Autogenerated conversion functions to/from speed_t */ -+#include "speedlist.h" - - ATTRIBUTE_PURE - static speed_t - string_to_baud (char const *arg) - { -- for (int i = 0; speeds[i].string != nullptr; ++i) -- if (STREQ (arg, speeds[i].string)) -- return speeds[i].speed; -- return (speed_t) -1; --} -+ char *ep; -+ unsigned long value; -+ unsigned char c; - --ATTRIBUTE_PURE --static unsigned long int --baud_to_value (speed_t speed) --{ -- for (int i = 0; speeds[i].string != nullptr; ++i) -- if (speed == speeds[i].speed) -- return speeds[i].value; -- return 0; -+ /* Explicitly disallow negative numbers. */ -+ while (c_isspace (*arg)) -+ arg++; -+ if (*arg == '-') -+ return (speed_t) -1; -+ -+ value = strtoul (arg, &ep, 10); -+ -+ c = *ep++; -+ if (c == '.') -+ { -+ /* Number includes a fraction. Round it to nearest-even. -+ Note in particular that 134.5 must round to 134! */ -+ c = *ep++; -+ if (c) -+ { -+ c -= '0'; -+ if (c > 9) -+ { -+ return (speed_t) -1; /* Garbage after otherwise valid number */ -+ } -+ else if (c > 5) -+ { -+ value++; -+ } -+ else if (c == 5) -+ { -+ while ((c = *ep++) == '0') -+ ; /* Skip zeroes after .5 */ -+ -+ if (c >= '1' && c <= '9') -+ value++; /* Nonzero digit, round up */ -+ else -+ value += (value & 1); /* Exactly in the middle, round even */ -+ } -+ } -+ } -+ else if (c) -+ { -+ /* Not a valid number; check for legacy aliases "exta" and "extb" */ -+ if (STREQ (arg, "exta")) -+ return B19200; -+ else if (STREQ (arg, "extb")) -+ return B38400; -+ else -+ return (speed_t) -1; -+ } -+ -+ return value_to_baud (value); - } - - static void -diff --git a/src/termios.c b/src/termios.c -new file mode 100644 -index 0000000..f17e12e ---- /dev/null -+++ b/src/termios.c -@@ -0,0 +1,34 @@ -+/* termios.c -- coax out Bxxx macros from termios.h -+ -+ Copyright (C) 2025 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program 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 General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* This simply #includes headers which may or may not provide Bxxx -+ constant macros. This is run through the C preprocessor and defined -+ macros are extracted. -+ -+ In the case where the C preprocessor isn't capable of doing so, -+ the script this is fed through contains a pre-defined set of common -+ constants. */ -+ -+#include -+ -+#ifdef TERMIOS_NEEDS_XOPEN_SOURCE -+# define _XOPEN_SOURCE -+#endif -+ -+#include -+#include -+#include --- -2.50.0 - - -From 60c9206391e2fac32639d3a143435d1dd9ec6421 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 17 Jun 2025 23:32:05 +0100 -Subject: [PATCH 2/5] tests: stty: adjust tests for arbitary speeds - -* tests/stty/stty-invalid.sh: Adjust to what is now invalid. -* tests/stty/stty.sh: Add checks for valid speed variants. -* tests/stty/bad-speed.sh: New test to ensure unsupported speeds -are diagnosed. - -(cherry picked from commit efaec8078142996d958b6720b85a13b12497c3d0) ---- - tests/local.mk | 1 + - tests/stty/bad-speed.sh | 50 ++++++++++++++++++++++++++++++++++++++ - tests/stty/stty-invalid.sh | 10 ++++++-- - tests/stty/stty.sh | 10 ++++++++ - 4 files changed, 69 insertions(+), 2 deletions(-) - create mode 100755 tests/stty/bad-speed.sh - -diff --git a/tests/local.mk b/tests/local.mk -index 642d225..b68df41 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -425,6 +425,7 @@ all_tests = \ - tests/stat/stat-printf.pl \ - tests/stat/stat-slash.sh \ - tests/misc/stdbuf.sh \ -+ tests/stty/bad-speed.sh \ - tests/stty/stty.sh \ - tests/stty/stty-invalid.sh \ - tests/stty/stty-pairs.sh \ -diff --git a/tests/stty/bad-speed.sh b/tests/stty/bad-speed.sh -new file mode 100755 -index 0000000..d80d2e7 ---- /dev/null -+++ b/tests/stty/bad-speed.sh -@@ -0,0 +1,50 @@ -+#!/bin/sh -+# Ensure we handle cfsetispeed failing -+# which we did not before coreutils v9.1 -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program 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 General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ stty -+require_gcc_shared_ -+ -+# Replace each cfsetispeed call with a call to these stubs. -+cat > k.c <<'EOF' || framework_failure_ -+#include -+#include -+#include -+#include -+ -+int cfsetispeed(struct termios *termios_p, speed_t speed) -+{ -+ /* Leave a marker so we can identify if the function was intercepted. */ -+ fclose(fopen("preloaded", "w")); -+ -+ errno=EINVAL; -+ return -1; -+} -+EOF -+ -+# Then compile/link it: -+gcc_shared_ k.c k.so \ -+ || skip_ 'failed to build shared library' -+ -+( export LD_PRELOAD=$LD_PRELOAD:./k.so -+ returns_ 1 stty ispeed 9600 ) || fail=1 -+ -+test -e preloaded || skip_ 'LD_PRELOAD interception failed' -+ -+Exit $fail -diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh -index 4b87e2a..a1442a8 100755 ---- a/tests/stty/stty-invalid.sh -+++ b/tests/stty/stty-invalid.sh -@@ -20,6 +20,7 @@ - print_ver_ stty - require_controlling_input_terminal_ - require_trap_signame_ -+getlimits_ - - trap '' TTOU # Ignore SIGTTOU - -@@ -50,8 +51,13 @@ if tty -s = 9.8 supports arbitrary speeds on some systems -+# so restrict tests here to invalid numbers -+# We simulate unsupported numbers in a separate "LD_PRELOAD" test. -+WRAP_9600="$(expr $ULONG_OFLOW - 9600)" -+for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do -+ returns_ 1 stty ispeed "$speed" || fail=1 -+done - - # Just in case either of the above mistakenly succeeds (and changes - # the state of our tty), try to restore the initial state. -diff --git a/tests/stty/stty.sh b/tests/stty/stty.sh -index dab4cd0..c0f7494 100755 ---- a/tests/stty/stty.sh -+++ b/tests/stty/stty.sh -@@ -95,4 +95,14 @@ for W in $(seq 80 90); do - test "$output_width" -le "$W" || fail=1 - done - -+# Ensure we support varied numeric forms -+# with appropriate rounding -+if stty ispeed '9600'; then -+ stty ispeed ' +9600' || fail=1 -+ stty ispeed '9600.49' || fail=1 -+ stty ispeed '9600.50' || fail=1 -+ stty ispeed '9599.51' || fail=1 -+ stty ispeed ' 9600.' || fail=1 -+fi -+ - Exit $fail --- -2.50.0 - - -From a47c15eea3ffe08662415ae13873b40c7ffcdb43 Mon Sep 17 00:00:00 2001 -From: Collin Funk -Date: Sat, 21 Jun 2025 22:05:19 -0700 -Subject: [PATCH 3/5] build: add src/termios.c to the tarball - -* src/local.mk (EXTRA_DIST): Add src/termios.c. - -(cherry picked from commit b7db7757831e93ca44ae59e1921bc4ebbc87974f) ---- - src/local.mk | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/local.mk b/src/local.mk -index 3b8a34e..188dda1 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -72,7 +72,8 @@ EXTRA_DIST += \ - src/primes.h \ - src/tac-pipe.c \ - src/extract-magic \ -- src/speedgen -+ src/speedgen \ -+ src/termios.c - - CLEANFILES += $(SCRIPTS) - --- -2.50.0 - - -From caa439bf750193bcbed215a6676053f0b3c96e21 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 22 Jun 2025 15:01:21 +0100 -Subject: [PATCH 4/5] doc: stty: adjust description of supported speeds - -* doc/coreutils.texi (stty invocation): Remove now imprecise -list of speeds given we may now support higher or arbitrary speeds. -Mention that we may support higher or arbitrary speeds. - -(cherry picked from commit 8b05eca972f70858749a946ac24f08d0718c1be6) ---- - doc/coreutils.texi | 21 ++------------------- - 1 file changed, 2 insertions(+), 19 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 6d1ee11..c04af2b 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -15932,25 +15932,8 @@ Print the terminal speed. - Set the input and output speeds to @var{n}. @var{n} can be one of: 0 - 50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 - 38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; --@code{extb} is the same as 38400. Many systems, including GNU/Linux, --support higher speeds. The @command{stty} command includes support --for speeds of --57600, --115200, --230400, --460800, --500000, --576000, --921600, --1000000, --1152000, --1500000, --2000000, --2500000, --3000000, --3500000, --or --4000000 where the system supports these. -+@code{extb} is the same as 38400. Many systems, support arbitrary -+or higher speeds. - 0 hangs up the line if @option{-clocal} is set. - @end table - --- -2.50.0 - - -From 8e48d56c2aa10f9875ffe1ec051a17f0eab6d2f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 22 Jun 2025 16:40:04 +0100 -Subject: [PATCH 5/5] stty: stricter floating point parsing - -* src/stty.c (string_to_baud): Disallow extraneous characters -after floating point numbers. -* tests/stty/stty-invalid.sh: Add test cases. - -(cherry picked from commit 3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d) ---- - src/stty.c | 27 +++++++++++++-------------- - tests/stty/stty-invalid.sh | 3 ++- - 2 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/src/stty.c b/src/stty.c -index 561de1c..0163ea4 100644 ---- a/src/stty.c -+++ b/src/stty.c -@@ -2200,25 +2200,24 @@ string_to_baud (char const *arg) - c = *ep++; - if (c) - { -- c -= '0'; -- if (c > 9) -+ unsigned char d = c - '0'; -+ if (d > 5) -+ value++; -+ else if (d == 5) - { -- return (speed_t) -1; /* Garbage after otherwise valid number */ -- } -- else if (c > 5) -- { -- value++; -- } -- else if (c == 5) -- { -- while ((c = *ep++) == '0') -- ; /* Skip zeroes after .5 */ -+ while ((c = *ep++) == '0'); /* Skip zeroes after .5 */ - -- if (c >= '1' && c <= '9') -- value++; /* Nonzero digit, round up */ -+ if (c) -+ value++; /* Nonzero, round up */ - else - value += (value & 1); /* Exactly in the middle, round even */ - } -+ -+ while (c_isdigit (c)) /* Skip remaining digits. */ -+ c = *ep++; -+ -+ if (c) -+ return (speed_t) -1; /* Garbage after otherwise valid number */ - } - } - else if (c) -diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh -index a1442a8..868ed1d 100755 ---- a/tests/stty/stty-invalid.sh -+++ b/tests/stty/stty-invalid.sh -@@ -55,7 +55,8 @@ fi - # so restrict tests here to invalid numbers - # We simulate unsupported numbers in a separate "LD_PRELOAD" test. - WRAP_9600="$(expr $ULONG_OFLOW - 9600)" --for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do -+for speed in 9599.. 9600.. 9600.5. 9600.50. 9600.0. ++9600 \ -+ -$WRAP_9600 --$WRAP_9600 0x2580 96E2 9600,0 '9600.0 '; do - returns_ 1 stty ispeed "$speed" || fail=1 - done - --- -2.50.0 - diff --git a/coreutils-CVE-2025-5278.patch b/coreutils-CVE-2025-5278.patch deleted file mode 100644 index af81286..0000000 --- a/coreutils-CVE-2025-5278.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001 -From: Pádraig Brady -Date: Tue, 20 May 2025 16:03:44 +0100 -Subject: [PATCH] sort: fix buffer under-read (CWE-127) - -* src/sort.c (begfield): Check pointer adjustment -to avoid Out-of-range pointer offset (CWE-823). -(limfield): Likewise. -* tests/sort/sort-field-limit.sh: Add a new test, -which triggers with ASAN or Valgrind. -* tests/local.mk: Reference the new test. -Fixes https://bugs.gnu.org/78507 - -(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633) ---- - src/sort.c | 12 ++++++++++-- - tests/local.mk | 1 + - tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++ - 3 files changed, 46 insertions(+), 2 deletions(-) - create mode 100755 tests/sort/sort-field-limit.sh - -diff --git a/src/sort.c b/src/sort.c -index b10183b..7af1a25 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key) - ++ptr; - - /* Advance PTR by SCHAR (if possible), but no further than LIM. */ -- ptr = MIN (lim, ptr + schar); -+ size_t remaining_bytes = lim - ptr; -+ if (schar < remaining_bytes) -+ ptr += schar; -+ else -+ ptr = lim; - - return ptr; - } -@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key) - ++ptr; - - /* Advance PTR by ECHAR (if possible), but no further than LIM. */ -- ptr = MIN (lim, ptr + echar); -+ size_t remaining_bytes = lim - ptr; -+ if (echar < remaining_bytes) -+ ptr += echar; -+ else -+ ptr = lim; - } - - return ptr; -diff --git a/tests/local.mk b/tests/local.mk -index 4da6756..642d225 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -388,6 +388,7 @@ all_tests = \ - tests/sort/sort-debug-keys.sh \ - tests/sort/sort-debug-warn.sh \ - tests/sort/sort-discrim.sh \ -+ tests/sort/sort-field-limit.sh \ - tests/sort/sort-files0-from.pl \ - tests/sort/sort-float.sh \ - tests/sort/sort-h-thousands-sep.sh \ -diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh -new file mode 100755 -index 0000000..52d8e1d ---- /dev/null -+++ b/tests/sort/sort-field-limit.sh -@@ -0,0 +1,35 @@ -+#!/bin/sh -+# From 7.2-9.7, this would trigger an out of bounds mem read -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program 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 General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ sort -+getlimits_ -+ -+# This issue triggers with valgrind or ASAN -+valgrind --error-exitcode=1 sort --version 2>/dev/null && -+ VALGRIND='valgrind --error-exitcode=1' -+ -+{ printf '%s\n' aa bb; } > in || framework_failure_ -+ -+_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1 -+compare in out || fail=1 -+ -+_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1 -+compare in out || fail=1 -+ -+Exit $fail --- -2.49.0 - diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index f5e3d73..2deacf7 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From d3117ae1bb422f771f1c19af54f81d5151f55065 Mon Sep 17 00:00:00 2001 +From ae768935e696a23e336601c5a239e147628ecf05 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index d1c282f..6d1ee11 100644 +index 937d8af..11fa1d6 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12588,6 +12588,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index d1c282f..6d1ee11 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index a969c5c..c465a3f 100644 +index 857f76c..07b21ea 100644 --- a/src/df.c +++ b/src/df.c -@@ -122,6 +122,9 @@ static bool print_type; +@@ -121,6 +121,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index a969c5c..c465a3f 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -249,13 +252,15 @@ enum +@@ -248,13 +251,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,7 +59,7 @@ index a969c5c..c465a3f 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -572,7 +577,10 @@ get_header (void) +@@ -571,7 +576,10 @@ get_header (void) for (idx_t col = 0; col < ncolumns; col++) { char *cell; @@ -71,7 +71,7 @@ index a969c5c..c465a3f 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1454,6 +1462,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1446,6 +1454,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index a969c5c..c465a3f 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1524,6 +1543,7 @@ or all file systems by default.\n\ +@@ -1516,6 +1535,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index a969c5c..c465a3f 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1618,6 +1638,9 @@ main (int argc, char **argv) +@@ -1610,6 +1630,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index a969c5c..c465a3f 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1714,6 +1737,13 @@ main (int argc, char **argv) +@@ -1706,6 +1729,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.49.0 +2.51.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2917075..92167bd 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c0db8de625ca1ae0e0f4784c4eb2c779eae0047f Mon Sep 17 00:00:00 2001 +From c5b102c8d9ddf1cc1109858615de3a9d6d57b7e6 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -7,17 +7,13 @@ Subject: [PATCH] coreutils-i18n.patch bootstrap.conf | 2 + configure.ac | 6 + lib/linebuffer.h | 8 + - lib/mbchar.c | 23 ++ - lib/mbchar.h | 383 +++++++++++++++++ lib/mbfile.c | 20 + lib/mbfile.h | 283 +++++++++++++ - m4/mbchar.m4 | 15 + m4/mbfile.m4 | 16 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- - src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 790 +++++++++++++++++++++++++++++++++--- @@ -27,19 +23,15 @@ Subject: [PATCH] coreutils-i18n.patch tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 50 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3632 insertions(+), 195 deletions(-) - create mode 100644 lib/mbchar.c - create mode 100644 lib/mbchar.h + 25 files changed, 2878 insertions(+), 167 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h - create mode 100644 m4/mbchar.m4 create mode 100644 m4/mbfile.m4 create mode 100644 tests/expand/mb.sh create mode 100644 tests/i18n/sort.sh @@ -47,10 +39,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 94c164e..cecbf26 100644 +index b8feef9..ab1eb93 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -166,6 +166,8 @@ gnulib_modules=" +@@ -169,6 +169,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +52,10 @@ index 94c164e..cecbf26 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 775c4cc..e6b5c9c 100644 +index 274eff4..5a1cfa5 100644 --- a/configure.ac +++ b/configure.ac -@@ -504,6 +504,12 @@ fi +@@ -465,6 +465,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -102,424 +94,6 @@ index ca56f80..509b7e6 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ -diff --git a/lib/mbchar.c b/lib/mbchar.c -new file mode 100644 -index 0000000..713c2f7 ---- /dev/null -+++ b/lib/mbchar.c -@@ -0,0 +1,23 @@ -+/* Copyright (C) 2001, 2006, 2009-2025 Free Software Foundation, Inc. -+ -+ This file 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. -+ -+ This file 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 this program. If not, see . */ -+ -+ -+#include -+ -+#define MBCHAR_INLINE _GL_EXTERN_INLINE -+ -+#include -+ -+#include "mbchar.h" -diff --git a/lib/mbchar.h b/lib/mbchar.h -new file mode 100644 -index 0000000..d77168e ---- /dev/null -+++ b/lib/mbchar.h -@@ -0,0 +1,383 @@ -+/* Multibyte character data type. -+ Copyright (C) 2001, 2005-2007, 2009-2025 Free Software Foundation, Inc. -+ -+ This file 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. -+ -+ This file 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 this program. If not, see . */ -+ -+/* Written by Bruno Haible . */ -+ -+/* A multibyte character is a short subsequence of a char* string, -+ representing a single 32-bit wide character. -+ -+ We use multibyte characters instead of 32-bit wide characters because -+ of the following goals: -+ 1) correct multibyte handling, i.e. operate according to the LC_CTYPE -+ locale, -+ 2) ease of maintenance, i.e. the maintainer needs not know all details -+ of the ISO C 99 standard, -+ 3) don't fail grossly if the input is not in the encoding set by the -+ locale, because often different encodings are in use in the same -+ countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), -+ 4) fast in the case of ASCII characters. -+ -+ Multibyte characters are only accessed through the mb* macros. -+ -+ mb_ptr (mbc) -+ return a pointer to the beginning of the multibyte sequence. -+ -+ mb_len (mbc) -+ returns the number of bytes occupied by the multibyte sequence. -+ Always > 0. -+ -+ mb_iseq (mbc, sc) -+ returns true if mbc is the standard ASCII character sc. -+ -+ mb_isnul (mbc) -+ returns true if mbc is the nul character. -+ -+ mb_cmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2. -+ -+ mb_casecmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2, modulo upper/lowercase conversion. -+ -+ mb_equal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal. -+ -+ mb_caseequal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. -+ -+ mb_isalnum (mbc) -+ returns true if mbc is alphanumeric. -+ -+ mb_isalpha (mbc) -+ returns true if mbc is alphabetic. -+ -+ mb_isascii(mbc) -+ returns true if mbc is plain ASCII. -+ -+ mb_isblank (mbc) -+ returns true if mbc is a blank. -+ -+ mb_iscntrl (mbc) -+ returns true if mbc is a control character. -+ -+ mb_isdigit (mbc) -+ returns true if mbc is a decimal digit. -+ -+ mb_isgraph (mbc) -+ returns true if mbc is a graphic character. -+ -+ mb_islower (mbc) -+ returns true if mbc is lowercase. -+ -+ mb_isprint (mbc) -+ returns true if mbc is a printable character. -+ -+ mb_ispunct (mbc) -+ returns true if mbc is a punctuation character. -+ -+ mb_isspace (mbc) -+ returns true if mbc is a space character. -+ -+ mb_isupper (mbc) -+ returns true if mbc is uppercase. -+ -+ mb_isxdigit (mbc) -+ returns true if mbc is a hexadecimal digit. -+ -+ mb_width (mbc) -+ returns the number of columns on the output device occupied by mbc. -+ Always >= 0. -+ -+ mb_putc (mbc, stream) -+ outputs mbc on stream, a byte oriented FILE stream opened for output. -+ -+ mb_setascii (&mbc, sc) -+ assigns the standard ASCII character sc to mbc. -+ (Only available if the 'mbfile' module is in use.) -+ -+ mb_copy (&destmbc, &srcmbc) -+ copies srcmbc to destmbc. -+ -+ Here are the function prototypes of the macros. -+ -+ extern const char * mb_ptr (const mbchar_t mbc); -+ extern size_t mb_len (const mbchar_t mbc); -+ extern bool mb_iseq (const mbchar_t mbc, char sc); -+ extern bool mb_isnul (const mbchar_t mbc); -+ extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_isalnum (const mbchar_t mbc); -+ extern bool mb_isalpha (const mbchar_t mbc); -+ extern bool mb_isascii (const mbchar_t mbc); -+ extern bool mb_isblank (const mbchar_t mbc); -+ extern bool mb_iscntrl (const mbchar_t mbc); -+ extern bool mb_isdigit (const mbchar_t mbc); -+ extern bool mb_isgraph (const mbchar_t mbc); -+ extern bool mb_islower (const mbchar_t mbc); -+ extern bool mb_isprint (const mbchar_t mbc); -+ extern bool mb_ispunct (const mbchar_t mbc); -+ extern bool mb_isspace (const mbchar_t mbc); -+ extern bool mb_isupper (const mbchar_t mbc); -+ extern bool mb_isxdigit (const mbchar_t mbc); -+ extern int mb_width (const mbchar_t mbc); -+ extern void mb_putc (const mbchar_t mbc, FILE *stream); -+ extern void mb_setascii (mbchar_t *new, char sc); -+ extern void mb_copy (mbchar_t *new, const mbchar_t *old); -+ */ -+ -+#ifndef _MBCHAR_H -+#define _MBCHAR_H 1 -+ -+/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ -+#if !_GL_CONFIG_H_INCLUDED -+ #error "Please include config.h first." -+#endif -+ -+#include -+#include -+ -+_GL_INLINE_HEADER_BEGIN -+#ifndef MBCHAR_INLINE -+# define MBCHAR_INLINE _GL_INLINE -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/* The longest multibyte characters, nowadays, are 4 bytes long. -+ Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ -+#define MBCHAR_BUF_SIZE 4 -+ -+struct mbchar -+{ -+ const char *ptr; /* pointer to current character */ -+ size_t bytes; /* number of bytes of current character, > 0 */ -+ bool wc_valid; /* true if wc is a valid 32-bit wide character */ -+ char32_t wc; /* if wc_valid: the current character */ -+#if defined GNULIB_MBFILE -+ char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ -+#endif -+}; -+ -+/* EOF (not a real character) is represented with bytes = 0 and -+ wc_valid = false. */ -+ -+typedef struct mbchar mbchar_t; -+ -+/* Access the current character. */ -+#define mb_ptr(mbc) ((mbc).ptr) -+#define mb_len(mbc) ((mbc).bytes) -+ -+/* Comparison of characters. */ -+#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) -+#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) -+#define mb_cmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_casecmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_equal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? (mbc1).wc == (mbc2).wc \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+#define mb_caseequal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+ -+/* , classification. */ -+#define mb_isascii(mbc) \ -+ ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) -+#define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) -+#define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) -+#define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) -+#define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) -+#define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) -+#define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) -+#define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) -+#define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) -+#define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) -+#define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) -+#define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) -+#define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) -+ -+/* Extra function. */ -+ -+/* Unprintable characters appear as a small box of width 1. */ -+#define MB_UNPRINTABLE_WIDTH 1 -+ -+MBCHAR_INLINE int -+mb_width_aux (char32_t wc) -+{ -+ int w = c32width (wc); -+ /* For unprintable characters, arbitrarily return 0 for control characters -+ and MB_UNPRINTABLE_WIDTH otherwise. */ -+ return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); -+} -+ -+#define mb_width(mbc) \ -+ ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) -+ -+/* Output. */ -+#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) -+ -+#if defined GNULIB_MBFILE -+/* Assignment. */ -+# define mb_setascii(mbc, sc) \ -+ ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ -+ (mbc)->wc = (mbc)->buf[0] = (sc)) -+#endif -+ -+/* Copying a character. */ -+MBCHAR_INLINE void -+mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) -+{ -+#if defined GNULIB_MBFILE -+ if (old_mbc->ptr == &old_mbc->buf[0]) -+ { -+ memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); -+ new_mbc->ptr = &new_mbc->buf[0]; -+ } -+ else -+#endif -+ new_mbc->ptr = old_mbc->ptr; -+ new_mbc->bytes = old_mbc->bytes; -+ if ((new_mbc->wc_valid = old_mbc->wc_valid)) -+ new_mbc->wc = old_mbc->wc; -+} -+ -+ -+/* is_basic(c) tests whether the single-byte character c is -+ - in the ISO C "basic character set" or is one of '@', '$', and '`' -+ which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in -+ practice are safe to treat as basic in the execution character set, -+ or -+ - in the POSIX "portable character set", which -+ -+ equally guarantees to be single-byte. -+ This is a convenience function, and is in this file only to share code -+ between mbiter.h, mbuiter.h, and mbfile.h. */ -+#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ -+ && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ -+ && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ -+ && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ -+ && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ -+ && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ -+ && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ -+ && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ -+ && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ -+ && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ -+ && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ -+ && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ -+ && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ -+ && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ -+ && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ -+ && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ -+ && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ -+ && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ -+ && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ -+ && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ -+ && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ -+ && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ -+ && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ -+ && ('|' == 124) && ('}' == 125) && ('~' == 126) -+/* The character set is ISO-646, not EBCDIC. */ -+# define IS_BASIC_ASCII 1 -+ -+/* All locale encodings (see localcharset.h) map the characters 0x00..0x7F -+ to U+0000..U+007F, like ASCII, except for -+ CP864 different mapping of '%' -+ SHIFT_JIS different mappings of 0x5C, 0x7E -+ JOHAB different mapping of 0x5C -+ However, these characters in the range 0x20..0x7E are in the ISO C -+ "basic character set" and in the POSIX "portable character set", which -+ ISO C and POSIX guarantee to be single-byte. Thus, locales with these -+ encodings are not POSIX compliant. And they are most likely not in use -+ any more (as of 2023). */ -+# define is_basic(c) ((unsigned char) (c) < 0x80) -+ -+#else -+ -+MBCHAR_INLINE bool -+is_basic (char c) -+{ -+ switch (c) -+ { -+ case '\0': -+ case '\007': case '\010': -+ case '\t': case '\n': case '\v': case '\f': case '\r': -+ case ' ': case '!': case '"': case '#': case '$': case '%': -+ case '&': case '\'': case '(': case ')': case '*': -+ case '+': case ',': case '-': case '.': case '/': -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ case ':': case ';': case '<': case '=': case '>': -+ case '?': case '@': -+ case 'A': case 'B': case 'C': case 'D': case 'E': -+ case 'F': case 'G': case 'H': case 'I': case 'J': -+ case 'K': case 'L': case 'M': case 'N': case 'O': -+ case 'P': case 'Q': case 'R': case 'S': case 'T': -+ case 'U': case 'V': case 'W': case 'X': case 'Y': -+ case 'Z': -+ case '[': case '\\': case ']': case '^': case '_': case '`': -+ case 'a': case 'b': case 'c': case 'd': case 'e': -+ case 'f': case 'g': case 'h': case 'i': case 'j': -+ case 'k': case 'l': case 'm': case 'n': case 'o': -+ case 'p': case 'q': case 'r': case 's': case 't': -+ case 'u': case 'v': case 'w': case 'x': case 'y': -+ case 'z': case '{': case '|': case '}': case '~': -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+#endif -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+_GL_INLINE_HEADER_END -+ -+#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 index 0000000..f4e3e77 @@ -835,27 +409,6 @@ index 0000000..c852f31 +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ -diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 -new file mode 100644 -index 0000000..b76f1d7 ---- /dev/null -+++ b/m4/mbchar.m4 -@@ -0,0 +1,15 @@ -+# mbchar.m4 -+# serial 9 -+dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. -+dnl This file is free software; the Free Software Foundation -+dnl gives unlimited permission to copy and/or distribute it, -+dnl with or without modifications, as long as this notice is preserved. -+dnl This file is offered as-is, without any warranty. -+ -+dnl autoconf tests required for use of mbchar.m4 -+dnl From Bruno Haible. -+ -+AC_DEFUN([gl_MBCHAR], -+[ -+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -+]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 index 0000000..1d126e0 @@ -879,7 +432,7 @@ index 0000000..1d126e0 + : +]) diff --git a/src/cut.c b/src/cut.c -index b424997..c9f181c 100644 +index f0effb9..36479d6 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1539,7 +1092,7 @@ index b424997..c9f181c 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 732123f..fdbef3f 100644 +index ca2ad4d..2ad24bf 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1671,7 +1224,7 @@ index 732123f..fdbef3f 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index fe6c8ed..80a1280 100644 +index 46ef4e3..e19469b 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -29,6 +29,18 @@ extern idx_t max_column_width; @@ -1848,414 +1401,11 @@ index 5ec7ce9..65ac315 100644 } } -diff --git a/src/fold.c b/src/fold.c -index b64aad4..a156337 100644 ---- a/src/fold.c -+++ b/src/fold.c -@@ -23,10 +23,32 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswprint(), iswblank(), wcwidth(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "fadvise.h" - #include "xdectoint.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# undef MB_LEN_MAX -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - #define TAB_WIDTH 8 - - /* The official name of this program (e.g., no 'g' prefix). */ -@@ -34,20 +56,41 @@ - - #define AUTHORS proper_name ("David MacKenzie") - -+#define FATAL_ERROR(Message) \ -+ do \ -+ { \ -+ error (0, 0, (Message)); \ -+ usage (2); \ -+ } \ -+ while (0) -+ -+enum operating_mode -+{ -+ /* Fold texts by columns that are at the given positions. */ -+ column_mode, -+ -+ /* Fold texts by bytes that are at the given positions. */ -+ byte_mode, -+ -+ /* Fold texts by characters that are at the given positions. */ -+ character_mode, -+}; -+ -+/* The argument shows current mode. (Default: column_mode) */ -+static enum operating_mode operating_mode; -+ - /* If nonzero, try to break on whitespace. */ - static bool break_spaces; - --/* If nonzero, count bytes, not column positions. */ --static bool count_bytes; -- - /* If nonzero, at least one of the files we read was standard input. */ - static bool have_read_stdin; - --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; - - static struct option const longopts[] = - { - {"bytes", no_argument, nullptr, 'b'}, -+ {"characters", no_argument, nullptr, 'c'}, - {"spaces", no_argument, nullptr, 's'}, - {"width", required_argument, nullptr, 'w'}, - {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - - fputs (_("\ - -b, --bytes count bytes rather than columns\n\ -+ -c, --characters count characters rather than columns\n\ - -s, --spaces break at spaces\n\ - -w, --width=WIDTH use WIDTH columns instead of 80\n\ - "), stdout); -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - static size_t - adjust_column (size_t column, char c) - { -- if (!count_bytes) -+ if (operating_mode != byte_mode) - { - if (c == '\b') - { -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) - to stdout, with maximum line length WIDTH. - Return true if successful. */ - --static bool --fold_file (char const *filename, size_t width) -+static void -+fold_text (FILE *istream, size_t width, int *saved_errno) - { -- FILE *istream; - int c; - size_t column = 0; /* Screen column where next char will go. */ - idx_t offset_out = 0; /* Index in 'line_out' for next char. */ - static char *line_out = nullptr; - static idx_t allocated_out = 0; -- int saved_errno; -- -- if (STREQ (filename, "-")) -- { -- istream = stdin; -- have_read_stdin = true; -- } -- else -- istream = fopen (filename, "r"); -- -- if (istream == nullptr) -- { -- error (0, errno, "%s", quotef (filename)); -- return false; -- } - - fadvise (istream, FADVISE_SEQUENTIAL); - -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) - bool found_blank = false; - idx_t logical_end = offset_out; - -+ /* If LINE_OUT has no wide character, -+ put a new wide character in LINE_OUT -+ if column is bigger than width. */ -+ if (offset_out == 0) -+ { -+ line_out[offset_out++] = c; -+ continue; -+ } -+ - /* Look for the last blank. */ - while (logical_end) - { -@@ -212,13 +249,224 @@ fold_file (char const *filename, size_t width) - line_out[offset_out++] = c; - } - -- saved_errno = errno; -+ *saved_errno = errno; - if (!ferror (istream)) -- saved_errno = 0; -+ *saved_errno = 0; - - if (offset_out) - fwrite (line_out, sizeof (char), offset_out, stdout); - -+} -+ -+#if HAVE_MBRTOWC -+static void -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) -+{ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ wint_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character which shows -+ as same character as WC. */ -+ mbstate_t state, state_bak; /* State of the stream. */ -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ -+ -+ static char *line_out = NULL; -+ idx_t offset_out = 0; /* Index in `line_out' for next char. */ -+ static idx_t allocated_out = 0; -+ -+ int increment; -+ size_t column = 0; -+ -+ size_t last_blank_pos; -+ size_t last_blank_column; -+ int is_blank_seen; -+ int last_blank_increment = 0; -+ int is_bs_following_last_blank; -+ size_t bs_following_last_blank_num; -+ int is_cr_after_last_blank; -+ -+#define CLEAR_FLAGS \ -+ do \ -+ { \ -+ last_blank_pos = 0; \ -+ last_blank_column = 0; \ -+ is_blank_seen = 0; \ -+ is_bs_following_last_blank = 0; \ -+ bs_following_last_blank_num = 0; \ -+ is_cr_after_last_blank = 0; \ -+ } \ -+ while (0) -+ -+#define START_NEW_LINE \ -+ do \ -+ { \ -+ putchar ('\n'); \ -+ column = 0; \ -+ offset_out = 0; \ -+ CLEAR_FLAGS; \ -+ } \ -+ while (0) -+ -+ CLEAR_FLAGS; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ for (;; bufpos += mblength, buflen -= mblength) -+ { -+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); -+ bufpos = buf; -+ } -+ -+ if (buflen < 1) -+ break; -+ -+ /* Get a wide character. */ -+ state_bak = state; -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ convfail++; -+ state = state_bak; -+ /* Fall through. */ -+ -+ case 0: -+ mblength = 1; -+ break; -+ } -+ -+rescan: -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ -+ increment = mblength; -+ else if (operating_mode == character_mode) /* character mode */ -+ increment = 1; -+ else /* column mode */ -+ { -+ switch (wc) -+ { -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; -+ -+ case L'\r': -+ increment = -1 * column; -+ break; -+ -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } -+ } -+ -+ if (column + increment > width && break_spaces && last_blank_pos) -+ { -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); -+ putchar ('\n'); -+ -+ offset_out = offset_out - last_blank_pos; -+ column = column - last_blank_column + ((is_cr_after_last_blank) -+ ? last_blank_increment : bs_following_last_blank_num); -+ memmove (line_out, line_out + last_blank_pos, offset_out); -+ CLEAR_FLAGS; -+ goto rescan; -+ } -+ -+ if (column + increment > width && column != 0) -+ { -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ goto rescan; -+ } -+ -+ if (allocated_out - offset_out <= mblength) -+ { -+ line_out = xpalloc (line_out, &allocated_out, 1, -1, sizeof *line_out); -+ } -+ -+ memcpy (line_out + offset_out, bufpos, mblength); -+ offset_out += mblength; -+ column += increment; -+ -+ if (is_blank_seen && !convfail && wc == L'\r') -+ is_cr_after_last_blank = 1; -+ -+ if (is_bs_following_last_blank && !convfail && wc == L'\b') -+ ++bs_following_last_blank_num; -+ else -+ is_bs_following_last_blank = 0; -+ -+ if (break_spaces && !convfail && iswblank (wc)) -+ { -+ last_blank_pos = offset_out; -+ last_blank_column = column; -+ is_blank_seen = 1; -+ last_blank_increment = increment; -+ is_bs_following_last_blank = 1; -+ bs_following_last_blank_num = 0; -+ is_cr_after_last_blank = 0; -+ } -+ } -+ -+ *saved_errno = errno; -+ if (!ferror (istream)) -+ *saved_errno = 0; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), offset_out, stdout); -+ -+} -+#endif -+ -+/* Fold file FILENAME, or standard input if FILENAME is "-", -+ to stdout, with maximum line length WIDTH. -+ Return true if successful. */ -+ -+static bool -+fold_file (char const *filename, size_t width) -+{ -+ FILE *istream; -+ int saved_errno; -+ -+ if (STREQ (filename, "-")) -+ { -+ istream = stdin; -+ have_read_stdin = true; -+ } -+ else -+ istream = fopen (filename, "r"); -+ -+ if (istream == nullptr) -+ { -+ error (0, errno, "%s", filename); -+ return false; -+ } -+ -+ /* Define how ISTREAM is being folded. */ -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ fold_multibyte_text (istream, width, &saved_errno); -+ else -+#endif -+ fold_text (istream, width, &saved_errno); -+ - if (STREQ (filename, "-")) - clearerr (istream); - else if (fclose (istream) != 0 && !saved_errno) -@@ -249,7 +497,8 @@ main (int argc, char **argv) - - atexit (close_stdout); - -- break_spaces = count_bytes = have_read_stdin = false; -+ operating_mode = column_mode; -+ break_spaces = have_read_stdin = false; - - while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) - { -@@ -258,7 +507,15 @@ main (int argc, char **argv) - switch (optc) - { - case 'b': /* Count bytes rather than columns. */ -- count_bytes = true; -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = byte_mode; -+ break; -+ -+ case 'c': -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = character_mode; - break; - - case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index 188dda1..7db5753 100644 +index 8f6d9a5..da16e59 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -478,8 +478,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -479,8 +479,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2267,7 +1417,7 @@ index 188dda1..7db5753 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index e7081a0..19e0268 100644 +index 87974d0..999bae7 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -3038,7 +2188,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 7af1a25..d3dc684 100644 +index 5a6a963..0b1b941 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3688,7 +2838,7 @@ index 7af1a25..d3dc684 100644 } @@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) - return reversed ? (diff < 0) - (diff > 0) : diff; + return reversed ? _GL_CMP (0, diff) : diff; } +#if HAVE_MBRTOWC @@ -4006,7 +3156,7 @@ index 7af1a25..d3dc684 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4291,6 +4934,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4289,6 +4932,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4014,7 +3164,7 @@ index 7af1a25..d3dc684 100644 break; case 'g': key->general_numeric = true; -@@ -4370,7 +5014,7 @@ main (int argc, char **argv) +@@ -4368,7 +5012,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4023,7 +3173,7 @@ index 7af1a25..d3dc684 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4393,6 +5037,29 @@ main (int argc, char **argv) +@@ -4391,6 +5035,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4053,7 +3203,7 @@ index 7af1a25..d3dc684 100644 have_read_stdin = false; inittables (); -@@ -4663,13 +5330,34 @@ main (int argc, char **argv) +@@ -4661,13 +5328,34 @@ main (int argc, char **argv) case 't': { @@ -4086,13 +3236,13 @@ index 7af1a25..d3dc684 100644 +#endif + if (newtab_length == 1 && optarg[1]) { - if (STREQ (optarg, "\\0")) + if (streq (optarg, "\\0")) - newtab = '\0'; + newtab[0] = '\0'; else { /* Provoke with 'sort -txx'. Complain about -@@ -4680,9 +5368,11 @@ main (int argc, char **argv) +@@ -4678,9 +5366,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4549,10 +3699,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index b68df41..0fe8193 100644 +index 4aa199a..c553c81 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -391,6 +391,8 @@ all_tests = \ +@@ -404,6 +404,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4561,7 +3711,7 @@ index b68df41..0fe8193 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -596,6 +598,7 @@ all_tests = \ +@@ -609,6 +611,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +3719,7 @@ index b68df41..0fe8193 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -752,6 +755,7 @@ all_tests = \ +@@ -765,6 +768,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4644,76 +3794,6 @@ index 4b07210..68b9ea1 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 877322e..ba889c8 100755 ---- a/tests/misc/fold.pl -+++ b/tests/misc/fold.pl -@@ -20,9 +20,17 @@ use strict; - - (my $program_name = $0) =~ s|.*/||; - -+my $prog = 'fold'; -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; --my $prog = 'fold'; -+ -+# uncommented to enable multibyte paths -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; - - my @Tests = - ( -@@ -44,6 +52,46 @@ my @Tests = - {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], - ); - -+# Add _POSIX2_VERSION=199209 to the environment of each test -+# that uses an old-style option like +1. -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether fold is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+@Tests = triple_test \@Tests; -+ -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 index 0000000..11836ba @@ -4952,7 +4032,7 @@ index a3204d3..40942a5 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index 2ee92c4..96c7965 100755 +index 5fa9d52..a66952a 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -4972,7 +4052,7 @@ index 2ee92c4..96c7965 100755 # Since each test is run with a file name and with redirected stdin, # the name in the diagnostic is either the file name or "-". # Normalize each diagnostic to use '-'. -@@ -423,6 +428,38 @@ foreach my $t (@Tests) +@@ -428,6 +433,38 @@ foreach my $t (@Tests) } } @@ -5011,7 +4091,7 @@ index 2ee92c4..96c7965 100755 @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -432,6 +469,7 @@ foreach my $t (@Tests) +@@ -437,6 +474,7 @@ foreach my $t (@Tests) # Remove the IN_PIPE version of the "output-is-input" test above. # The others aren't susceptible because they have three inputs each. @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; @@ -5198,5 +4278,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.50.0 +2.51.0 diff --git a/coreutils-python3.patch b/coreutils-python3.patch index e6ff471..447fdbc 100644 --- a/coreutils-python3.patch +++ b/coreutils-python3.patch @@ -1,4 +1,4 @@ -From f1a6e8d840a28eb2ab7a488e0d06450b7192c76d Mon Sep 17 00:00:00 2001 +From 8927d505ecb5334f09c48ef98ef1f464f581d0f7 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 2 Apr 2024 14:11:26 +0100 Subject: [PATCH] coreutils-python3.patch @@ -10,10 +10,10 @@ Subject: [PATCH] coreutils-python3.patch 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/init.cfg b/init.cfg -index 612d287..9a6fa2d 100644 +index ac05f7b..26d9516 100644 --- a/init.cfg +++ b/init.cfg -@@ -597,10 +597,10 @@ seek_data_capable_() +@@ -601,10 +601,10 @@ seek_data_capable_() # Skip the current test if "." lacks d_type support. require_dirent_d_type_() { @@ -37,7 +37,7 @@ index 1a2f76f..42d3924 100644 # Intended to exit 0 only on Linux/GNU systems. import os diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh -index 1d0a359..bd03542 100755 +index adf482b..cf9214a 100755 --- a/tests/du/move-dir-while-traversing.sh +++ b/tests/du/move-dir-while-traversing.sh @@ -21,8 +21,8 @@ print_ver_ du @@ -61,5 +61,5 @@ index 1d0a359..bd03542 100755 import os,sys -- -2.48.1 +2.51.0 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch deleted file mode 100644 index 91bc5b5..0000000 --- a/coreutils-selinux.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fc96cab095d704e8bf9934812dd8d6f87fbf4be4 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Wed, 30 Aug 2023 17:19:58 +0200 -Subject: [PATCH] coreutils-selinux.patch - ---- - src/cp.c | 19 ++++++++++++++++++- - src/install.c | 12 +++++++++++- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/src/cp.c b/src/cp.c -index a0ec067..1169c6a 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -996,7 +996,7 @@ main (int argc, char **argv) - selinux_enabled = (0 < is_selinux_enabled ()); - cp_option_init (&x); - -- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", -+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", - long_opts, nullptr)) - != -1) - { -@@ -1048,6 +1048,23 @@ main (int argc, char **argv) - copy_contents = true; - break; - -+ case 'c': -+ fprintf (stderr, "%s: warning: option '-c' is deprecated," -+ " please use '--preserve=context' instead\n", argv[0]); -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } -+ else if (selinux_enabled) -+ { -+ x.preserve_security_context = true; -+ x.require_preserve_context = true; -+ } -+ break; -+ - case 'd': - x.preserve_links = true; - x.dereference = DEREF_NEVER; -diff --git a/src/install.c b/src/install.c -index b3b26ab..2d2f072 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -807,7 +807,7 @@ main (int argc, char **argv) - dir_arg = false; - umask (0); - -- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, -+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, - nullptr)) - != -1) - { -@@ -872,6 +872,9 @@ main (int argc, char **argv) - no_target_directory = true; - break; - -+ case 'P': -+ fprintf (stderr, "%s: warning: option '-P' is deprecated," -+ " please use '--preserve-context' instead\n", argv[0]); - case PRESERVE_CONTEXT_OPTION: - if (! selinux_enabled) - { -@@ -879,6 +882,13 @@ main (int argc, char **argv) - "this kernel is not SELinux-enabled")); - break; - } -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } - x.preserve_security_context = true; - use_default_selinux_context = false; - break; --- -2.48.1 - diff --git a/coreutils.spec b/coreutils.spec index 17e98b3..a82d750 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.7 -Release: 5%{?dist} +Version: 9.8 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,29 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) -# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=8a356b77717a2e4f735ec06e326880ca1f61aadb -# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 -Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch - -# sort: fix buffer under-read (CVE-2025-5278) -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 -Patch106: coreutils-CVE-2025-5278.patch - -# stty: add support for arbitrary baud rates (rhbz#2375439) -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=357fda90d15fd3f7dba61e1ab322b183a48d0081 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=efaec8078142996d958b6720b85a13b12497c3d0 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=b7db7757831e93ca44ae59e1921bc4ebbc87974f -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8b05eca972f70858749a946ac24f08d0718c1be6 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d -Patch107: coreutils-9.7-stty-arbitrary-baud-rates.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# downstream SELinux options deprecated since 2009 -Patch950: coreutils-selinux.patch - Conflicts: filesystem < 3 # To avoid clobbering installs @@ -295,6 +275,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Sep 24 2025 Lukáš Zaoral - 9.8-1 +- rebase to latest upstream release (rhbz#2397467) +- remove downstream patch for selinux options deprecated since 2009 + * Wed Jul 23 2025 Fedora Release Engineering - 9.7-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 0e9a66d..d1677b5 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.7.tar.xz) = fe81e6ba4fb492095153d5baac1eca8f07ece0957849de746a2a858cf007893cc2ded595a31a5e5d43d13216cc44b9d74a3245d9f23221ecc8cd00f428f27414 -SHA512 (coreutils-9.7.tar.xz.sig) = 48d86a19cee3c153f01f7478847f4621685c02e59942540bb20b30e314df05230817b87d0e73acd953e79fab35718e5bea57f25fe511a2c275a85ced4b317bae +SHA512 (coreutils-9.8.tar.xz.sig) = 0fa9ab4404cd2157584797de22a1f28ec4e0353dae05a7476198dc77e23bf59aaeb1aabf9f7dc22f5d80df311e6ef1490add75ae1663b4091e58cc29db4dcfa3 +SHA512 (coreutils-9.8.tar.xz) = 7b6c420907f0e33e4aff3dd92270f8cbd3e94b2ae8cf7caa2d5d1cfd5e9958319904a6547127abd55ee63aae0316f5b1228586b2da34ea402da032e925a25e53 From 0095d94d91e464de7116672697c0766e15f611de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 25 Sep 2025 10:23:54 +0200 Subject: [PATCH 26/29] tail: fix tailing larger number of lines in regular files Resolves: rhbz#2398008 --- coreutils-i18n.patch | 12 +-- ...v9.8-tail-n-broken-for-regular-files.patch | 83 +++++++++++++++++++ coreutils.spec | 9 +- 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 coreutils-v9.8-tail-n-broken-for-regular-files.patch diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 92167bd..1fd522a 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c5b102c8d9ddf1cc1109858615de3a9d6d57b7e6 Mon Sep 17 00:00:00 2001 +From d4945b936d0bbea48db45de5e6284cc333e68034 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -39,7 +39,7 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index b8feef9..ab1eb93 100644 +index b8feef9..24a264d 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -169,6 +169,8 @@ gnulib_modules=" @@ -3699,10 +3699,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 4aa199a..c553c81 100644 +index c1e251b..a7654e8 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -404,6 +404,8 @@ all_tests = \ +@@ -405,6 +405,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -3711,7 +3711,7 @@ index 4aa199a..c553c81 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -609,6 +611,7 @@ all_tests = \ +@@ -610,6 +612,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -3719,7 +3719,7 @@ index 4aa199a..c553c81 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -765,6 +768,7 @@ all_tests = \ +@@ -766,6 +769,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ diff --git a/coreutils-v9.8-tail-n-broken-for-regular-files.patch b/coreutils-v9.8-tail-n-broken-for-regular-files.patch new file mode 100644 index 0000000..2ce3f2e --- /dev/null +++ b/coreutils-v9.8-tail-n-broken-for-regular-files.patch @@ -0,0 +1,83 @@ +From f9249475026ef5eb18156e8ca6fc2cf3ab61d493 Mon Sep 17 00:00:00 2001 +From: Hannes Braun +Date: Wed, 24 Sep 2025 21:20:49 +0200 +Subject: [PATCH] tail: fix tailing larger number of lines in regular files + +* src/tail.c (file_lines): Seek to the previous block instead of the +beginning (or a little before) of the block that was just scanned. +Otherwise, the same block is read and scanned (at least partially) +again. This bug was introduced by commit v9.7-219-g976f8abc1. +* tests/tail/basic-seek.sh: Add a new test. +* tests/local.mk: Reference the new test. +* NEWS: mention the bug fix. + +(cherry-picked from commit 914972e80dbf82aac9ffe3ff1f67f1028e1a788b) +--- + src/tail.c | 2 +- + tests/local.mk | 1 + + tests/tail/basic-seek.sh | 28 ++++++++++++++++++++++++++++ + 3 files changed, 30 insertions(+), 1 deletion(-) + create mode 100755 tests/tail/basic-seek.sh + +diff --git a/src/tail.c b/src/tail.c +index b8bef1d..c7779c7 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, + goto free_buffer; + } + +- pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname); ++ pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname); + bytes_read = read (fd, buffer, bufsize); + if (bytes_read < 0) + { +diff --git a/tests/local.mk b/tests/local.mk +index 4aa199a..c1e251b 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -179,6 +179,7 @@ all_tests = \ + tests/tty/tty-eof.pl \ + tests/misc/read-errors.sh \ + tests/misc/write-errors.sh \ ++ tests/tail/basic-seek.sh \ + tests/tail/inotify-hash-abuse.sh \ + tests/tail/inotify-hash-abuse2.sh \ + tests/tail/F-vs-missing.sh \ +diff --git a/tests/tail/basic-seek.sh b/tests/tail/basic-seek.sh +new file mode 100755 +index 0000000..307ed66 +--- /dev/null ++++ b/tests/tail/basic-seek.sh +@@ -0,0 +1,28 @@ ++#!/bin/sh ++# Verify that tail works when seeking within a file ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ tail ++ ++yes '=================================' | ++ head -n1K > file.in || framework_failure_ ++ ++# This returned 139 in coreutils v9.8 ++test $(tail -n200 file.in | wc -l) = 200 || fail=1 ++ ++Exit $fail +-- +2.51.0 + diff --git a/coreutils.spec b/coreutils.spec index a82d750..f8de1d5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.8 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,10 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# tail: fix tailing larger number of lines in regular files (rhbz#2398008) +# https://github.com/coreutils/coreutils/commit/914972e80dbf82aac9ffe3ff1f67f1028e1a788b +Patch105: coreutils-v9.8-tail-n-broken-for-regular-files.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -275,6 +279,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Sep 25 2025 Lukáš Zaoral - 9.8-2 +- tail: fix tailing larger number of lines in regular files (rhbz#2398008) + * Wed Sep 24 2025 Lukáš Zaoral - 9.8-1 - rebase to latest upstream release (rhbz#2397467) - remove downstream patch for selinux options deprecated since 2009 From 0615d97b816fef35a8d2626b20545d9bd48f427b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 29 Sep 2025 12:14:21 +0200 Subject: [PATCH 27/29] require gnulib-l10n for translations of gnulib messages Resolves: rhbz#2393892 --- coreutils.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f8de1d5..7e7ce12 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.8 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -121,6 +121,9 @@ packaged as a single multicall binary. # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 +# Gnulib translations are maintained seprately since coreutils 9.6 (#2393892) +Requires: gnulib-l10n + # info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) Suggests: glibc-doc @@ -279,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Sep 29 2025 Lukáš Zaoral - 9.8-3 +- require gnulib-l10n for translations of gnulib messages (rhbz#2393892) + * Thu Sep 25 2025 Lukáš Zaoral - 9.8-2 - tail: fix tailing larger number of lines in regular files (rhbz#2398008) From eb04a0fe336b24ee60d1c9478d5856ac21d792fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 26 Nov 2025 14:54:16 +0100 Subject: [PATCH 28/29] rebase to latest upstream release Resolves: rhbz#2413803 --- coreutils-9.9-gnulib-c23.patch | 169 ++++++++++++++++++ coreutils-df-direct.patch | 10 +- coreutils-i18n.patch | 149 +++++++-------- ...v9.8-tail-n-broken-for-regular-files.patch | 83 --------- coreutils.spec | 15 +- sources | 4 +- 6 files changed, 260 insertions(+), 170 deletions(-) create mode 100644 coreutils-9.9-gnulib-c23.patch delete mode 100644 coreutils-v9.8-tail-n-broken-for-regular-files.patch diff --git a/coreutils-9.9-gnulib-c23.patch b/coreutils-9.9-gnulib-c23.patch new file mode 100644 index 0000000..82e3899 --- /dev/null +++ b/coreutils-9.9-gnulib-c23.patch @@ -0,0 +1,169 @@ +From 891761bca1aa78336e5b18c121075b6e4696c5d4 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sun, 23 Nov 2025 00:50:40 -0800 +Subject: [PATCH] Port to C23 qualifier-generic fns like strchr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This ports Gnulib to strict C23 platforms that reject code +like ‘char *q = strchr (P, 'x');’ when P is a pointer to const, +because in C23 strchr is a qualifier-generic function so +strchr (P, 'x') returns char const *. +This patch does not attempt to do the following two things, +which might be useful in the future: +1. When compiling on non-C23 platforms, check user code for +portability to platforms that define qualifier-generic functions. +2. Port Gnulib to platforms that have qualifier-generic functions +not listed in the C23 standard, e.g., strchrnul. I don’t know +of any such platforms. +* lib/mbschr.c (mbschr): +* lib/memchr2.c (memchr2): +Port to C23, where functions like strchr are qualifier-generic. +* lib/c++defs.h (_GL_FUNCDECL_SYS_NAME): New macro. +* lib/c++defs.h (_GL_FUNCDECL_SYS): +* lib/stdlib.in.h (bsearch): +Use it, to prevent C23 names like strchr from acting like macros. +* lib/string.in.h (memchr, strchr, strpbrk, strrchr): +Do not #undef when GNULIB_POSIXCHECK is defined, as this could +cause conforming C23 code to fail to conform. It’s not clear why +_GL_WARN_ON_USE_CXX; perhaps it was needed but isn’t any more? +But for now, limit the removal of #undef to these four functions +where #undeffing is clearly undesirable in C23. +* lib/wchar.in.h (wmemchr): Parenthesize function name in decl, +to prevent it from acting like a macro. + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: df17f4f37ed3ca373d23ad42eae51122bdb96626 +--- + lib/c++defs.h | 12 +++++++++++- + lib/mbschr.c | 2 +- + lib/memchr2.c | 2 +- + lib/stdlib.in.h | 6 +++--- + lib/string.in.h | 4 ---- + lib/wchar.in.h | 2 +- + 6 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/lib/c++defs.h b/lib/c++defs.h +index b77979a..7384457 100644 +--- a/lib/c++defs.h ++++ b/lib/c++defs.h +@@ -127,6 +127,16 @@ + #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ + _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters + ++/* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to ++ parenthsized func otherwise. Parenthesization is needed in C23 if ++ the function is like strchr and so is a qualifier-generic macro ++ that expands to something more complicated. */ ++#ifdef __cplusplus ++# define _GL_FUNCDECL_SYS_NAME(func) func ++#else ++# define _GL_FUNCDECL_SYS_NAME(func) (func) ++#endif ++ + /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); + declares the system function, named func, with the given prototype, + consisting of return type, parameters, and attributes. +@@ -139,7 +149,7 @@ + _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); + */ + #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ +- _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters ++ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters + + /* _GL_CXXALIAS_RPL (func, rettype, parameters); + declares a C++ alias called GNULIB_NAMESPACE::func +diff --git a/lib/mbschr.c b/lib/mbschr.c +index c9e14b5..6582134 100644 +--- a/lib/mbschr.c ++++ b/lib/mbschr.c +@@ -65,5 +65,5 @@ mbschr (const char *string, int c) + return NULL; + } + else +- return strchr (string, c); ++ return (char *) strchr (string, c); + } +diff --git a/lib/memchr2.c b/lib/memchr2.c +index 7493823..d7724ae 100644 +--- a/lib/memchr2.c ++++ b/lib/memchr2.c +@@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n) + c2 = (unsigned char) c2_in; + + if (c1 == c2) +- return memchr (s, c1, n); ++ return (void *) memchr (s, c1, n); + + /* Handle the first few bytes by reading one byte at a time. + Do this until VOID_PTR is aligned on a longword boundary. */ +diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h +index bef0aaa..fd0e1e0 100644 +--- a/lib/stdlib.in.h ++++ b/lib/stdlib.in.h +@@ -224,9 +224,9 @@ _GL_INLINE_HEADER_BEGIN + + /* Declarations for ISO C N3322. */ + #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +-_GL_EXTERN_C void *bsearch (const void *__key, +- const void *__base, size_t __nmemb, size_t __size, +- int (*__compare) (const void *, const void *)) ++_GL_EXTERN_C void *_GL_FUNCDECL_SYS_NAME (bsearch) ++ (const void *__key, const void *__base, size_t __nmemb, size_t __size, ++ int (*__compare) (const void *, const void *)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); + _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) +diff --git a/lib/string.in.h b/lib/string.in.h +index fdcdd21..8b56acf 100644 +--- a/lib/string.in.h ++++ b/lib/string.in.h +@@ -409,7 +409,6 @@ _GL_CXXALIASWARN1 (memchr, void const *, + _GL_CXXALIASWARN (memchr); + # endif + #elif defined GNULIB_POSIXCHECK +-# undef memchr + /* Assume memchr is always declared. */ + _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " + "use gnulib module memchr for portability" ); +@@ -674,7 +673,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " + #if defined GNULIB_POSIXCHECK + /* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strchr + /* Assume strchr is always declared. */ + _GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), +@@ -981,7 +979,6 @@ _GL_CXXALIASWARN (strpbrk); + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +-# undef strpbrk + _GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk cannot work correctly on character strings " +@@ -1011,7 +1008,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " + #if defined GNULIB_POSIXCHECK + /* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strrchr + /* Assume strrchr is always declared. */ + _GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), +diff --git a/lib/wchar.in.h b/lib/wchar.in.h +index ab602a2..6be4515 100644 +--- a/lib/wchar.in.h ++++ b/lib/wchar.in.h +@@ -301,7 +301,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); + # ifndef __cplusplus +-_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n) ++_GL_EXTERN_C wchar_t *(wmemchr) (const wchar_t *__s, wchar_t __wc, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); + # endif + _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) +-- +2.52.0 + diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 2deacf7..341ee2c 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From ae768935e696a23e336601c5a239e147628ecf05 Mon Sep 17 00:00:00 2001 +From 91be1a584108a6a3d96f64382bbf206c4213b3db Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 937d8af..11fa1d6 100644 +index b420606..0ccb368 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12588,6 +12588,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12597,6 +12597,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,7 +29,7 @@ index 937d8af..11fa1d6 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 857f76c..07b21ea 100644 +index 75e638c..ef9f0a7 100644 --- a/src/df.c +++ b/src/df.c @@ -121,6 +121,9 @@ static bool print_type; @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.51.0 +2.52.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1fd522a..83579e9 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From d4945b936d0bbea48db45de5e6284cc333e68034 Mon Sep 17 00:00:00 2001 +From a81b096084524e9aeef5e8b81fc829eb9efec581 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -16,7 +16,7 @@ Subject: [PATCH] coreutils-i18n.patch src/expand.c | 90 +++- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- - src/sort.c | 790 +++++++++++++++++++++++++++++++++--- + src/sort.c | 791 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ @@ -29,7 +29,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 25 files changed, 2878 insertions(+), 167 deletions(-) + 25 files changed, 2879 insertions(+), 167 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -39,20 +39,20 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index b8feef9..24a264d 100644 +index ec68ac8..ec2fbbe 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -169,6 +169,8 @@ gnulib_modules=" - maintainer-makefile +@@ -171,6 +171,8 @@ gnulib_modules=" malloc-gnu manywarnings + mbbuf + mbchar + mbfile mbrlen mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 274eff4..5a1cfa5 100644 +index 5e99ef3..ac07577 100644 --- a/configure.ac +++ b/configure.ac @@ -465,6 +465,12 @@ fi @@ -1092,7 +1092,7 @@ index f0effb9..36479d6 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index ca2ad4d..2ad24bf 100644 +index 14dd804..0d8eaaa 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1103,7 +1103,7 @@ index ca2ad4d..2ad24bf 100644 #include "system.h" #include "c-ctype.h" #include "fadvise.h" -@@ -123,6 +124,119 @@ set_increment_size (colno tabval) +@@ -132,6 +133,119 @@ set_increment_size (colno tabval) return ok; } @@ -1402,10 +1402,10 @@ index 5ec7ce9..65ac315 100644 } diff --git a/src/local.mk b/src/local.mk -index 8f6d9a5..da16e59 100644 +index a8ad6b4..b0e61ec 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -479,8 +479,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -490,8 +490,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -1415,9 +1415,9 @@ index 8f6d9a5..da16e59 100644 +src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c src_wc_SOURCES = src/wc.c - if USE_AVX2_WC_LINECOUNT + if USE_AVX512_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 87974d0..999bae7 100644 +index 10b8c52..079c86c 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -1764,7 +1764,7 @@ index 87974d0..999bae7 100644 h_next = h + chars_per_column; } } -@@ -1748,9 +1872,9 @@ static void +@@ -1751,9 +1875,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1776,7 +1776,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2024,13 +2148,13 @@ store_char (char c) +@@ -2030,13 +2154,13 @@ store_char (char c) /* May be too generous. */ buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff); } @@ -1792,7 +1792,7 @@ index 87974d0..999bae7 100644 char *s; int num_width; -@@ -2047,22 +2171,24 @@ add_line_number (COLUMN *p) +@@ -2053,22 +2177,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -1821,7 +1821,7 @@ index 87974d0..999bae7 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2221,7 +2347,7 @@ print_white_space (void) +@@ -2227,7 +2353,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1830,7 +1830,7 @@ index 87974d0..999bae7 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2241,6 +2367,7 @@ print_sep_string (void) +@@ -2247,6 +2373,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1838,7 +1838,7 @@ index 87974d0..999bae7 100644 if (separators_not_printed <= 0) { -@@ -2252,6 +2379,7 @@ print_sep_string (void) +@@ -2258,6 +2385,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1846,7 +1846,7 @@ index 87974d0..999bae7 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2265,12 +2393,15 @@ print_sep_string (void) +@@ -2271,12 +2399,15 @@ print_sep_string (void) } else { @@ -1863,7 +1863,7 @@ index 87974d0..999bae7 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2298,7 +2429,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2307,7 +2438,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1872,7 +1872,7 @@ index 87974d0..999bae7 100644 { if (tabify_output) { -@@ -2322,6 +2453,74 @@ print_char (char c) +@@ -2331,6 +2462,74 @@ print_char (char c) putchar (c); } @@ -1947,7 +1947,7 @@ index 87974d0..999bae7 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2498,9 +2697,9 @@ read_line (COLUMN *p) +@@ -2507,9 +2706,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1959,7 +1959,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2569,7 +2768,7 @@ print_stored (COLUMN *p) +@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -1968,7 +1968,7 @@ index 87974d0..999bae7 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2581,7 +2780,7 @@ print_stored (COLUMN *p) +@@ -2590,7 +2789,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1977,7 +1977,7 @@ index 87974d0..999bae7 100644 pad_vertically = true; -@@ -2601,9 +2800,9 @@ print_stored (COLUMN *p) +@@ -2610,9 +2809,9 @@ print_stored (COLUMN *p) } } @@ -1989,7 +1989,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2616,8 +2815,8 @@ print_stored (COLUMN *p) +@@ -2625,8 +2824,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2000,7 +2000,7 @@ index 87974d0..999bae7 100644 } return true; -@@ -2636,7 +2835,7 @@ print_stored (COLUMN *p) +@@ -2645,7 +2844,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2009,7 +2009,7 @@ index 87974d0..999bae7 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2646,10 +2845,10 @@ char_to_clump (char c) +@@ -2655,10 +2854,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2022,7 +2022,7 @@ index 87974d0..999bae7 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2730,6 +2929,164 @@ char_to_clump (char c) +@@ -2739,6 +2938,164 @@ char_to_clump (char c) return chars; } @@ -2188,13 +2188,14 @@ index 87974d0..999bae7 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 5a6a963..0b1b941 100644 +index 05d00cc..eb51f20 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -29,6 +29,14 @@ - #include +@@ -30,6 +30,15 @@ #include #include + #include ++ +#if HAVE_WCHAR_H +# include +#endif @@ -2206,7 +2207,7 @@ index 5a6a963..0b1b941 100644 #include "system.h" #include "argmatch.h" #include "assure.h" -@@ -158,14 +166,39 @@ static int thousands_sep; +@@ -160,14 +169,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -2247,7 +2248,7 @@ index 5a6a963..0b1b941 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -342,13 +375,11 @@ static bool stable; +@@ -344,13 +378,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -2264,9 +2265,9 @@ index 5a6a963..0b1b941 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -806,6 +837,46 @@ reap_all (void) - reap (-1); - } +@@ -386,6 +418,46 @@ struct tempnode + static struct tempnode *volatile temphead; + static struct tempnode *volatile *temptail = &temphead; +/* Function pointers. */ +static void @@ -2311,7 +2312,7 @@ index 5a6a963..0b1b941 100644 /* Clean up any remaining temporary files. */ static void -@@ -1273,7 +1344,7 @@ zaptemp (char const *name) +@@ -1343,7 +1415,7 @@ zaptemp (char const *name) free (node); } @@ -2320,7 +2321,7 @@ index 5a6a963..0b1b941 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1288,7 +1359,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1358,7 +1430,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -2329,7 +2330,7 @@ index 5a6a963..0b1b941 100644 { size_t i; -@@ -1300,7 +1371,7 @@ inittables (void) +@@ -1370,7 +1442,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2338,7 +2339,7 @@ index 5a6a963..0b1b941 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1450,6 +1522,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -2423,7 +2424,7 @@ index 5a6a963..0b1b941 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1676,7 +1826,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -2432,7 +2433,7 @@ index 5a6a963..0b1b941 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1685,10 +1835,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -2445,7 +2446,7 @@ index 5a6a963..0b1b941 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1653,12 +1802,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1718,12 +1868,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2518,7 +2519,7 @@ index 5a6a963..0b1b941 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1673,10 +1881,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1738,10 +1947,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2531,7 +2532,7 @@ index 5a6a963..0b1b941 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1722,10 +1930,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1787,10 +1996,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2544,7 +2545,7 @@ index 5a6a963..0b1b941 100644 if (newlim) lim = newlim; } -@@ -1760,6 +1968,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1825,6 +2034,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2675,7 +2676,7 @@ index 5a6a963..0b1b941 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1846,8 +2178,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1911,8 +2244,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2700,7 +2701,7 @@ index 5a6a963..0b1b941 100644 line->keybeg = line_start; } } -@@ -1985,12 +2331,10 @@ find_unit_order (char const *number) +@@ -2050,12 +2397,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -2716,7 +2717,7 @@ index 5a6a963..0b1b941 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -2002,7 +2346,7 @@ human_numcompare (char const *a, char const *b) +@@ -2067,7 +2412,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -2725,7 +2726,7 @@ index 5a6a963..0b1b941 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2012,6 +2356,25 @@ numcompare (char const *a, char const *b) +@@ -2077,6 +2422,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2751,7 +2752,7 @@ index 5a6a963..0b1b941 100644 static int nan_compare (long double a, long double b) { -@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2118,7 +2482,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2760,7 +2761,7 @@ index 5a6a963..0b1b941 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2392,15 +2755,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2457,15 +2821,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2778,7 +2779,7 @@ index 5a6a963..0b1b941 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2546,7 +2908,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2611,7 +2974,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2787,7 +2788,7 @@ index 5a6a963..0b1b941 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2594,9 +2956,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2659,9 +3022,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -2800,7 +2801,7 @@ index 5a6a963..0b1b941 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2607,9 +2969,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2672,9 +3035,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -2813,7 +2814,7 @@ index 5a6a963..0b1b941 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2617,19 +2979,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2682,19 +3045,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -2837,7 +2838,7 @@ index 5a6a963..0b1b941 100644 } } -@@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) +@@ -2746,11 +3109,87 @@ diff_reversed (int diff, bool reversed) return reversed ? _GL_CMP (0, diff) : diff; } @@ -2926,7 +2927,7 @@ index 5a6a963..0b1b941 100644 { struct keyfield *key = keylist; -@@ -2766,7 +3204,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2831,7 +3270,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2935,7 +2936,7 @@ index 5a6a963..0b1b941 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2876,6 +3314,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2941,6 +3380,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3147,7 +3148,7 @@ index 5a6a963..0b1b941 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2903,7 +3546,7 @@ compare (struct line const *a, struct line const *b) +@@ -2968,7 +3612,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3156,7 +3157,7 @@ index 5a6a963..0b1b941 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4289,6 +4932,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4340,6 +4984,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3164,7 +3165,7 @@ index 5a6a963..0b1b941 100644 break; case 'g': key->general_numeric = true; -@@ -4368,7 +5012,7 @@ main (int argc, char **argv) +@@ -4419,7 +5064,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3173,7 +3174,7 @@ index 5a6a963..0b1b941 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4391,6 +5035,29 @@ main (int argc, char **argv) +@@ -4442,6 +5087,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -3203,7 +3204,7 @@ index 5a6a963..0b1b941 100644 have_read_stdin = false; inittables (); -@@ -4661,13 +5328,34 @@ main (int argc, char **argv) +@@ -4717,13 +5385,34 @@ main (int argc, char **argv) case 't': { @@ -3242,7 +3243,7 @@ index 5a6a963..0b1b941 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4678,9 +5366,11 @@ main (int argc, char **argv) +@@ -4734,9 +5423,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3699,10 +3700,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index c1e251b..a7654e8 100644 +index 53fc53e..0148422 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -405,6 +405,8 @@ all_tests = \ +@@ -412,6 +412,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -3711,7 +3712,7 @@ index c1e251b..a7654e8 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -610,6 +612,7 @@ all_tests = \ +@@ -618,6 +620,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -3719,7 +3720,7 @@ index c1e251b..a7654e8 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -766,6 +769,7 @@ all_tests = \ +@@ -774,6 +777,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -3846,7 +3847,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 27d9c17..4976335 100755 +index bb7469c..c1dec95 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -3864,7 +3865,7 @@ index 27d9c17..4976335 100755 my @Tests = ( ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -128,6 +136,37 @@ my @Tests = +@@ -132,6 +140,37 @@ my @Tests = ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], ); @@ -4278,5 +4279,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.51.0 +2.52.0 diff --git a/coreutils-v9.8-tail-n-broken-for-regular-files.patch b/coreutils-v9.8-tail-n-broken-for-regular-files.patch deleted file mode 100644 index 2ce3f2e..0000000 --- a/coreutils-v9.8-tail-n-broken-for-regular-files.patch +++ /dev/null @@ -1,83 +0,0 @@ -From f9249475026ef5eb18156e8ca6fc2cf3ab61d493 Mon Sep 17 00:00:00 2001 -From: Hannes Braun -Date: Wed, 24 Sep 2025 21:20:49 +0200 -Subject: [PATCH] tail: fix tailing larger number of lines in regular files - -* src/tail.c (file_lines): Seek to the previous block instead of the -beginning (or a little before) of the block that was just scanned. -Otherwise, the same block is read and scanned (at least partially) -again. This bug was introduced by commit v9.7-219-g976f8abc1. -* tests/tail/basic-seek.sh: Add a new test. -* tests/local.mk: Reference the new test. -* NEWS: mention the bug fix. - -(cherry-picked from commit 914972e80dbf82aac9ffe3ff1f67f1028e1a788b) ---- - src/tail.c | 2 +- - tests/local.mk | 1 + - tests/tail/basic-seek.sh | 28 ++++++++++++++++++++++++++++ - 3 files changed, 30 insertions(+), 1 deletion(-) - create mode 100755 tests/tail/basic-seek.sh - -diff --git a/src/tail.c b/src/tail.c -index b8bef1d..c7779c7 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, - goto free_buffer; - } - -- pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname); -+ pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname); - bytes_read = read (fd, buffer, bufsize); - if (bytes_read < 0) - { -diff --git a/tests/local.mk b/tests/local.mk -index 4aa199a..c1e251b 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -179,6 +179,7 @@ all_tests = \ - tests/tty/tty-eof.pl \ - tests/misc/read-errors.sh \ - tests/misc/write-errors.sh \ -+ tests/tail/basic-seek.sh \ - tests/tail/inotify-hash-abuse.sh \ - tests/tail/inotify-hash-abuse2.sh \ - tests/tail/F-vs-missing.sh \ -diff --git a/tests/tail/basic-seek.sh b/tests/tail/basic-seek.sh -new file mode 100755 -index 0000000..307ed66 ---- /dev/null -+++ b/tests/tail/basic-seek.sh -@@ -0,0 +1,28 @@ -+#!/bin/sh -+# Verify that tail works when seeking within a file -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program 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 General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ tail -+ -+yes '=================================' | -+ head -n1K > file.in || framework_failure_ -+ -+# This returned 139 in coreutils v9.8 -+test $(tail -n200 file.in | wc -l) = 200 || fail=1 -+ -+Exit $fail --- -2.51.0 - diff --git a/coreutils.spec b/coreutils.spec index 7e7ce12..13a7c9d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.8 -Release: 3%{?dist} +Version: 9.9 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,9 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# tail: fix tailing larger number of lines in regular files (rhbz#2398008) -# https://github.com/coreutils/coreutils/commit/914972e80dbf82aac9ffe3ff1f67f1028e1a788b -Patch105: coreutils-v9.8-tail-n-broken-for-regular-files.patch +# gnulib C23 support +# https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626 +Patch105: coreutils-9.9-gnulib-c23.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -160,7 +160,7 @@ find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' # FIXME: Force a newer gettext version to workaround `autoreconf -i` errors # with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel. -sed -i 's/0.19.2/0.22.5/' bootstrap.conf configure.ac +sed -i "s/0.19.2/$(rpm -q --queryformat '%%{VERSION}\n' gettext-devel)/" bootstrap.conf configure.ac autoreconf -fiv @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Nov 26 2025 Lukáš Zaoral - 9.9-1 +- rebase to latest upstream release (rhbz#2413803) + * Mon Sep 29 2025 Lukáš Zaoral - 9.8-3 - require gnulib-l10n for translations of gnulib messages (rhbz#2393892) diff --git a/sources b/sources index d1677b5..0952ab1 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.8.tar.xz.sig) = 0fa9ab4404cd2157584797de22a1f28ec4e0353dae05a7476198dc77e23bf59aaeb1aabf9f7dc22f5d80df311e6ef1490add75ae1663b4091e58cc29db4dcfa3 -SHA512 (coreutils-9.8.tar.xz) = 7b6c420907f0e33e4aff3dd92270f8cbd3e94b2ae8cf7caa2d5d1cfd5e9958319904a6547127abd55ee63aae0316f5b1228586b2da34ea402da032e925a25e53 +SHA512 (coreutils-9.9.tar.xz.sig) = 0a3dfdfa6b4234e2e1d42142269f959bdf3cf8f6605a50270a27eff84dd22588f182121f7dd3eeb04be45f5109d02690215065b3d3b43882874d0e165a1435d0 +SHA512 (coreutils-9.9.tar.xz) = e7b0e59f7732d2c098ea4934014f470248bd5c4764210e9200a698010a8e3b95bbb26e543f0cd73ed5a4b8e1f8cda932c73f39954d68175e4deaa47526610c65 From f674e5fc9ccd33d82c2c5477a124604a3b4d0fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 13 Jan 2026 16:19:08 +0100 Subject: [PATCH 29/29] fix cut test failure on aarch64 rawhide Resolves: rhbz#2424302 --- coreutils-9.9-fix-cut-test-aarch64.patch | 28 ++++++++++++++++++++++++ coreutils.spec | 9 +++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.9-fix-cut-test-aarch64.patch diff --git a/coreutils-9.9-fix-cut-test-aarch64.patch b/coreutils-9.9-fix-cut-test-aarch64.patch new file mode 100644 index 0000000..600f87b --- /dev/null +++ b/coreutils-9.9-fix-cut-test-aarch64.patch @@ -0,0 +1,28 @@ +From 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 22 Dec 2025 17:12:48 +0000 +Subject: [PATCH] tests: avoid false failure due to ulimit on aarch64 + +* tests/cut/cut-huge-range.sh: Add an extra 1MiB headroom, +which was seen with aarch64. +Reported at https://bugzilla.redhat.com/2424302 + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +--- + tests/cut/cut-huge-range.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/cut/cut-huge-range.sh b/tests/cut/cut-huge-range.sh +index 4bd1b129d8..98d7e8f0b9 100755 +--- a/tests/cut/cut-huge-range.sh ++++ b/tests/cut/cut-huge-range.sh +@@ -22,6 +22,7 @@ getlimits_ + + vm=$(get_min_ulimit_v_ returns_ 0 cut -b1 /dev/null) \ + || skip_ 'shell lacks ulimit, or ASAN enabled' ++vm=$(($vm+1000)) # https://bugzilla.redhat.com/2424302 + + # Ensure we can cut up to our sentinel value. + # Don't use expr to subtract one, + diff --git a/coreutils.spec b/coreutils.spec index 13a7c9d..6712263 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.9 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,10 @@ Patch104: coreutils-df-direct.patch # https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626 Patch105: coreutils-9.9-gnulib-c23.patch +# fix cut test failure on aarch64 rawhide (rhbz#2424302) +# https://github.com/coreutils/coreutils/commit/95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +Patch106: coreutils-9.9-fix-cut-test-aarch64.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -282,6 +286,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jan 13 2026 Lukáš Zaoral - 9.9-2 +- fix cut test failure on aarch64 rawhide (rhbz#2424302) + * Wed Nov 26 2025 Lukáš Zaoral - 9.9-1 - rebase to latest upstream release (rhbz#2413803)