From 3b5057119c86502702dc53e5d0579be3eed7b990 Mon Sep 17 00:00:00 2001 From: zyppe <210hcl@gmail.com> Date: Tue, 6 Feb 2024 16:48:14 +0800 Subject: [PATCH] Initialize for coreutils --- .coreutils.metadata | 1 + .gitignore | 1 + baselibs.conf | 3 + coreutils-8.32.tar.xz.sig | 16 + coreutils-build-timeout-as-pie.patch | 39 + coreutils-df-fuse-portal-dummy.patch | 29 + coreutils-disable_tests.patch | 23 + coreutils-getaddrinfo.patch | 21 + coreutils-gnulib-disable-test-float.patch | 25 + coreutils-i18n.patch | 5332 +++++++++++++++++ coreutils-invalid-ids.patch | 30 + ...estore-8.31-behavior-on-removed-dirs.patch | 156 + coreutils-misc.patch | 61 + coreutils-remove_hostname_documentation.patch | 92 + coreutils-remove_kill_documentation.patch | 126 + coreutils-skip-gnulib-test-tls.patch | 37 + coreutils-skip-some-sort-tests-on-ppc.patch | 52 + coreutils-sysinfo.patch | 64 + coreutils-test_without_valgrind.patch | 18 + ...s-tests-shorten-extreme-factor-tests.patch | 36 + coreutils-use-python3.patch | 24 + coreutils.changes | 2948 +++++++++ coreutils.keyring | 1103 ++++ coreutils.spec | 321 + gnulib-test-avoid-FP-perror-strerror.patch | 101 + 25 files changed, 10659 insertions(+) create mode 100644 .coreutils.metadata create mode 100644 .gitignore create mode 100644 baselibs.conf create mode 100644 coreutils-8.32.tar.xz.sig create mode 100644 coreutils-build-timeout-as-pie.patch create mode 100644 coreutils-df-fuse-portal-dummy.patch create mode 100644 coreutils-disable_tests.patch create mode 100644 coreutils-getaddrinfo.patch create mode 100644 coreutils-gnulib-disable-test-float.patch create mode 100644 coreutils-i18n.patch create mode 100644 coreutils-invalid-ids.patch create mode 100644 coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch create mode 100644 coreutils-misc.patch create mode 100644 coreutils-remove_hostname_documentation.patch create mode 100644 coreutils-remove_kill_documentation.patch create mode 100644 coreutils-skip-gnulib-test-tls.patch create mode 100644 coreutils-skip-some-sort-tests-on-ppc.patch create mode 100644 coreutils-sysinfo.patch create mode 100644 coreutils-test_without_valgrind.patch create mode 100644 coreutils-tests-shorten-extreme-factor-tests.patch create mode 100644 coreutils-use-python3.patch create mode 100644 coreutils.changes create mode 100644 coreutils.keyring create mode 100644 coreutils.spec create mode 100644 gnulib-test-avoid-FP-perror-strerror.patch diff --git a/.coreutils.metadata b/.coreutils.metadata new file mode 100644 index 0000000..004048a --- /dev/null +++ b/.coreutils.metadata @@ -0,0 +1 @@ +cb6b804ac6193a4e3b0ce59473ac38a47e120d2fbc7e08bd205088e5b5ddedbb coreutils-8.32.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a60bbc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +coreutils-8.32.tar.xz diff --git a/baselibs.conf b/baselibs.conf new file mode 100644 index 0000000..34d4a2b --- /dev/null +++ b/baselibs.conf @@ -0,0 +1,3 @@ +targettype x86 package coreutils + +^/bin/uname$ + prereq -glibc-x86 diff --git a/coreutils-8.32.tar.xz.sig b/coreutils-8.32.tar.xz.sig new file mode 100644 index 0000000..e1420fc --- /dev/null +++ b/coreutils-8.32.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAl5hC5MACgkQ32/ZcTBg +N9n92Q//Td2GE1f8AZKkxCNI76Q/TqbxAwhjbkR+KdzvsyMePmgHcMgHG6sO2MNF +g6DIBmHpO3vWGzvUxUZRRhuW5QBOnMxHb/WXZ0p/g45d5MQdn4i0dA0wUJgByOqn +/WVfygNg9mrWFx/uTeCdhrwL11m71C7j/eQVu7Wr5DIb20VJ8+nVC2IWW33ZvxRj +Goa0wwDpeeD9qYe/Y+E5ZyhDYHJGRmNAlS03SXLO3+RfsbZFwdQEtzvr+v1VN6/S +9OsoI/GLdRjY1tByppaoZ63ZybB6iF5zZfJiWDF7Nw4MduJpjZQDSywiNleJ9vOi +fwR1180PjMV6aTXvPwqbqQxZjDl7nqvO36ghlTvErJbqdJVIYxmUGNjeJyjqI85l +Lhckh0GWos9K/kl13Ry9KWsxNQgfjNhtgjXGh+W47ojrho2kCiK5BTwDFeVU0jtU +H/1EePSGAIUF/Sfjz3rmGgLaaBwPiRiyzEIuZMyd4NCJWwfOTqgOshOYw15GCWYq +wGesN/4LWzEja7Au5lHP7imXjP0bp4qE/sYrOb4WzVVLCn+z2hu6SEIzjJzSm+D+ +8Wv3Ia1/ypVpR+Z7gUt7VtEvI8zAwlySd/6Jw5U7TL0rzvZsTVWmCvEjPp+o3jCB +Fy/4ybao1gowBFtT1AtPMmxmiJ41KWCxLFrTuGJpFYCGvBH2y8s= +=yHV6 +-----END PGP SIGNATURE----- diff --git a/coreutils-build-timeout-as-pie.patch b/coreutils-build-timeout-as-pie.patch new file mode 100644 index 0000000..2b2f9c2 --- /dev/null +++ b/coreutils-build-timeout-as-pie.patch @@ -0,0 +1,39 @@ +From d1a49cccf99373293a88f5bce74857d5bb813e46 Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Thu, 10 Jan 2013 09:21:22 +0200 +Subject: build timeout as PIE + +The OBS requires /usr/bin/timeout to be built as an position +independent executable (PIE). This is enforced via RPMLINT. + +* src/local.mk (AM_CFLAGS): Add -fpie option. +(timeout_CFLAGS): Likewise. +(timeout_LDFLAGS): Add -pie option. + +--- + src/local.mk | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: src/local.mk +=================================================================== +--- src/local.mk.orig ++++ src/local.mk +@@ -17,7 +17,7 @@ + ## along with this program. If not, see . + + # FIXME: once lib/ and gnulib-tests/ are also converted, hoist to Makefile.am +-AM_CFLAGS = $(WERROR_CFLAGS) ++AM_CFLAGS = $(WERROR_CFLAGS) -fpie + + # The list of all programs (separated in different variables to express + # the how and when they should be installed) is defined in this makefile +@@ -280,6 +280,9 @@ src_factor_LDADD += $(LIB_GMP) + # for getloadavg + src_uptime_LDADD += $(GETLOADAVG_LIBS) + ++src_timeout_CFLAGS = -fpie ++src_timeout_LDFLAGS = -pie ++ + # for various ACL functions + copy_ldadd += $(LIB_ACL) + src_ls_LDADD += $(LIB_HAS_ACL) diff --git a/coreutils-df-fuse-portal-dummy.patch b/coreutils-df-fuse-portal-dummy.patch new file mode 100644 index 0000000..26bb57f --- /dev/null +++ b/coreutils-df-fuse-portal-dummy.patch @@ -0,0 +1,29 @@ +From 9a38d499ca16f2f4304992eb1ab0894cd0b478e1 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 7 Jun 2021 14:43:03 +0200 +Subject: [PATCH] mountlist: recognize fuse.portal as dummy file system + +This was originally proposed at: + + https://lists.gnu.org/archive/html/bug-gnulib/2021-02/msg00053.html + +As the full review might take some time, would it be possible to apply +at least the part related to fuse.portal file systems? They started to +cause problems recently: + + https://bugs.launchpad.net/ubuntu/+source/xdg-desktop-portal/+bug/1905623 + https://github.com/muesli/duf/issues/35 + https://bugzilla.redhat.com/1913358 +--- +diff --git a/lib/mountlist.c b/lib/mountlist.c +index f5d1364c1..e4c177982 100644 +--- a/lib/mountlist.c ++++ b/lib/mountlist.c +@@ -170,6 +170,7 @@ + || strcmp (Fs_type, "debugfs") == 0 \ + || strcmp (Fs_type, "devpts") == 0 \ + || strcmp (Fs_type, "fusectl") == 0 \ ++ || strcmp (Fs_type, "fuse.portal") == 0 \ + || strcmp (Fs_type, "mqueue") == 0 \ + || strcmp (Fs_type, "rpc_pipefs") == 0 \ + || strcmp (Fs_type, "sysfs") == 0 \ diff --git a/coreutils-disable_tests.patch b/coreutils-disable_tests.patch new file mode 100644 index 0000000..86da92c --- /dev/null +++ b/coreutils-disable_tests.patch @@ -0,0 +1,23 @@ +--- + gnulib-tests/gnulib.mk | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +Index: gnulib-tests/gnulib.mk +=================================================================== +--- gnulib-tests/gnulib.mk.orig ++++ gnulib-tests/gnulib.mk +@@ -951,10 +951,10 @@ EXTRA_DIST += test-getloadavg.c signatur + + ## begin gnulib module getlogin-tests + +-TESTS += test-getlogin +-check_PROGRAMS += test-getlogin +-test_getlogin_LDADD = $(LDADD) $(LIB_GETLOGIN) +-EXTRA_DIST += test-getlogin.c test-getlogin.h signature.h macros.h ++#TESTS += test-getlogin ++#check_PROGRAMS += test-getlogin ++#test_getlogin_LDADD = $(LDADD) $(LIB_GETLOGIN) ++#EXTRA_DIST += test-getlogin.c test-getlogin.h signature.h macros.h + + ## end gnulib module getlogin-tests + diff --git a/coreutils-getaddrinfo.patch b/coreutils-getaddrinfo.patch new file mode 100644 index 0000000..13b8013 --- /dev/null +++ b/coreutils-getaddrinfo.patch @@ -0,0 +1,21 @@ +--- + gnulib-tests/test-getaddrinfo.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +Index: gnulib-tests/test-getaddrinfo.c +=================================================================== +--- gnulib-tests/test-getaddrinfo.c.orig ++++ gnulib-tests/test-getaddrinfo.c +@@ -93,11 +93,7 @@ simple (char const *host, char const *se + the test merely because someone is down the country on their + in-law's farm. */ + if (res == EAI_AGAIN) +- { +- skip++; +- fprintf (stderr, "skipping getaddrinfo test: no network?\n"); +- return 77; +- } ++ return 0; + /* IRIX reports EAI_NONAME for "https". Don't fail the test + merely because of this. */ + if (res == EAI_NONAME) diff --git a/coreutils-gnulib-disable-test-float.patch b/coreutils-gnulib-disable-test-float.patch new file mode 100644 index 0000000..e0b8d1a --- /dev/null +++ b/coreutils-gnulib-disable-test-float.patch @@ -0,0 +1,25 @@ +Disable gnulib test 'test-float' temporarily as it fails on ppc and ppc64le. + +* gnulib-tests/gnulib.mk: Comment lines related to 'test-float'. +--- + gnulib-tests/gnulib.mk | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +Index: gnulib-tests/gnulib.mk +=================================================================== +--- gnulib-tests/gnulib.mk.orig ++++ gnulib-tests/gnulib.mk +@@ -635,9 +635,10 @@ EXTRA_DIST += test-filevercmp.c macros.h + + ## begin gnulib module float-tests + +-TESTS += test-float +-check_PROGRAMS += test-float +-EXTRA_DIST += test-float.c macros.h ++# Test fails with GCC-10 on ppc and ppc64le. ++#TESTS += test-float ++#check_PROGRAMS += test-float ++#EXTRA_DIST += test-float.c macros.h + + ## end gnulib module float-tests + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch new file mode 100644 index 0000000..4b8cd60 --- /dev/null +++ b/coreutils-i18n.patch @@ -0,0 +1,5332 @@ + bootstrap.conf | 1 + configure.ac | 2 + lib/linebuffer.h | 8 + lib/mbfile.c | 3 + lib/mbfile.h | 255 ++++++++++++++ + m4/mbfile.m4 | 14 + src/cut.c | 441 ++++++++++++++++++++++++- + src/expand-common.c | 114 ++++++ + src/expand-common.h | 12 + src/expand.c | 90 ++++- + src/fold.c | 308 ++++++++++++++++- + src/join.c | 359 +++++++++++++++++--- + src/pr.c | 443 ++++++++++++++++++++++--- + src/sort.c | 772 +++++++++++++++++++++++++++++++++++++++++--- + src/unexpand.c | 101 ++++- + src/uniq.c | 119 ++++++ + 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/sort-merge.pl | 42 ++ + tests/misc/sort.pl | 40 ++ + tests/misc/unexpand.pl | 39 ++ + tests/misc/uniq.pl | 55 +++ + tests/pr/pr-tests.pl | 49 ++ + tests/unexpand/mb.sh | 172 +++++++++ + 29 files changed, 3632 insertions(+), 210 deletions(-) + create mode 100644 lib/mbfile.c + create mode 100644 lib/mbfile.h + create mode 100644 m4/mbfile.m4 + 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 + +Index: bootstrap.conf +=================================================================== +--- bootstrap.conf.orig ++++ bootstrap.conf +@@ -154,6 +154,7 @@ gnulib_modules=" + maintainer-makefile + malloc-gnu + manywarnings ++ mbfile + mbrlen + mbrtowc + mbsalign +Index: configure.ac +=================================================================== +--- configure.ac.orig ++++ configure.ac +@@ -446,6 +446,8 @@ fi + # I'm leaving it here for now. This whole thing needs to be modernized... + gl_WINSIZE_IN_PTEM + ++gl_MBFILE ++ + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H + + if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ +Index: lib/linebuffer.h +=================================================================== +--- lib/linebuffer.h.orig ++++ lib/linebuffer.h +@@ -21,6 +21,11 @@ + + # include + ++/* Get mbstate_t. */ ++# if HAVE_WCHAR_H ++# include ++# endif ++ + /* A 'struct linebuffer' holds a line of text. */ + + struct linebuffer +@@ -28,6 +33,9 @@ struct linebuffer + size_t size; /* Allocated. */ + size_t length; /* Used. */ + char *buffer; ++# if HAVE_WCHAR_H ++ mbstate_t state; ++# endif + }; + + /* Initialize linebuffer LINEBUFFER for use. */ +Index: lib/mbfile.c +=================================================================== +--- /dev/null ++++ lib/mbfile.c +@@ -0,0 +1,3 @@ ++#include ++#define MBFILE_INLINE _GL_EXTERN_INLINE ++#include "mbfile.h" +Index: lib/mbfile.h +=================================================================== +--- /dev/null ++++ lib/mbfile.h +@@ -0,0 +1,255 @@ ++/* Multibyte character I/O: macros for multi-byte encodings. ++ Copyright (C) 2001, 2005, 2009-2015 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 . */ ++ ++/* Written by Mitsuru Chinen ++ and Bruno Haible . */ ++ ++/* The macros in this file implement multi-byte character input from a ++ stream. ++ ++ mb_file_t ++ is the type for multibyte character input stream, usable for variable ++ declarations. ++ ++ mbf_char_t ++ is the type for multibyte character or EOF, usable for variable ++ declarations. ++ ++ mbf_init (mbf, stream) ++ initializes the MB_FILE for reading from stream. ++ ++ mbf_getc (mbc, mbf) ++ reads the next multibyte character from mbf and stores it in mbc. ++ ++ mb_iseof (mbc) ++ returns true if mbc represents the EOF value. ++ ++ Here are the function prototypes of the macros. ++ ++ extern void mbf_init (mb_file_t mbf, FILE *stream); ++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); ++ extern bool mb_iseof (const mbf_char_t mbc); ++ */ ++ ++#ifndef _MBFILE_H ++#define _MBFILE_H 1 ++ ++#include ++#include ++#include ++#include ++ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.1 has a bug: and must be included before ++ . */ ++#include ++#include ++#include ++ ++#include "mbchar.h" ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++#ifndef MBFILE_INLINE ++# define MBFILE_INLINE _GL_INLINE ++#endif ++ ++struct mbfile_multi { ++ FILE *fp; ++ bool eof_seen; ++ bool have_pushback; ++ mbstate_t state; ++ unsigned int bufcount; ++ char buf[MBCHAR_BUF_SIZE]; ++ struct mbchar pushback; ++}; ++ ++MBFILE_INLINE void ++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ size_t bytes; ++ ++ /* 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; ++ } ++ ++ /* Before using mbrtowc, we need at least one byte. */ ++ if (mbf->bufcount == 0) ++ { ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ mbf->eof_seen = true; ++ goto eof; ++ } ++ mbf->buf[0] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ ++ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ ++ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) ++ { ++ /* These characters are part of the basic character set. ISO C 99 ++ guarantees that their wide character code is identical to their ++ char code. */ ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; ++ mbc->wc_valid = true; ++ mbc->ptr = &mbc->buf[0]; ++ mbc->bytes = 1; ++ mbf->bufcount = 0; ++ return; ++ } ++ ++ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes ++ from mbf->fp as needed. This is needed to give reasonable interactive ++ behaviour when mbf->fp is connected to an interactive tty. */ ++ for (;;) ++ { ++ /* We don't know whether the 'mbrtowc' function updates the state when ++ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or ++ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We ++ don't have an autoconf test for this, yet. ++ The new behaviour would allow us to feed the bytes one by one into ++ mbrtowc. But the old behaviour forces us to feed all bytes since ++ the end of the last character into mbrtowc. Since we want to retry ++ with more bytes when mbrtowc returns -2, we must backup the state ++ before calling mbrtowc, because implementations with the new ++ behaviour will clobber it. */ ++ mbstate_t backup_state = mbf->state; ++ ++ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); ++ ++ if (bytes == (size_t) -1) ++ { ++ /* An invalid multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else if (bytes == (size_t) -2) ++ { ++ /* An incomplete multibyte character. */ ++ mbf->state = backup_state; ++ if (mbf->bufcount == MBCHAR_BUF_SIZE) ++ { ++ /* An overlong incomplete multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else ++ { ++ /* Read one more byte and retry mbrtowc. */ ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ /* An incomplete multibyte character at the end. */ ++ mbf->eof_seen = true; ++ bytes = mbf->bufcount; ++ mbc->wc_valid = false; ++ break; ++ } ++ mbf->buf[mbf->bufcount] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ } ++ else ++ { ++ if (bytes == 0) ++ { ++ /* A null wide character was encountered. */ ++ bytes = 1; ++ assert (mbf->buf[0] == '\0'); ++ assert (mbc->wc == 0); ++ } ++ mbc->wc_valid = true; ++ break; ++ } ++ } ++ ++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ ++ mbc->ptr = &mbc->buf[0]; ++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); ++ mbc->bytes = bytes; ++ ++ mbf->bufcount -= bytes; ++ if (mbf->bufcount > 0) ++ { ++ /* It's not worth calling memmove() for so few bytes. */ ++ unsigned int count = mbf->bufcount; ++ char *p = &mbf->buf[0]; ++ ++ do ++ { ++ *p = *(p + bytes); ++ p++; ++ } ++ while (--count > 0); ++ } ++ return; ++ ++eof: ++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ ++ mbc->ptr = NULL; ++ mbc->bytes = 0; ++ mbc->wc_valid = false; ++ return; ++} ++ ++MBFILE_INLINE void ++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ mb_copy (&mbf->pushback, mbc); ++ mbf->have_pushback = true; ++} ++ ++typedef struct mbfile_multi mb_file_t; ++ ++typedef mbchar_t mbf_char_t; ++ ++#define mbf_init(mbf, stream) \ ++ ((mbf).fp = (stream), \ ++ (mbf).eof_seen = false, \ ++ (mbf).have_pushback = false, \ ++ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ ++ (mbf).bufcount = 0) ++ ++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) ++ ++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) ++ ++#define mb_iseof(mbc) ((mbc).bytes == 0) ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++ ++#endif /* _MBFILE_H */ +Index: m4/mbfile.m4 +=================================================================== +--- /dev/null ++++ m4/mbfile.m4 +@@ -0,0 +1,14 @@ ++# mbfile.m4 serial 7 ++dnl Copyright (C) 2005, 2008-2015 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 mbfile.h ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBFILE], ++[ ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) ++ : ++]) +Index: src/cut.c +=================================================================== +--- src/cut.c.orig ++++ src/cut.c +@@ -28,6 +28,11 @@ + #include + #include + #include ++ ++/* Get mbstate_t, mbrtowc(). */ ++#if HAVE_WCHAR_H ++# include ++#endif + #include "system.h" + + #include "error.h" +@@ -38,6 +43,18 @@ + + #include "set-fields.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 ++ + /* The official name of this program (e.g., no 'g' prefix). */ + #define PROGRAM_NAME "cut" + +@@ -54,6 +71,52 @@ + } \ + while (0) + ++/* Refill the buffer BUF to get a multibyte character. */ ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ ++ do \ ++ { \ ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ ++ { \ ++ memmove (BUF, BUFPOS, BUFLEN); \ ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ ++ BUFPOS = BUF; \ ++ } \ ++ } \ ++ while (0) ++ ++/* Get wide character on BUFPOS. BUFPOS is not included after that. ++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ if (BUFLEN < 1) \ ++ { \ ++ WC = WEOF; \ ++ break; \ ++ } \ ++ \ ++ /* Get a wide character. */ \ ++ CONVFAIL = false; \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ CONVFAIL = true; \ ++ STATE = state_bak; \ ++ /* Fall througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ ++ while (0) ++ + + /* Pointer inside RP. When checking if a byte or field is selected + by a finite range, we check if it is between CURRENT_RP.LO +@@ -61,6 +124,9 @@ + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ + static struct field_range_pair *current_rp; + ++/* Length of the delimiter given as argument to -d. */ ++size_t delimlen; ++ + /* This buffer is used to support the semantics of the -s option + (or lack of same) when the specified field list includes (does + not include) the first field. In both of those cases, the entire +@@ -77,15 +143,25 @@ enum operating_mode + { + undefined_mode, + +- /* Output characters that are in the given bytes. */ ++ /* Output bytes that are at the given positions. */ + byte_mode, + ++ /* Output characters that are at the given positions. */ ++ character_mode, ++ + /* Output the given delimiter-separated fields. */ + field_mode + }; + + static enum operating_mode operating_mode; + ++/* If nonzero, when in byte mode, don't split multibyte characters. */ ++static int byte_mode_character_aware; ++ ++/* If nonzero, the function for single byte locale is work ++ if this program runs on multibyte locale. */ ++static int force_singlebyte_mode; ++ + /* If true do not output lines containing no delimiter characters. + Otherwise, all such lines are printed. This option is valid only + with field mode. */ +@@ -97,6 +173,9 @@ static bool complement; + + /* The delimiter character for field mode. */ + static unsigned char delim; ++#if HAVE_WCHAR_H ++static wchar_t wcdelim; ++#endif + + /* The delimiter for each line/record. */ + static unsigned char line_delim = '\n'; +@@ -164,7 +243,7 @@ Print selected parts of lines from each + -f, --fields=LIST select only these fields; also print any line\n\ + that contains no delimiter character, unless\n\ + the -s option is specified\n\ +- -n (ignored)\n\ ++ -n with -b: don't split multibyte characters\n\ + "), stdout); + fputs (_("\ + --complement complement the set of selected bytes, characters\n\ +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++/* This function is in use for the following case. ++ ++ 1. Read from the stream STREAM, printing to standard output any selected ++ characters. ++ ++ 2. Read from stream STREAM, printing to standard output any selected bytes, ++ without splitting multibyte characters. */ ++ ++static void ++cut_characters_or_cut_bytes_no_split (FILE *stream) ++{ ++ uintmax_t idx; /* number of bytes or characters in the line so far. */ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in 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 of the stream. */ ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ ++ /* Whether to begin printing delimiters between ranges for the current line. ++ Set after we've begun printing data corresponding to the first range. */ ++ bool print_delimiter = false; ++ ++ idx = 0; ++ buflen = 0; ++ bufpos = buf; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ current_rp = frp; ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); ++ (void) convfail; /* ignore unused */ ++ ++ if (wc == WEOF) ++ { ++ if (idx > 0) ++ putchar (line_delim); ++ break; ++ } ++ else if (wc == line_delim) ++ { ++ putchar (line_delim); ++ idx = 0; ++ print_delimiter = false; ++ current_rp = frp; ++ } ++ else ++ { ++ next_item (&idx); ++ if (print_kth (idx)) ++ { ++ if (output_delimiter_specified) ++ { ++ if (print_delimiter && is_range_start_index (idx)) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ print_delimiter = true; ++ } ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } ++ } ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ + /* Read from stream STREAM, printing to standard output any selected fields. */ + + static void +@@ -425,13 +580,211 @@ cut_fields (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++static void ++cut_fields_mb (FILE *stream) ++{ ++ int c; ++ uintmax_t field_idx; ++ int found_any_selected_field; ++ int buffer_first_field; ++ int empty_input; ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc = 0; /* 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 of the stream. */ ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ ++ ++ current_rp = frp; ++ ++ found_any_selected_field = 0; ++ field_idx = 1; ++ bufpos = buf; ++ buflen = 0; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ c = getc (stream); ++ empty_input = (c == EOF); ++ if (c != EOF) ++ { ++ ungetc (c, stream); ++ wc = 0; ++ } ++ else ++ wc = WEOF; ++ ++ /* To support the semantics of the -s flag, we may have to buffer ++ all of the first field to determine whether it is `delimited.' ++ But that is unnecessary if all non-delimited lines must be printed ++ and the first field has been selected, or if non-delimited lines ++ must be suppressed and the first field has *not* been selected. ++ That is because a non-delimited line has exactly one field. */ ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); ++ ++ while (1) ++ { ++ if (field_idx == 1 && buffer_first_field) ++ { ++ int len = 0; ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); ++ memcpy (field_1_buffer + len, bufpos, mblength); ++ len += mblength; ++ buflen -= mblength; ++ bufpos += mblength; ++ ++ if (!convfail && (wc == line_delim || wc == wcdelim)) ++ break; ++ } ++ ++ if (len <= 0 && wc == WEOF) ++ break; ++ ++ /* If the first field extends to the end of line (it is not ++ delimited) and we are printing all non-delimited lines, ++ print this one. */ ++ if (convfail || (!convfail && wc != wcdelim)) ++ { ++ if (suppress_non_delimited) ++ { ++ /* Empty. */ ++ } ++ else ++ { ++ fwrite (field_1_buffer, sizeof (char), len, stdout); ++ /* Make sure the output line is newline terminated. */ ++ if (convfail || (!convfail && wc != line_delim)) ++ putchar (line_delim); ++ } ++ continue; ++ } ++ ++ if (print_kth (1)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ next_item (&field_idx); ++ } ++ ++ if (wc != WEOF) ++ { ++ if (print_kth (field_idx)) ++ { ++ if (found_any_selected_field) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ found_any_selected_field = 1; ++ } ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ else if (!convfail && (wc == wcdelim || wc == line_delim)) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } ++ ++ if (print_kth (field_idx)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } ++ ++ if ((!convfail || wc == line_delim) && buflen < 1) ++ wc = WEOF; ++ ++ if (!convfail && wc == wcdelim) ++ next_item (&field_idx); ++ else if (wc == WEOF || (!convfail && wc == line_delim)) ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar (line_delim); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ current_rp = frp; ++ found_any_selected_field = 0; ++ } ++ } ++} ++#endif ++ + static void + cut_stream (FILE *stream) + { +- if (operating_mode == byte_mode) +- cut_bytes (stream); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ switch (operating_mode) ++ { ++ case byte_mode: ++ if (byte_mode_character_aware) ++ cut_characters_or_cut_bytes_no_split (stream); ++ else ++ cut_bytes (stream); ++ break; ++ ++ case character_mode: ++ cut_characters_or_cut_bytes_no_split (stream); ++ break; ++ ++ case field_mode: ++ if (delimlen == 1) ++ { ++ /* Check if we have utf8 multibyte locale, so we can use this ++ optimization because of uniqueness of characters, which is ++ not true for e.g. SJIS */ ++ char * loc = setlocale(LC_CTYPE, NULL); ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) ++ { ++ cut_fields (stream); ++ break; ++ } ++ } ++ cut_fields_mb (stream); ++ break; ++ ++ default: ++ abort (); ++ } ++ } + else +- cut_fields (stream); ++#endif ++ { ++ if (operating_mode == field_mode) ++ cut_fields (stream); ++ else ++ cut_bytes (stream); ++ } + } + + /* Process file FILE to standard output. +@@ -483,6 +836,7 @@ main (int argc, char **argv) + bool ok; + bool delim_specified = false; + char *spec_list_string IF_LINT ( = NULL); ++ char mbdelim[MB_LEN_MAX + 1]; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -505,7 +859,6 @@ main (int argc, char **argv) + switch (optc) + { + case 'b': +- case 'c': + /* Build the byte list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); +@@ -513,6 +866,14 @@ main (int argc, char **argv) + spec_list_string = optarg; + break; + ++ case 'c': ++ /* Build the character list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = character_mode; ++ spec_list_string = optarg; ++ break; ++ + case 'f': + /* Build the field list. */ + if (operating_mode != undefined_mode) +@@ -524,10 +885,38 @@ main (int argc, char **argv) + case 'd': + /* New delimiter. */ + /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ +- if (optarg[0] != '\0' && optarg[1] != '\0') +- FATAL_ERROR (_("the delimiter must be a single character")); +- delim = optarg[0]; +- delim_specified = true; ++ { ++#if HAVE_MBRTOWC ++ if(MB_CUR_MAX > 1) ++ { ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); ++ ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) ++ ++force_singlebyte_mode; ++ else ++ { ++ delimlen = (delimlen < 1) ? 1 : delimlen; ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ memcpy (mbdelim, optarg, delimlen); ++ mbdelim[delimlen] = '\0'; ++ if (delimlen == 1) ++ delim = *optarg; ++ } ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ if (optarg[0] != '\0' && optarg[1] != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ delim = (unsigned char) optarg[0]; ++ } ++ delim_specified = true; ++ } + break; + + case OUTPUT_DELIMITER_OPTION: +@@ -540,6 +929,7 @@ main (int argc, char **argv) + break; + + case 'n': ++ byte_mode_character_aware = 1; + break; + + case 's': +@@ -579,15 +969,34 @@ main (int argc, char **argv) + | (complement ? SETFLD_COMPLEMENT : 0) ); + + if (!delim_specified) +- delim = '\t'; ++ { ++ delim = '\t'; ++#ifdef HAVE_MBRTOWC ++ wcdelim = L'\t'; ++ mbdelim[0] = '\t'; ++ mbdelim[1] = '\0'; ++ delimlen = 1; ++#endif ++ } + + if (output_delimiter_string == NULL) + { +- static char dummy[2]; +- dummy[0] = delim; +- dummy[1] = '\0'; +- output_delimiter_string = dummy; +- output_delimiter_length = 1; ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ output_delimiter_string = xstrdup(mbdelim); ++ output_delimiter_length = delimlen; ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } + } + + if (optind == argc) +Index: src/expand-common.c +=================================================================== +--- src/expand-common.c.orig ++++ src/expand-common.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "system.h" + #include "die.h" + #include "error.h" +@@ -126,6 +127,119 @@ set_increment_size (uintmax_t tabval) + return ok; + } + ++extern int ++set_utf_locale (void) ++{ ++ /*try using some predefined locale */ ++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; ++ ++ const int predef_locales_count=3; ++ for (int i=0;ibufcount=0; ++ if (c == 0xEF) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ ungetc(c,fp); ++ } ++ return false; ++ } ++ ++ if (c == 0xBB) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if ( c!= EOF ) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ ungetc(0xEF,fp); ++ return false; ++ } ++ } ++ if (c == 0xBF) ++ { ++ mbf->bufcount=0; ++ return true; ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->buf[1]=(unsigned char) 0xBB; ++ mbf->bufcount=2; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(0xBB,fp); ++ return false; ++ } ++ } ++ return false; ++} ++ ++extern void ++print_bom(void) ++{ ++ putc (0xEF, stdout); ++ putc (0xBB, stdout); ++ putc (0xBF, stdout); ++} ++ + /* Add the comma or blank separated list of tab stops STOPS + to the list of tab stops. */ + extern void +Index: src/expand-common.h +=================================================================== +--- src/expand-common.h.orig ++++ src/expand-common.h +@@ -34,6 +34,18 @@ extern size_t max_column_width; + /* The desired exit status. */ + extern int exit_status; + ++extern int ++set_utf_locale (void); ++ ++extern bool ++check_utf_locale(void); ++ ++extern bool ++check_bom(FILE* fp, mb_file_t *mbf); ++ ++extern void ++print_bom(void); ++ + /* Add tab stop TABVAL to the end of 'tab_list'. */ + extern void + add_tab_stop (uintmax_t tabval); +Index: src/expand.c +=================================================================== +--- src/expand.c.orig ++++ src/expand.c +@@ -37,6 +37,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + #include "xstrndup.h" +@@ -98,19 +101,41 @@ expand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; ++ mbf_char_t c; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; ++ ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); + + if (!fp) + return; ++ mbf_init (mbf, fp); ++ found_bom=check_bom(fp,&mbf); + +- while (true) ++ if (using_utf_locale == false && found_bom == true) ++ { ++ /*try using some predefined locale */ ++ ++ if (set_utf_locale () != 0) + { +- /* Input character, or EOF. */ +- int c; ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } ++ } ++ + ++ if (found_bom == true) ++ { ++ print_bom(); ++ } ++ ++ while (true) ++ { + /* If true, perform translations. */ + bool convert = true; + +- + /* The following variables have valid values only when CONVERT + is true: */ + +@@ -120,17 +145,48 @@ expand (void) + /* Index in TAB_LIST of next tab stop to examine. */ + size_t tab_index = 0; + +- + /* Convert a line of text. */ + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ *all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +@@ -149,32 +205,34 @@ expand (void) + if (putchar (' ') < 0) + die (EXIT_FAILURE, errno, _("write error")); + +- c = ' '; ++ mb_setascii (&c, ' '); + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ + column -= !!column; + tab_index -= !!tab_index; + } +- else ++ /* A leading control character could make us trip over. */ ++ else if (!mb_iscntrl (c)) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } + +- convert &= convert_entire_line || !! isblank (c); ++ convert &= convert_entire_line || mb_isblank (c); + } + +- if (c < 0) ++ if (mb_iseof (c)) + return; + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } + +Index: src/fold.c +=================================================================== +--- src/fold.c.orig ++++ src/fold.c +@@ -22,12 +22,34 @@ + #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 "die.h" + #include "error.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). */ +@@ -35,20 +57,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, NULL, 'b'}, ++ {"characters", no_argument, NULL, 'c'}, + {"spaces", no_argument, NULL, 's'}, + {"width", required_argument, NULL, 'w'}, + {GETOPT_HELP_OPTION_DECL}, +@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing t + + 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); +@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing t + static size_t + adjust_column (size_t column, char c) + { +- if (!count_bytes) ++ if (operating_mode != byte_mode) + { + if (c == '\b') + { +@@ -116,30 +160,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. */ + size_t offset_out = 0; /* Index in 'line_out' for next char. */ + static char *line_out = NULL; + static size_t allocated_out = 0; +- int saved_errno; +- +- if (STREQ (filename, "-")) +- { +- istream = stdin; +- have_read_stdin = true; +- } +- else +- istream = fopen (filename, "r"); +- +- if (istream == NULL) +- { +- error (0, errno, "%s", quotef (filename)); +- return false; +- } + + fadvise (istream, FADVISE_SEQUENTIAL); + +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t + bool found_blank = false; + size_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) + { +@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t + line_out[offset_out++] = c; + } + +- saved_errno = errno; ++ *saved_errno = errno; + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) 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; ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ ++ static size_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 (operating_mode == byte_mode) /* byte mode */ ++ increment = mblength; ++ else if (operating_mode == character_mode) /* character mode */ ++ increment = 1; ++ else /* column mode */ ++ { ++ if (convfail) ++ increment = 1; ++ else ++ { ++ 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'\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 = X2REALLOC (line_out, &allocated_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 (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) 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. */ ++ ++static bool ++fold_file (char const *filename, size_t width) ++{ ++ FILE *istream; ++ int saved_errno; ++ ++ if (STREQ (filename, "-")) ++ { ++ istream = stdin; ++ have_read_stdin = 1; ++ } ++ else ++ istream = fopen (filename, "r"); ++ ++ if (istream == NULL) ++ { ++ error (0, errno, "%s", filename); ++ return 1; ++ } ++ ++ /* 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 (ferror (istream)) + { + error (0, saved_errno, "%s", quotef (filename)); +@@ -252,7 +499,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, NULL)) != -1) + { +@@ -261,7 +509,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. */ +Index: src/join.c +=================================================================== +--- src/join.c.orig ++++ src/join.c +@@ -22,19 +22,33 @@ + #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 "die.h" + #include "error.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" + +@@ -136,10 +150,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 +@@ -276,13 +292,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)) != NULL; ptr = sep + 1) ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; 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)) +@@ -306,6 +323,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) + { +@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct + size_t jf_1, size_t jf_2) + { + /* Start of field to compare in each file. */ +- char *beg1; +- char *beg2; +- +- size_t len1; +- size_t len2; /* Length of fields to compare. */ ++ char *beg[2]; ++ char *copy[2]; ++ size_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 = NULL; +- len1 = 0; ++ beg[0] = NULL; ++ 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 = NULL; +- len2 = 0; ++ beg[1] = NULL; ++ 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 ? -1 : len1 != len2; ++ return len[0] - len[1]; + } + + /* Check that successive input lines PREV and CURRENT from input file +@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, + } + ++line_no[which - 1]; + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ xfields_multibyte (line); ++ else ++#endif + xfields (line); + + if (prevline[which - 1]) +@@ -563,21 +803,28 @@ prfield (size_t n, struct line const *li + + /* 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, size_t join_field, size_t autocount) + { + size_t i; + size_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); + } + } +@@ -588,7 +835,6 @@ static void + prjoin (struct line const *line1, struct line const *line2) + { + const struct outlist *outlist; +- char output_separator = tab < 0 ? ' ' : tab; + size_t field; + struct line const *line; + +@@ -622,7 +868,7 @@ prjoin (struct line const *line1, struct + o = o->next; + if (o == NULL) + break; +- putchar (output_separator); ++ PUT_TAB_CHAR; + } + putchar (eolchar); + } +@@ -1098,20 +1344,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 +- die (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); ++ die (EXIT_FAILURE, 0, _("incompatible tabs")); + } +- if (0 <= tab && tab != newtab) +- die (EXIT_FAILURE, 0, _("incompatible tabs")); + tab = newtab; ++ tablen = newtablen; + } + break; + +Index: src/pr.c +=================================================================== +--- src/pr.c.orig ++++ src/pr.c +@@ -311,6 +311,24 @@ + + #include + #include ++ ++/* Get MB_LEN_MAX. */ ++#include ++/* 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 == 1 ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Get MB_CUR_MAX. */ ++#include ++ ++/* Solaris 2.5 has a bug: must be included before . */ ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include ++#endif ++ + #include "system.h" + #include "die.h" + #include "error.h" +@@ -325,6 +343,18 @@ + #include "xstrtol-error.h" + #include "xdectoint.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 ++ ++#ifndef HAVE_DECL_WCWIDTH ++"this configure-time declaration test was not run" ++#endif ++#if !HAVE_DECL_WCWIDTH ++extern int wcwidth (); ++#endif ++ + /* The official name of this program (e.g., no 'g' prefix). */ + #define PROGRAM_NAME "pr" + +@@ -417,7 +447,20 @@ struct COLUMN + + typedef struct COLUMN COLUMN; + +-static int char_to_clump (char c); ++/* Funtion pointers to switch functions for single byte locale or for ++ multibyte locale. If multibyte functions do not exist in your sysytem, ++ these pointers always point the function for single byte locale. */ ++static void (*print_char) (char c); ++static int (*char_to_clump) (char c); ++ ++/* Functions for single byte locale. */ ++static void print_char_single (char c); ++static int char_to_clump_single (char c); ++ ++/* Functions for multibyte locale. */ ++static void print_char_multi (char c); ++static int char_to_clump_multi (char c); ++ + static bool read_line (COLUMN *p); + static bool print_page (void); + static bool print_stored (COLUMN *p); +@@ -429,6 +472,7 @@ static void add_line_number (COLUMN *p); + static void getoptnum (const char *n_str, int min, int *num, + const char *errfmt); + static void getoptarg (char *arg, char switch_char, char *character, ++ int *character_length, int *character_width, + int *number); + static void print_files (int number_of_files, char **av); + static void init_parameters (int number_of_files); +@@ -442,7 +486,6 @@ static void store_char (char c); + static void pad_down (unsigned int lines); + static void read_rest_of_line (COLUMN *p); + static void skip_read (COLUMN *p, int column_number); +-static void print_char (char c); + static void cleanup (void); + static void print_sep_string (void); + static void separator_string (const char *optarg_S); +@@ -454,7 +497,7 @@ static COLUMN *column_vector; + we store the leftmost columns contiguously in buff. + To print a line from buff, get the index of the first character + from line_vector[i], and print up to line_vector[i + 1]. */ +-static char *buff; ++static unsigned char *buff; + + /* Index of the position in buff where the next character + will be stored. */ +@@ -558,7 +601,7 @@ static int chars_per_column; + static bool untabify_input = false; + + /* (-e) The input tab character. */ +-static char input_tab_char = '\t'; ++static char input_tab_char[MB_LEN_MAX] = "\t"; + + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... + where the leftmost column is 1. */ +@@ -568,7 +611,10 @@ static int chars_per_input_tab = 8; + static bool tabify_output = false; + + /* (-i) The output tab character. */ +-static char output_tab_char = '\t'; ++static char output_tab_char[MB_LEN_MAX] = "\t"; ++ ++/* (-i) The byte length of output tab character. */ ++static int output_tab_char_length = 1; + + /* (-i) The width of the output tab. */ + static int chars_per_output_tab = 8; +@@ -638,7 +684,13 @@ static int line_number; + static bool numbered_lines = false; + + /* (-n) Character which follows each line number. */ +-static char number_separator = '\t'; ++static char number_separator[MB_LEN_MAX] = "\t"; ++ ++/* (-n) The byte length of the character which follows each line number. */ ++static int number_separator_length = 1; ++ ++/* (-n) The character width of the character which follows each line number. */ ++static int number_separator_width = 0; + + /* (-n) line counting starts with 1st line of input file (not with 1st + line of 1st page printed). */ +@@ -691,6 +743,7 @@ static bool use_col_separator = false; + -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ + static char const *col_sep_string = ""; + static int col_sep_length = 0; ++static int col_sep_width = 0; + static char *column_separator = (char *) " "; + static char *line_separator = (char *) "\t"; + +@@ -852,6 +905,13 @@ separator_string (const char *optarg_S) + integer_overflow (); + col_sep_length = len; + col_sep_string = optarg_S; ++ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ col_sep_width = mbswidth (col_sep_string, 0); ++ else ++#endif ++ col_sep_width = col_sep_length; + } + + int +@@ -876,6 +936,21 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++/* Define which functions are used, the ones for single byte locale or the ones ++ for multibyte locale. */ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ print_char = print_char_multi; ++ char_to_clump = char_to_clump_multi; ++ } ++ else ++#endif ++ { ++ print_char = print_char_single; ++ char_to_clump = char_to_clump_single; ++ } ++ + n_files = 0; + file_names = (argc > 1 + ? xnmalloc (argc - 1, sizeof (char *)) +@@ -952,8 +1027,12 @@ main (int argc, char **argv) + break; + case 'e': + if (optarg) +- getoptarg (optarg, 'e', &input_tab_char, +- &chars_per_input_tab); ++ { ++ int dummy_length, dummy_width; ++ ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, ++ &dummy_width, &chars_per_input_tab); ++ } + /* Could check tab width > 0. */ + untabify_input = true; + break; +@@ -966,8 +1045,12 @@ main (int argc, char **argv) + break; + case 'i': + if (optarg) +- getoptarg (optarg, 'i', &output_tab_char, +- &chars_per_output_tab); ++ { ++ int dummy_width; ++ ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, ++ &dummy_width, &chars_per_output_tab); ++ } + /* Could check tab width > 0. */ + tabify_output = true; + break; +@@ -985,8 +1068,8 @@ main (int argc, char **argv) + case 'n': + numbered_lines = true; + if (optarg) +- getoptarg (optarg, 'n', &number_separator, +- &chars_per_number); ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, ++ &number_separator_width, &chars_per_number); + break; + case 'N': + skip_count = false; +@@ -1011,6 +1094,7 @@ main (int argc, char **argv) + /* Reset an additional input of -s, -S dominates -s */ + col_sep_string = ""; + col_sep_length = 0; ++ col_sep_width = 0; + use_col_separator = true; + if (optarg) + separator_string (optarg); +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, i + a number. */ + + static void +-getoptarg (char *arg, char switch_char, char *character, int *number) ++getoptarg (char *arg, char switch_char, char *character, int *character_length, ++ int *character_width, int *number) + { + if (!ISDIGIT (*arg)) +- *character = *arg++; ++ { ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ ++ { ++ wchar_t wc; ++ size_t mblength; ++ int width; ++ mbstate_t state = {'\0'}; ++ ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ *character_length = 1; ++ *character_width = 1; ++ } ++ else ++ { ++ *character_length = (mblength < 1) ? 1 : mblength; ++ width = wcwidth (wc); ++ *character_width = (width < 0) ? 0 : width; ++ } ++ ++ strncpy (character, arg, *character_length); ++ arg += *character_length; ++ } ++ else /* for single byte locale. */ ++#endif ++ { ++ *character = *arg++; ++ *character_length = 1; ++ *character_width = 1; ++ } ++ } ++ + if (*arg) + { + long int tmp_long; +@@ -1191,6 +1310,11 @@ static void + init_parameters (int number_of_files) + { + int chars_used_by_number = 0; ++ int mb_len = 1; ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ mb_len = MB_LEN_MAX; ++#endif + + lines_per_body = lines_per_page - lines_per_header - lines_per_footer; + if (lines_per_body <= 0) +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) + else + col_sep_string = column_separator; + +- col_sep_length = 1; ++ col_sep_length = col_sep_width = 1; + use_col_separator = true; + } + /* It's rather pointless to define a TAB separator with column +@@ -1258,11 +1382,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. */ +- if (number_separator == '\t') ++ if (number_separator[0] == '\t') + number_width = (chars_per_number + + TAB_WIDTH (chars_per_default_tab, chars_per_number)); + else +- number_width = chars_per_number + 1; ++ number_width = chars_per_number + number_separator_width; + + /* The number is part of the column width unless we are + printing files in parallel. */ +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) + } + + int sep_chars, useful_chars; +- if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_length, &sep_chars)) ++ if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_width, &sep_chars)) + sep_chars = INT_MAX; + if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, + &useful_chars)) +@@ -1294,7 +1418,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); +- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); ++ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); + } + + /* Open the necessary files, +@@ -1400,7 +1524,7 @@ init_funcs (void) + + /* Enlarge p->start_position of first column to use the same form of + padding_not_printed with all columns. */ +- h = h + col_sep_length; ++ h = h + col_sep_width; + + /* This loop takes care of all but the rightmost column. */ + +@@ -1434,7 +1558,7 @@ init_funcs (void) + } + else + { +- h = h_next + col_sep_length; ++ h = h_next + col_sep_width; + h_next = h + chars_per_column; + } + } +@@ -1725,9 +1849,9 @@ static void + align_column (COLUMN *p) + { + padding_not_printed = p->start_position; +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2002,13 +2126,13 @@ store_char (char c) + /* May be too generous. */ + buff = X2REALLOC (buff, &buff_allocated); + } +- buff[buff_current++] = c; ++ buff[buff_current++] = (unsigned char) c; + } + + static void + add_line_number (COLUMN *p) + { +- int i; ++ int i, j; + char *s; + int num_width; + +@@ -2025,22 +2149,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. */ +- if (number_separator == '\t') ++ if (number_separator[0] == '\t') + { + i = number_width - chars_per_number; + while (i-- > 0) + (p->char_func) (' '); + } + else +- (p->char_func) (number_separator); ++ for (j = 0; j < number_separator_length; j++) ++ (p->char_func) (number_separator[j]); + } + else + /* To comply with POSIX, we avoid any expansion of default TAB + separator with a single column output. No column_width requirement + has to be considered. */ + { +- (p->char_func) (number_separator); +- if (number_separator == '\t') ++ for (j = 0; j < number_separator_length; j++) ++ (p->char_func) (number_separator[j]); ++ if (number_separator[0] == '\t') + output_position = POS_AFTER_TAB (chars_per_output_tab, + output_position); + } +@@ -2199,7 +2325,7 @@ print_white_space (void) + while (goal - h_old > 1 + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) + { +- putchar (output_tab_char); ++ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); + h_old = h_new; + } + while (++h_old <= goal) +@@ -2219,6 +2345,7 @@ print_sep_string (void) + { + char const *s = col_sep_string; + int l = col_sep_length; ++ int not_space_flag; + + if (separators_not_printed <= 0) + { +@@ -2230,6 +2357,7 @@ print_sep_string (void) + { + for (; separators_not_printed > 0; --separators_not_printed) + { ++ not_space_flag = 0; + while (l-- > 0) + { + /* 3 types of sep_strings: spaces only, spaces and chars, +@@ -2243,12 +2371,15 @@ print_sep_string (void) + } + else + { ++ not_space_flag = 1; + if (spaces_not_printed > 0) + print_white_space (); + putchar (*s++); +- ++output_position; + } + } ++ if (not_space_flag) ++ output_position += col_sep_width; ++ + /* sep_string ends with some spaces */ + if (spaces_not_printed > 0) + print_white_space (); +@@ -2276,7 +2407,7 @@ print_clump (COLUMN *p, int n, char *clu + required number of tabs and spaces. */ + + static void +-print_char (char c) ++print_char_single (char c) + { + if (tabify_output) + { +@@ -2300,6 +2431,74 @@ print_char (char c) + putchar (c); + } + ++#ifdef HAVE_MBRTOWC ++static void ++print_char_multi (char c) ++{ ++ static size_t mbc_pos = 0; ++ static char mbc[MB_LEN_MAX] = {'\0'}; ++ static mbstate_t state = {'\0'}; ++ mbstate_t state_bak; ++ wchar_t wc; ++ size_t mblength; ++ int width; ++ ++ if (tabify_output) ++ { ++ state_bak = state; ++ mbc[mbc_pos++] = c; ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ while (mbc_pos > 0) ++ { ++ switch (mblength) ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return; ++ ++ case (size_t)-1: ++ state = state_bak; ++ ++output_position; ++ putchar (mbc[0]); ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); ++ --mbc_pos; ++ break; ++ ++ case 0: ++ mblength = 1; ++ ++ default: ++ if (wc == L' ') ++ { ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ --mbc_pos; ++ ++spaces_not_printed; ++ return; ++ } ++ else if (spaces_not_printed > 0) ++ print_white_space (); ++ ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ ++ if ((width = wcwidth (wc)) < 1) ++ { ++ if (wc == L'\b') ++ --output_position; ++ } ++ else ++ output_position += width; ++ ++ fwrite (mbc, sizeof(char), mblength, stdout); ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ } ++ return; ++ } ++ putchar (c); ++} ++#endif ++ + /* Skip to page PAGE before printing. + PAGE may be larger than total number of pages. */ + +@@ -2477,9 +2676,9 @@ read_line (COLUMN *p) + align_empty_cols = false; + } + +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2548,7 +2747,7 @@ print_stored (COLUMN *p) + COLUMN *q; + + int line = p->current_line++; +- char *first = &buff[line_vector[line]]; ++ unsigned char *first = &buff[line_vector[line]]; + /* FIXME + UMR: Uninitialized memory read: + * This is occurring while in: +@@ -2560,7 +2759,7 @@ print_stored (COLUMN *p) + xmalloc [xmalloc.c:94] + init_store_cols [pr.c:1648] + */ +- char *last = &buff[line_vector[line + 1]]; ++ unsigned char *last = &buff[line_vector[line + 1]]; + + pad_vertically = true; + +@@ -2580,9 +2779,9 @@ print_stored (COLUMN *p) + } + } + +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2595,8 +2794,8 @@ print_stored (COLUMN *p) + if (spaces_not_printed == 0) + { + output_position = p->start_position + end_vector[line]; +- if (p->start_position - col_sep_length == chars_per_margin) +- output_position -= col_sep_length; ++ if (p->start_position - col_sep_width == chars_per_margin) ++ output_position -= col_sep_width; + } + + return true; +@@ -2615,7 +2814,7 @@ print_stored (COLUMN *p) + number of characters is 1.) */ + + static int +-char_to_clump (char c) ++char_to_clump_single (char c) + { + unsigned char uc = c; + char *s = clump_buff; +@@ -2625,10 +2824,10 @@ char_to_clump (char c) + int chars; + int chars_per_c = 8; + +- if (c == input_tab_char) ++ if (c == input_tab_char[0]) + chars_per_c = chars_per_input_tab; + +- if (c == input_tab_char || c == '\t') ++ if (c == input_tab_char[0] || c == '\t') + { + width = TAB_WIDTH (chars_per_c, input_position); + +@@ -2709,6 +2908,164 @@ char_to_clump (char c) + return chars; + } + ++#ifdef HAVE_MBRTOWC ++static int ++char_to_clump_multi (char c) ++{ ++ static size_t mbc_pos = 0; ++ static char mbc[MB_LEN_MAX] = {'\0'}; ++ static mbstate_t state = {'\0'}; ++ mbstate_t state_bak; ++ wchar_t wc; ++ size_t mblength; ++ int wc_width; ++ register char *s = clump_buff; ++ register int i, j; ++ char esc_buff[4]; ++ int width; ++ int chars; ++ int chars_per_c = 8; ++ ++ state_bak = state; ++ mbc[mbc_pos++] = c; ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ width = 0; ++ chars = 0; ++ while (mbc_pos > 0) ++ { ++ switch (mblength) ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return 0; ++ ++ case (size_t)-1: ++ state = state_bak; ++ mblength = 1; ++ ++ if (use_esc_sequence || use_cntrl_prefix) ++ { ++ width = +4; ++ chars = +4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); ++ for (i = 0; i <= 2; ++i) ++ *s++ = (int) esc_buff[i]; ++ } ++ else ++ { ++ width += 1; ++ chars += 1; ++ *s++ = mbc[0]; ++ } ++ break; ++ ++ case 0: ++ mblength = 1; ++ /* Fall through */ ++ ++ default: ++ if (memcmp (mbc, input_tab_char, mblength) == 0) ++ chars_per_c = chars_per_input_tab; ++ ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') ++ { ++ int width_inc; ++ ++ width_inc = TAB_WIDTH (chars_per_c, input_position); ++ width += width_inc; ++ ++ if (untabify_input) ++ { ++ for (i = width_inc; i; --i) ++ *s++ = ' '; ++ chars += width_inc; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ chars += mblength; ++ } ++ } ++ else if ((wc_width = wcwidth (wc)) < 1) ++ { ++ if (use_esc_sequence) ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ else if (use_cntrl_prefix) ++ { ++ if (wc < 0200) ++ { ++ width += 2; ++ chars += 2; ++ *s++ = '^'; ++ *s++ = wc ^ 0100; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ } ++ else if (wc == L'\b') ++ { ++ width += -1; ++ chars += 1; ++ *s++ = c; ++ } ++ else ++ { ++ width += 0; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } ++ else ++ { ++ width += wc_width; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ ++ /* Too many backspaces must put us in position 0 -- never negative. */ ++ if (width < 0 && input_position == 0) ++ { ++ chars = 0; ++ input_position = 0; ++ } ++ else if (width < 0 && input_position <= -width) ++ input_position = 0; ++ else ++ input_position += width; ++ ++ return chars; ++} ++#endif ++ + /* We've just printed some files and need to clean up things before + looking for more options and printing the next batch of files. + +Index: src/sort.c +=================================================================== +--- src/sort.c.orig ++++ src/sort.c +@@ -29,6 +29,14 @@ + #include + #include + #include ++#if HAVE_WCHAR_H ++# include ++#endif ++/* Get isw* functions. */ ++#if HAVE_WCTYPE_H ++# include ++#endif ++ + #include "system.h" + #include "argmatch.h" + #include "die.h" +@@ -157,14 +165,39 @@ static int decimal_point; + /* Thousands separator; if -1, then there isn't one. */ + static int thousands_sep; + ++/* True if -f is specified. */ ++static bool folding; ++ + /* Nonzero if the corresponding locales are hard. */ + static bool hard_LC_COLLATE; +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + static bool hard_LC_TIME; + #endif + + #define NONZERO(x) ((x) != 0) + ++/* get a multibyte character's byte length. */ ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t wc; \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ STATE = state_bak; \ ++ /* Fall through. */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++ } \ ++ while (0) ++ + /* The kind of blanks for '-b' to skip in various options. */ + enum blanktype { bl_start, bl_end, bl_both }; + +@@ -338,13 +371,11 @@ static bool reverse; + they were read if all keys compare equal. */ + static bool stable; + +-/* If TAB has this value, blanks separate fields. */ +-enum { TAB_DEFAULT = CHAR_MAX + 1 }; +- +-/* Tab character separating fields. If TAB_DEFAULT, then fields are ++/* Tab character separating fields. If tab_length is 0, then fields are + separated by the empty string between a non-blank character and a blank + character. */ +-static int tab = TAB_DEFAULT; ++static char tab[MB_LEN_MAX + 1]; ++static size_t tab_length = 0; + + /* Flag to remove consecutive duplicate lines from the output. + Only the last of a sequence of equal lines will be output. */ +@@ -802,6 +833,46 @@ reap_all (void) + reap (-1); + } + ++/* Function pointers. */ ++static void ++(*inittables) (void); ++static char * ++(*begfield) (const struct line*, const struct keyfield *); ++static char * ++(*limfield) (const struct line*, const struct keyfield *); ++static void ++(*skipblanks) (char **ptr, char *lim); ++static int ++(*getmonth) (char const *, size_t, char **); ++static int ++(*keycompare) (const struct line *, const struct line *); ++static int ++(*numcompare) (const char *, const char *); ++ ++/* Test for white space multibyte character. ++ Set LENGTH the byte length of investigated multibyte character. */ ++#if HAVE_MBRTOWC ++static int ++ismbblank (const char *str, size_t len, size_t *length) ++{ ++ size_t mblength; ++ wchar_t wc; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ mblength = mbrtowc (&wc, str, len, &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ *length = 1; ++ return 0; ++ } ++ ++ *length = (mblength < 1) ? 1 : mblength; ++ return iswblank (wc) || wc == '\n'; ++} ++#endif ++ + /* Clean up any remaining temporary files. */ + + static void +@@ -1270,7 +1341,7 @@ zaptemp (char const *name) + free (node); + } + +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + + static int + struct_month_cmp (void const *m1, void const *m2) +@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void c + /* Initialize the character class tables. */ + + static void +-inittables (void) ++inittables_uni (void) + { + size_t i; + +@@ -1297,7 +1368,7 @@ inittables (void) + fold_toupper[i] = toupper (i); + } + +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + /* 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 con + xstrtol_fatal (e, oi, c, long_options, s); + } + ++#if HAVE_MBRTOWC ++static void ++inittables_mb (void) ++{ ++ int i, j, k, l; ++ char *name, *s, *lc_time, *lc_ctype; ++ size_t s_len, mblength; ++ char mbc[MB_LEN_MAX]; ++ wchar_t wc, pwc; ++ mbstate_t state_mb, state_wc; ++ ++ lc_time = setlocale (LC_TIME, ""); ++ if (lc_time) ++ lc_time = xstrdup (lc_time); ++ ++ lc_ctype = setlocale (LC_CTYPE, ""); ++ if (lc_ctype) ++ lc_ctype = xstrdup (lc_ctype); ++ ++ if (lc_time && lc_ctype) ++ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert ++ * the names of months to upper case */ ++ setlocale (LC_CTYPE, lc_time); ++ ++ for (i = 0; i < MONTHS_PER_YEAR; i++) ++ { ++ s = (char *) nl_langinfo (ABMON_1 + i); ++ s_len = strlen (s); ++ monthtab[i].name = name = (char *) xmalloc (s_len + 1); ++ monthtab[i].val = i + 1; ++ ++ memset (&state_mb, '\0', sizeof (mbstate_t)); ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ ++ for (j = 0; j < s_len;) ++ { ++ if (!ismbblank (s + j, s_len - j, &mblength)) ++ break; ++ j += mblength; ++ } ++ ++ for (k = 0; j < s_len;) ++ { ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); ++ if (mblength == 0) ++ break; ++ ++ pwc = towupper (wc); ++ if (pwc == wc) ++ { ++ memcpy (mbc, s + j, mblength); ++ j += mblength; ++ } ++ else ++ { ++ j += mblength; ++ mblength = wcrtomb (mbc, pwc, &state_wc); ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); ++ } ++ ++ for (l = 0; l < mblength; l++) ++ name[k++] = mbc[l]; ++ } ++ name[k] = '\0'; ++ } ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, ++ sizeof (struct month), struct_month_cmp); ++ ++ if (lc_time && lc_ctype) ++ /* restore the original locales */ ++ setlocale (LC_CTYPE, lc_ctype); ++ ++ free (lc_ctype); ++ free (lc_time); ++} ++#endif ++ + /* 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 + by KEY in LINE. */ + + static char * +-begfield (struct line const *line, struct keyfield const *key) ++begfield_uni (const struct line *line, const struct keyfield *key) + { + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t sword = key->sword; +@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struc + /* The leading field separator itself is included in a field when -t + is absent. */ + +- if (tab != TAB_DEFAULT) ++ if (tab_length) + while (ptr < lim && sword--) + { +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim) + ++ptr; +@@ -1648,11 +1797,70 @@ begfield (struct line const *line, struc + return ptr; + } + ++#if HAVE_MBRTOWC ++static char * ++begfield_mb (const struct line *line, const struct keyfield *key) ++{ ++ int i; ++ char *ptr = line->text, *lim = ptr + line->length - 1; ++ size_t sword = key->sword; ++ size_t schar = key->schar; ++ size_t mblength; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ if (tab_length) ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ } ++ else ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ } ++ ++ if (key->skipsblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ ++ for (i = 0; i < schar; i++) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ ++ return ptr; ++} ++#endif ++ + /* Return the limit of (a pointer to the first character after) the field + in LINE specified by KEY. */ + + static char * +-limfield (struct line const *line, struct keyfield const *key) ++limfield_uni (const struct line *line, const struct keyfield *key) + { + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t eword = key->eword, echar = key->echar; +@@ -1667,10 +1875,10 @@ limfield (struct line const *line, struc + 'beginning' is the first character following the delimiting TAB. + Otherwise, leave PTR pointing at the first 'blank' character after + the preceding field. */ +- if (tab != TAB_DEFAULT) ++ if (tab_length) + while (ptr < lim && eword--) + { +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim && (eword || echar)) + ++ptr; +@@ -1716,10 +1924,10 @@ limfield (struct line const *line, struc + */ + + /* Make LIM point to the end of (one byte past) the current field. */ +- if (tab != TAB_DEFAULT) ++ if (tab_length) + { + char *newlim; +- newlim = memchr (ptr, tab, lim - ptr); ++ newlim = memchr (ptr, tab[0], lim - ptr); + if (newlim) + lim = newlim; + } +@@ -1750,6 +1958,130 @@ limfield (struct line const *line, struc + return ptr; + } + ++#if HAVE_MBRTOWC ++static char * ++limfield_mb (const struct line *line, const struct keyfield *key) ++{ ++ char *ptr = line->text, *lim = ptr + line->length - 1; ++ size_t eword = key->eword, echar = key->echar; ++ int i; ++ size_t mblength; ++ mbstate_t state; ++ ++ if (echar == 0) ++ eword++; /* skip all of end field. */ ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ if (tab_length) ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim && (eword | echar)) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ } ++ else ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ } ++ ++ ++# ifdef POSIX_UNSPECIFIED ++ /* Make LIM point to the end of (one byte past) the current field. */ ++ if (tab_length) ++ { ++ char *newlim, *p; ++ ++ newlim = NULL; ++ for (p = ptr; p < lim;) ++ { ++ if (memcmp (p, tab, tab_length) == 0) ++ { ++ newlim = p; ++ break; ++ } ++ ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ p += mblength; ++ } ++ } ++ else ++ { ++ char *newlim; ++ newlim = ptr; ++ ++ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) ++ newlim += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) ++ newlim += mblength; ++ lim = newlim; ++ } ++# endif ++ ++ if (echar != 0) ++ { ++ /* If we're skipping leading blanks, don't start counting characters ++ * until after skipping past any leading blanks. */ ++ if (key->skipeblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ ++ for (i = 0; i < echar; i++) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ } ++ ++ return ptr; ++} ++#endif ++ ++static void ++skipblanks_uni (char **ptr, char *lim) ++{ ++ while (*ptr < lim && blanks[to_uchar (**ptr)]) ++ ++(*ptr); ++} ++ ++#if HAVE_MBRTOWC ++static void ++skipblanks_mb (char **ptr, char *lim) ++{ ++ size_t mblength; ++ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) ++ (*ptr) += mblength; ++} ++#endif ++ + /* 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 +@@ -1836,8 +2168,22 @@ fillbuf (struct buffer *buf, FILE *fp, c + else + { + if (key->skipsblanks) +- while (blanks[to_uchar (*line_start)]) +- line_start++; ++ { ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ while (line_start < line->keylim && ++ ismbblank (line_start, ++ line->keylim - line_start, ++ &mblength)) ++ line_start += mblength; ++ } ++ else ++#endif ++ while (blanks[to_uchar (*line_start)]) ++ line_start++; ++ } + line->keybeg = line_start; + } + } +@@ -1971,12 +2317,10 @@ find_unit_order (char const *number) + < K/k < M < G < T < P < E < Z < Y */ + + static int +-human_numcompare (char const *a, char const *b) ++human_numcompare (char *a, char *b) + { +- while (blanks[to_uchar (*a)]) +- a++; +- while (blanks[to_uchar (*b)]) +- b++; ++ skipblanks(&a, a + strlen(a)); ++ skipblanks(&b, b + strlen(b)); + + int diff = find_unit_order (a) - find_unit_order (b); + return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); +@@ -1987,7 +2331,7 @@ human_numcompare (char const *a, char co + hideously fast. */ + + static int +-numcompare (char const *a, char const *b) ++numcompare_uni (const char *a, const char *b) + { + while (blanks[to_uchar (*a)]) + a++; +@@ -1997,6 +2341,25 @@ numcompare (char const *a, char const *b + return strnumcmp (a, b, decimal_point, thousands_sep); + } + ++#if HAVE_MBRTOWC ++static int ++numcompare_mb (const char *a, const char *b) ++{ ++ size_t mblength, len; ++ len = strlen (a); /* okay for UTF-8 */ ++ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) ++ { ++ a += mblength; ++ len -= mblength; ++ } ++ len = strlen (b); /* okay for UTF-8 */ ++ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) ++ b += mblength; ++ ++ return strnumcmp (a, b, decimal_point, thousands_sep); ++} ++#endif /* HAV_EMBRTOWC */ ++ + /* Work around a problem whereby the long double value returned by glibc's + strtold ("NaN", ...) contains uninitialized bits: clear all bytes of + A and B before calling strtold. FIXME: remove this function if +@@ -2047,7 +2410,7 @@ general_numcompare (char const *sa, char + Return 0 if the name in S is not recognized. */ + + static int +-getmonth (char const *month, char **ea) ++getmonth_uni (char const *month, size_t len, char **ea) + { + size_t lo = 0; + size_t hi = MONTHS_PER_YEAR; +@@ -2323,15 +2686,14 @@ debug_key (struct line const *line, stru + char saved = *lim; + *lim = '\0'; + +- while (blanks[to_uchar (*beg)]) +- beg++; ++ skipblanks (&beg, lim); + + char *tighter_lim = beg; + + if (lim < beg) + tighter_lim = lim; + else if (key->month) +- getmonth (beg, &tighter_lim); ++ getmonth (beg, lim-beg, &tighter_lim); + else if (key->general_numeric) + ignore_value (strtold (beg, &tighter_lim)); + else if (key->numeric || key->human_numeric) +@@ -2465,7 +2827,7 @@ key_warnings (struct keyfield const *gke + /* 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 */ +- if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset ++ if (!zero_width && !gkey_only && !tab_length && !line_offset + && ((!key->skipsblanks && !implicit_skip) + || (!key->skipsblanks && key->schar) + || (!key->skipeblanks && key->echar))) +@@ -2523,11 +2885,87 @@ key_warnings (struct keyfield const *gke + error (0, 0, _("option '-r' only applies to last-resort comparison")); + } + ++#if HAVE_MBRTOWC ++static int ++getmonth_mb (const char *s, size_t len, char **ea) ++{ ++ char *month; ++ register size_t i; ++ register int lo = 0, hi = MONTHS_PER_YEAR, result; ++ char *tmp; ++ size_t wclength, mblength; ++ const char *pp; ++ const wchar_t *wpp; ++ wchar_t *month_wcs; ++ mbstate_t state; ++ ++ while (len > 0 && ismbblank (s, len, &mblength)) ++ { ++ s += mblength; ++ len -= mblength; ++ } ++ ++ if (len == 0) ++ return 0; ++ ++ if (SIZE_MAX - len < 1) ++ xalloc_die (); ++ ++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); ++ ++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); ++ memcpy (tmp, s, len); ++ tmp[len] = '\0'; ++ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); ++ memset (&state, '\0', sizeof (mbstate_t)); ++ ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); ++ if (wclength == (size_t)-1 || pp != NULL) ++ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); ++ ++ for (i = 0; i < wclength; i++) ++ { ++ month_wcs[i] = towupper(month_wcs[i]); ++ if (iswblank (month_wcs[i])) ++ { ++ month_wcs[i] = L'\0'; ++ break; ++ } ++ } ++ ++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); ++ assert (mblength != (-1) && wpp == NULL); ++ ++ do ++ { ++ int ix = (lo + hi) / 2; ++ ++ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) ++ hi = ix; ++ else ++ lo = ix; ++ } ++ while (hi - lo > 1); ++ ++ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) ++ ? monthtab[lo].val : 0); ++ ++ if (ea && result) ++ *ea = (char*) s + strlen (monthtab[lo].name); ++ ++ free (month); ++ free (tmp); ++ free (month_wcs); ++ ++ return result; ++} ++#endif ++ + /* Compare two lines A and B trying every key in sequence until there + are no more keys or a difference is found. */ + + static int +-keycompare (struct line const *a, struct line const *b) ++keycompare_uni (const struct line *a, const struct line *b) + { + struct keyfield *key = keylist; + +@@ -2612,7 +3050,7 @@ keycompare (struct line const *a, struct + else if (key->human_numeric) + diff = human_numcompare (ta, tb); + else if (key->month) +- diff = getmonth (ta, NULL) - getmonth (tb, NULL); ++ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); + else if (key->random) + diff = compare_random (ta, tlena, tb, tlenb); + else if (key->version) +@@ -2728,6 +3166,211 @@ keycompare (struct line const *a, struct + return key->reverse ? -diff : diff; + } + ++#if HAVE_MBRTOWC ++static int ++keycompare_mb (const struct line *a, const struct line *b) ++{ ++ struct keyfield *key = keylist; ++ ++ /* For the first iteration only, the key positions have been ++ precomputed for us. */ ++ char *texta = a->keybeg; ++ char *textb = b->keybeg; ++ char *lima = a->keylim; ++ char *limb = b->keylim; ++ ++ size_t mblength_a, mblength_b; ++ wchar_t wc_a, wc_b; ++ mbstate_t state_a, state_b; ++ ++ int diff = 0; ++ ++ memset (&state_a, '\0', sizeof(mbstate_t)); ++ memset (&state_b, '\0', sizeof(mbstate_t)); ++ /* Ignore keys with start after end. */ ++ if (a->keybeg - a->keylim > 0) ++ return 0; ++ ++ ++ /* Ignore and/or translate chars before comparing. */ ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t uwc; \ ++ char mbc[MB_LEN_MAX]; \ ++ mbstate_t state_wc; \ ++ \ ++ for (NEW_LEN = i = 0; i < LEN;) \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ ++ \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ ++ || MBLENGTH == 0) \ ++ { \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ ++ STATE = state_bak; \ ++ if (!ignore) \ ++ COPY[NEW_LEN++] = TEXT[i]; \ ++ i++; \ ++ continue; \ ++ } \ ++ \ ++ if (ignore) \ ++ { \ ++ if ((ignore == nonprinting && !iswprint (WC)) \ ++ || (ignore == nondictionary \ ++ && !iswalnum (WC) && !iswblank (WC))) \ ++ { \ ++ i += MBLENGTH; \ ++ continue; \ ++ } \ ++ } \ ++ \ ++ if (translate) \ ++ { \ ++ \ ++ uwc = towupper(WC); \ ++ if (WC == uwc) \ ++ { \ ++ memcpy (mbc, TEXT + i, MBLENGTH); \ ++ i += MBLENGTH; \ ++ } \ ++ else \ ++ { \ ++ i += MBLENGTH; \ ++ WC = uwc; \ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ ++ \ ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ ++ } \ ++ \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = mbc[j]; \ ++ } \ ++ else \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = TEXT[i++]; \ ++ } \ ++ COPY[NEW_LEN] = '\0'; \ ++ } \ ++ while (0) ++ ++ /* Actually compare the fields. */ ++ ++ for (;;) ++ { ++ /* Find the lengths. */ ++ size_t lena = lima <= texta ? 0 : lima - texta; ++ size_t lenb = limb <= textb ? 0 : limb - textb; ++ ++ char enda IF_LINT (= 0); ++ char endb IF_LINT (= 0); ++ ++ char const *translate = key->translate; ++ bool const *ignore = key->ignore; ++ ++ if (ignore || translate) ++ { ++ if (SIZE_MAX - lenb - 2 < lena) ++ xalloc_die (); ++ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); ++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; ++ size_t new_len_a, new_len_b; ++ size_t i, j; ++ ++ IGNORE_CHARS (new_len_a, lena, texta, copy_a, ++ wc_a, mblength_a, state_a); ++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, ++ wc_b, mblength_b, state_b); ++ texta = copy_a; textb = copy_b; ++ lena = new_len_a; lenb = new_len_b; ++ } ++ else ++ { ++ /* Use the keys in-place, temporarily null-terminated. */ ++ enda = texta[lena]; texta[lena] = '\0'; ++ endb = textb[lenb]; textb[lenb] = '\0'; ++ } ++ ++ if (key->random) ++ diff = compare_random (texta, lena, textb, lenb); ++ else if (key->numeric | key->general_numeric | key->human_numeric) ++ { ++ char savea = *lima, saveb = *limb; ++ ++ *lima = *limb = '\0'; ++ diff = (key->numeric ? numcompare (texta, textb) ++ : key->general_numeric ? general_numcompare (texta, textb) ++ : human_numcompare (texta, textb)); ++ *lima = savea, *limb = saveb; ++ } ++ else if (key->version) ++ diff = filevercmp (texta, textb); ++ else if (key->month) ++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ diff = 1; ++ else if (hard_LC_COLLATE && !folding) ++ { ++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); ++ } ++ else ++ { ++ diff = memcmp (texta, textb, MIN (lena, lenb)); ++ if (diff == 0) ++ diff = lena < lenb ? -1 : lena != lenb; ++ } ++ ++ if (ignore || translate) ++ free (texta); ++ else ++ { ++ texta[lena] = enda; ++ textb[lenb] = endb; ++ } ++ ++ if (diff) ++ goto not_equal; ++ ++ key = key->next; ++ if (! key) ++ break; ++ ++ /* Find the beginning and limit of the next field. */ ++ if (key->eword != -1) ++ lima = limfield (a, key), limb = limfield (b, key); ++ else ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; ++ ++ if (key->sword != -1) ++ texta = begfield (a, key), textb = begfield (b, key); ++ else ++ { ++ texta = a->text, textb = b->text; ++ if (key->skipsblanks) ++ { ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) ++ texta += mblength_a; ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) ++ textb += mblength_b; ++ } ++ } ++ } ++ ++not_equal: ++ if (key && key->reverse) ++ return -diff; ++ else ++ return diff; ++} ++#endif ++ + /* Compare two lines A and B, returning negative, zero, or positive + depending on whether A compares less than, equal to, or greater than B. */ + +@@ -2755,7 +3398,7 @@ compare (struct line const *a, struct li + diff = - NONZERO (blen); + else if (blen == 0) + diff = 1; +- else if (hard_LC_COLLATE) ++ else if (hard_LC_COLLATE && !folding) + { + /* xmemcoll0 is a performance enhancement as + it will not unconditionally write '\0' after the +@@ -4145,6 +4788,7 @@ set_ordering (char const *s, struct keyf + break; + case 'f': + key->translate = fold_toupper; ++ folding = true; + break; + case 'g': + key->general_numeric = true; +@@ -4224,7 +4868,7 @@ main (int argc, char **argv) + initialize_exit_failure (SORT_FAILURE); + + hard_LC_COLLATE = hard_locale (LC_COLLATE); +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + hard_LC_TIME = hard_locale (LC_TIME); + #endif + +@@ -4245,6 +4889,29 @@ main (int argc, char **argv) + thousands_sep = -1; + } + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ inittables = inittables_mb; ++ begfield = begfield_mb; ++ limfield = limfield_mb; ++ skipblanks = skipblanks_mb; ++ getmonth = getmonth_mb; ++ keycompare = keycompare_mb; ++ numcompare = numcompare_mb; ++ } ++ else ++#endif ++ { ++ inittables = inittables_uni; ++ begfield = begfield_uni; ++ limfield = limfield_uni; ++ skipblanks = skipblanks_uni; ++ getmonth = getmonth_uni; ++ keycompare = keycompare_uni; ++ numcompare = numcompare_uni; ++ } ++ + have_read_stdin = false; + inittables (); + +@@ -4519,13 +5186,34 @@ main (int argc, char **argv) + + case 't': + { +- char newtab = optarg[0]; +- if (! newtab) ++ char newtab[MB_LEN_MAX + 1]; ++ size_t newtab_length = 1; ++ strncpy (newtab, optarg, MB_LEN_MAX); ++ if (! newtab[0]) + die (SORT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ wchar_t wc; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, ++ MB_LEN_MAX), ++ &state); ++ switch (newtab_length) ++ { ++ case (size_t) -1: ++ case (size_t) -2: ++ case 0: ++ newtab_length = 1; ++ } ++ } ++#endif ++ if (newtab_length == 1 && optarg[1]) + { + if (STREQ (optarg, "\\0")) +- newtab = '\0'; ++ newtab[0] = '\0'; + else + { + /* Provoke with 'sort -txx'. Complain about +@@ -4536,9 +5224,11 @@ main (int argc, char **argv) + quote (optarg)); + } + } +- if (tab != TAB_DEFAULT && tab != newtab) ++ if (tab_length && (tab_length != newtab_length ++ || memcmp (tab, newtab, tab_length) != 0)) + die (SORT_FAILURE, 0, _("incompatible tabs")); +- tab = newtab; ++ memcpy (tab, newtab, newtab_length); ++ tab_length = newtab_length; + } + break; + +@@ -4767,12 +5457,10 @@ main (int argc, char **argv) + sort (files, nfiles, outfile, nthreads); + } + +-#ifdef lint + if (files_from) + readtokens0_free (&tok); + else + free (files); +-#endif + + if (have_read_stdin && fclose (stdin) == EOF) + sort_die (_("close failed"), "-"); +Index: src/unexpand.c +=================================================================== +--- src/unexpand.c.orig ++++ src/unexpand.c +@@ -38,6 +38,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + #include "xstrndup.h" +@@ -107,24 +110,47 @@ unexpand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; + + /* The array of pending blanks. In non-POSIX locales, blanks can + include characters other than spaces, so the blanks must be + stored, not merely counted. */ +- char *pending_blank; ++ mbf_char_t *pending_blank; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; ++ ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); + + 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")); ++ } ++ } + /* 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)); ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + + while (true) + { + /* Input character, or EOF. */ +- int c; ++ mbf_char_t c; + + /* If true, perform translations. */ + bool convert = true; +@@ -158,12 +184,44 @@ unexpand (void) + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ *all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- bool blank = !! isblank (c); ++ bool blank = mb_isblank (c); + + if (blank) + { +@@ -180,16 +238,16 @@ unexpand (void) + if (next_tab_column < column) + die (EXIT_FAILURE, 0, _("input line is too long")); + +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + column = next_tab_column; + + if (pending) +- pending_blank[0] = '\t'; ++ mb_setascii (&pending_blank[0], '\t'); + } + else + { +- column++; ++ column += mb_width (c); + + if (! (prev_blank && column == next_tab_column)) + { +@@ -197,13 +255,14 @@ unexpand (void) + will be replaced by tabs. */ + if (column == next_tab_column) + one_blank_before_tab_stop = true; +- pending_blank[pending++] = c; ++ mb_copy (&pending_blank[pending++], &c); + prev_blank = true; + continue; + } + + /* Replace the pending blanks by a tab or two. */ +- pending_blank[0] = c = '\t'; ++ mb_setascii (&c, '\t'); ++ mb_setascii (&pending_blank[0], '\t'); + } + + /* Discard pending blanks, unless it was a single +@@ -211,7 +270,7 @@ unexpand (void) + pending = one_blank_before_tab_stop; + } + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ +@@ -219,9 +278,9 @@ unexpand (void) + next_tab_column = column; + tab_index -= !!tab_index; + } +- else ++ else if (!mb_iseq (c, '\n')) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } +@@ -229,8 +288,11 @@ unexpand (void) + if (pending) + { + if (pending > 1 && one_blank_before_tab_stop) +- pending_blank[0] = '\t'; +- if (fwrite (pending_blank, 1, pending, stdout) != pending) ++ mb_setascii (&pending_blank[0], '\t'); ++ ++ for (int n = 0; n < pending; ++n) ++ mb_putc (pending_blank[n], stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + pending = 0; + one_blank_before_tab_stop = false; +@@ -240,16 +302,17 @@ unexpand (void) + convert &= convert_entire_line || blank; + } + +- if (c < 0) ++ if (mb_iseof (c)) + { + free (pending_blank); + return; + } + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } + +Index: src/uniq.c +=================================================================== +--- src/uniq.c.orig ++++ 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" +@@ -33,6 +44,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" + +@@ -139,6 +162,10 @@ enum + GROUP_OPTION = CHAR_MAX + 1 + }; + ++/* Function pointers. */ ++static char * ++(*find_field) (struct linebuffer *line); ++ + static struct option const longopts[] = + { + {"count", no_argument, NULL, 'c'}, +@@ -253,7 +280,7 @@ size_opt (char const *opt, char const *m + return a pointer to the beginning of the line's field to be compared. */ + + static char * _GL_ATTRIBUTE_PURE +-find_field (struct linebuffer const *line) ++find_field_uni (struct linebuffer *line) + { + size_t count; + char const *lp = line->buffer; +@@ -273,6 +300,83 @@ find_field (struct linebuffer const *lin + 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. +@@ -493,6 +597,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; +Index: tests/expand/mb.sh +=================================================================== +--- /dev/null ++++ tests/expand/mb.sh +@@ -0,0 +1,183 @@ ++#!/bin/sh ++ ++# Copyright (C) 2012-2015 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_ expand ++ ++export LC_ALL=en_US.UTF-8 ++ ++#input containing multibyte characters ++cat <<\EOF > in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++cat <<\EOF > exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#multiple files as an input ++cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with display widths != 1 ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#shouldn't fail with "input line too long" ++#when a line starts with a control character ++env printf '\n' > in || framework_failure_ ++ ++expand < in > out || fail=1 ++compare in out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > in || framework_failure_ ++ ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ ++ ++ ++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++exit $fail +Index: tests/i18n/sort.sh +=================================================================== +--- /dev/null ++++ tests/i18n/sort.sh +@@ -0,0 +1,29 @@ ++#!/bin/sh ++# Verify sort's multi-byte support. ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++ ++export LC_ALL=en_US.UTF-8 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ ++ || skip_ "No UTF-8 locale available" ++ ++# Enable heap consistency checkng on older systems ++export MALLOC_CHECK_=2 ++ ++ ++# check buffer overflow issue due to ++# expanding multi-byte representation due to case conversion ++# https://bugzilla.suse.com/show_bug.cgi?id=928749 ++cat < exp ++. ++ɑ ++EOF ++cat < out || fail=1 ++. ++ɑ ++EOF ++compare exp out || { fail=1; cat out; } ++ ++ ++Exit $fail +Index: tests/local.mk +=================================================================== +--- tests/local.mk.orig ++++ tests/local.mk +@@ -369,6 +369,8 @@ all_tests = \ + tests/misc/sort-discrim.sh \ + tests/misc/sort-files0-from.pl \ + tests/misc/sort-float.sh \ ++ tests/misc/sort-mb-tests.sh \ ++ tests/i18n/sort.sh \ + tests/misc/sort-h-thousands-sep.sh \ + tests/misc/sort-merge.pl \ + tests/misc/sort-merge-fdlimit.sh \ +@@ -567,6 +569,7 @@ all_tests = \ + tests/du/threshold.sh \ + tests/du/trailing-slash.sh \ + tests/du/two-args.sh \ ++ tests/expand/mb.sh \ + tests/id/gnu-zero-uids.sh \ + tests/id/no-context.sh \ + tests/id/context.sh \ +@@ -714,6 +717,7 @@ all_tests = \ + tests/touch/read-only.sh \ + tests/touch/relative.sh \ + tests/touch/trailing-slash.sh \ ++ tests/unexpand/mb.sh \ + $(all_root_tests) + + # See tests/factor/create-test.sh. +Index: tests/misc/expand.pl +=================================================================== +--- tests/misc/expand.pl.orig ++++ tests/misc/expand.pl +@@ -27,6 +27,15 @@ my $prog = 'expand'; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++#comment out next line to disable multibyte tests ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $prog = 'expand'; ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + my @Tests = + ( + ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], +@@ -168,6 +177,8 @@ my @Tests = + + + # Test errors ++ # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES ++ # So we force LC_MESSAGES=C to make them pass. + ['e1', '--tabs="a"', {IN=>''}, {OUT=>''}, {EXIT=>1}, + {ERR => "$prog: tab size contains invalid character(s): 'a'\n"}], + ['e2', "-t $UINTMAX_OFLOW", {IN=>''}, {OUT=>''}, {EXIT=>1}, +@@ -184,6 +195,37 @@ my @Tests = + {ERR => "$prog: '/' specifier not at start of number: '/'\n"}], + ); + ++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 expand 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 => "LANG=$mb_locale LC_MESSAGES=C"}]; ++ } ++ push @Tests, @new; ++ } ++ ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +Index: tests/misc/fold.pl +=================================================================== +--- tests/misc/fold.pl.orig ++++ tests/misc/fold.pl +@@ -20,9 +20,18 @@ 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; + ++# 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"}], + ); + ++# 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}; + +-my $prog = 'fold'; + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); + exit $fail; +Index: tests/misc/join.pl +=================================================================== +--- tests/misc/join.pl.orig ++++ 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}; + +Index: tests/misc/sort-mb-tests.sh +=================================================================== +--- /dev/null ++++ tests/misc/sort-mb-tests.sh +@@ -0,0 +1,45 @@ ++#!/bin/sh ++# Verify sort's multi-byte support. ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++ ++export LC_ALL=en_US.UTF-8 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ ++ || skip_ "No UTF-8 locale available" ++ ++ ++cat < exp ++Banana@5 ++Apple@10 ++Citrus@20 ++Cherry@30 ++EOF ++ ++cat < out || fail=1 ++Apple@10 ++Banana@5 ++Citrus@20 ++Cherry@30 ++EOF ++ ++compare exp out || { fail=1; cat out; } ++ ++ ++cat < exp ++Citrus@AA20@@5 ++Cherry@AA30@@10 ++Apple@AA10@@20 ++Banana@AA5@@30 ++EOF ++ ++cat < out || fail=1 ++Apple@AA10@@20 ++Banana@AA5@@30 ++Citrus@AA20@@5 ++Cherry@AA30@@10 ++EOF ++ ++compare exp out || { fail=1; cat out; } ++ ++Exit $fail +Index: tests/misc/sort-merge.pl +=================================================================== +--- tests/misc/sort-merge.pl.orig ++++ tests/misc/sort-merge.pl +@@ -26,6 +26,15 @@ my $prog = 'sort'; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++my $mb_locale; ++# uncommented according to upstream commit enabling multibyte paths ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + # three empty files and one that says 'foo' + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); + +@@ -77,6 +86,39 @@ my @Tests = + {OUT=>$big_input}], + ); + ++# 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 sort 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; ++ } ++ next if ($test_name =~ "nmerge-."); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +Index: tests/misc/sort.pl +=================================================================== +--- tests/misc/sort.pl.orig ++++ tests/misc/sort.pl +@@ -24,10 +24,15 @@ my $prog = 'sort'; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++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 $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + # 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) + } + } + ++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 sort 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; ++ } ++ #disable several failing tests until investigation, disable all tests with envvars set ++ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); ++ next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a"); ++ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. ++ 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" +@@ -432,6 +469,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; ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; + + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; +Index: tests/misc/unexpand.pl +=================================================================== +--- tests/misc/unexpand.pl.orig ++++ tests/misc/unexpand.pl +@@ -27,6 +27,14 @@ my $limits = getlimits (); + + my $prog = 'unexpand'; + ++# comment out next line to disable multibyte tests ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + my @Tests = + ( + ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], +@@ -128,6 +136,37 @@ my @Tests = + ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], + ); + ++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 unexpand 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; ++ } ++ next if ($test_name =~ 'b-1'); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +Index: tests/misc/uniq.pl +=================================================================== +--- tests/misc/uniq.pl.orig ++++ tests/misc/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; + +Index: tests/pr/pr-tests.pl +=================================================================== +--- tests/pr/pr-tests.pl.orig ++++ tests/pr/pr-tests.pl +@@ -24,6 +24,15 @@ use strict; + my $prog = 'pr'; + my $normalize_strerror = "s/': .*/'/"; + ++my $mb_locale; ++#Uncomment the following line to enable multibyte tests ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + my @tv = ( + + # -b option is no longer an official option. But it's still working to +@@ -474,8 +483,48 @@ push @Tests, + {IN=>{2=>"a\n"}}, + {OUT=>"a\t\t\t\t \t\t\ta\n"} ]; + ++# 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 pr 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; ++ } ++ #temporarily skip some failing tests ++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1"); ++ 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}; + +Index: tests/unexpand/mb.sh +=================================================================== +--- /dev/null ++++ tests/unexpand/mb.sh +@@ -0,0 +1,172 @@ ++#!/bin/sh ++ ++# Copyright (C) 2012-2015 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_ unexpand ++ ++export LC_ALL=en_US.UTF-8 ++ ++#input containing multibyte characters ++cat > in <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++cat > exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++#multiple files as an input ++cat >> exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand -a ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with a display width larger than 1 ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test input where a blank of width > 1 is not being substituted ++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" ++exp='   ö ü ß' ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > in || framework_failure_ ++ ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 diff --git a/coreutils-invalid-ids.patch b/coreutils-invalid-ids.patch new file mode 100644 index 0000000..99c0438 --- /dev/null +++ b/coreutils-invalid-ids.patch @@ -0,0 +1,30 @@ +While uid_t and gid_t are both unsigned, the values (uid_t) -1 and +(gid_t) -1 are reserved. A uid or gid argument of -1 to the chown(2) +system call means to leave the uid/gid unchanged. Catch this case +so that trying to set a uid or gid to -1 will result in an error. + +Test cases: + + chown 4294967295 file + chown :4294967295 file + chgrp 4294967295 file + +Andreas Gruenbacher + +--- + src/chgrp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: src/chgrp.c +=================================================================== +--- src/chgrp.c.orig ++++ src/chgrp.c +@@ -89,7 +89,7 @@ parse_group (const char *name) + { + uintmax_t tmp; + if (! (xstrtoumax (name, NULL, 10, &tmp, "") == LONGINT_OK +- && tmp <= GID_T_MAX)) ++ && tmp <= GID_T_MAX && (gid_t) tmp != (gid_t) -1)) + die (EXIT_FAILURE, 0, _("invalid group: %s"), + quote (name)); + gid = tmp; diff --git a/coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch b/coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch new file mode 100644 index 0000000..701df04 --- /dev/null +++ b/coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch @@ -0,0 +1,156 @@ +Upstream commits (squashed) after the release of coreutils-8.32: + [PATCH 1/2] ls: restore 8.31 behavior on removed directories + [PATCH 2/2] ls: improve removed-directory test +Remove this patch with the next coreutils release. + +Discussed at: + https://lists.gnu.org/archive/html/bug-coreutils/2020-03/msg00008.html + +Upstream commits: + https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=10fcb97 + https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=672819c + +commit 672819c73f2e94e61386dc0584bddf9da860cc26 (HEAD -> master, origin/master, origin/HEAD) +Author: Paul Eggert +Date: Sat Mar 7 10:29:51 2020 -0800 + + ls: improve removed-directory test + + * tests/ls/removed-directory.sh: Remove host_triplet test. + Skip this test if one cannot remove the working directory. + From a suggestion by Bernhard Voelker (Bug#39929). + +commit 10fcb97bd728f09d4a027eddf8ad2900f0819b0a +Author: Paul Eggert +Date: Thu Mar 5 17:25:29 2020 -0800 + + ls: restore 8.31 behavior on removed directories + + * NEWS: Mention this. + * src/ls.c: Do not include + (print_dir): Don't worry about whether the directory is removed. + * tests/ls/removed-directory.sh: Adjust to match new (i.e., old) + behavior. +--- + NEWS | 9 +++++++++ + src/ls.c | 22 ---------------------- + tests/ls/removed-directory.sh | 23 ++++++----------------- + 3 files changed, 15 insertions(+), 39 deletions(-) + +Index: NEWS +=================================================================== +--- NEWS.orig ++++ NEWS +@@ -1,5 +1,14 @@ + GNU coreutils NEWS -*- outline -*- + ++* Noteworthy downstream changes (on top of upstream coreutils-8.32) ++ ++** Changes in behavior ++ ++ On GNU/Linux systems, ls no longer issues an error message on ++ directory merely because it was removed. This reverts a change ++ that was made in release 8.32. ++ ++ + * Noteworthy changes in release 8.32 (2020-03-05) [stable] + + ** Bug fixes +Index: src/ls.c +=================================================================== +--- src/ls.c.orig ++++ src/ls.c +@@ -49,10 +49,6 @@ + # include + #endif + +-#ifdef __linux__ +-# include +-#endif +- + #include + #include + #include +@@ -2896,7 +2892,6 @@ print_dir (char const *name, char const + struct dirent *next; + uintmax_t total_blocks = 0; + static bool first = true; +- bool found_any_entries = false; + + errno = 0; + dirp = opendir (name); +@@ -2972,7 +2967,6 @@ print_dir (char const *name, char const + next = readdir (dirp); + if (next) + { +- found_any_entries = true; + if (! file_ignored (next->d_name)) + { + enum filetype type = unknown; +@@ -3018,22 +3012,6 @@ print_dir (char const *name, char const + if (errno != EOVERFLOW) + break; + } +-#ifdef __linux__ +- else if (! found_any_entries) +- { +- /* If readdir finds no directory entries at all, not even "." or +- "..", then double check that the directory exists. */ +- if (syscall (SYS_getdents, dirfd (dirp), NULL, 0) == -1 +- && errno != EINVAL) +- { +- /* We exclude EINVAL as that pertains to buffer handling, +- and we've passed NULL as the buffer for simplicity. +- ENOENT is returned if appropriate before buffer handling. */ +- file_failure (command_line_arg, _("reading directory %s"), name); +- } +- break; +- } +-#endif + else + break; + +Index: tests/ls/removed-directory.sh +=================================================================== +--- tests/ls/removed-directory.sh.orig ++++ tests/ls/removed-directory.sh +@@ -1,7 +1,7 @@ + #!/bin/sh +-# If ls is asked to list a removed directory (e.g. the parent process's +-# current working directory that has been removed by another process), it +-# emits an error message. ++# If ls is asked to list a removed directory (e.g., the parent process's ++# current working directory has been removed by another process), it ++# should not emit an error message merely because the directory is removed. + + # Copyright (C) 2020 Free Software Foundation, Inc. + +@@ -21,25 +21,14 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ ls + +-case $host_triplet in +- *linux*) ;; +- *) skip_ 'non linux kernel' ;; +-esac +- +-LS_FAILURE=2 +- +-cat <<\EOF >exp-err || framework_failure_ +-ls: reading directory '.': No such file or directory +-EOF +- + cwd=$(pwd) + mkdir d || framework_failure_ + cd d || framework_failure_ +-rmdir ../d || framework_failure_ ++rmdir ../d || skip_ "can't remove working directory on this platform" + +-returns_ $LS_FAILURE ls >../out 2>../err || fail=1 ++ls >../out 2>../err || fail=1 + cd "$cwd" || framework_failure_ + compare /dev/null out || fail=1 +-compare exp-err err || fail=1 ++compare /dev/null err || fail=1 + + Exit $fail diff --git a/coreutils-misc.patch b/coreutils-misc.patch new file mode 100644 index 0000000..126a478 --- /dev/null +++ b/coreutils-misc.patch @@ -0,0 +1,61 @@ +--- + gnulib-tests/test-isnanl.h | 5 +++-- + tests/misc/help-version.sh | 1 + + tests/other-fs-tmpdir | 3 +++ + 3 files changed, 7 insertions(+), 2 deletions(-) + +Index: gnulib-tests/test-isnanl.h +=================================================================== +--- gnulib-tests/test-isnanl.h.orig ++++ gnulib-tests/test-isnanl.h +@@ -47,7 +47,7 @@ main () + /* Quiet NaN. */ + ASSERT (isnanl (NaNl ())); + +-#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT ++#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT && 0 + /* A bit pattern that is different from a Quiet NaN. With a bit of luck, + it's a Signalling NaN. */ + { +@@ -98,6 +98,7 @@ main () + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + ASSERT (isnanl (x.value)); + } ++#if 0 + /* isnanl should return something for noncanonical values. */ + { /* Pseudo-NaN. */ + static memory_long_double x = +@@ -125,6 +126,6 @@ main () + ASSERT (isnanl (x.value) || !isnanl (x.value)); + } + #endif +- ++#endif + return 0; + } +Index: tests/misc/help-version.sh +=================================================================== +--- tests/misc/help-version.sh.orig ++++ tests/misc/help-version.sh +@@ -239,6 +239,7 @@ parted_setup () { args="-s $tmp_in mklab + for i in $built_programs; do + # Skip these. + case $i in chroot|stty|tty|false|chcon|runcon|coreutils) continue;; esac ++ case $i in df) continue;; esac + + rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out $bigZ_in $zin $zin2 + echo z |gzip > $zin +Index: tests/other-fs-tmpdir +=================================================================== +--- tests/other-fs-tmpdir.orig ++++ tests/other-fs-tmpdir +@@ -43,6 +43,9 @@ for d in $CANDIDATE_TMP_DIRS; do + + done + ++# Autobuild hack ++test -f /bin/uname.bin && other_partition_tmpdir= ++ + if test -z "$other_partition_tmpdir"; then + skip_ \ + "requires a writable directory on a different disk partition, diff --git a/coreutils-remove_hostname_documentation.patch b/coreutils-remove_hostname_documentation.patch new file mode 100644 index 0000000..d888cf3 --- /dev/null +++ b/coreutils-remove_hostname_documentation.patch @@ -0,0 +1,92 @@ +--- + doc/coreutils.texi | 42 +----------------------------------------- + 1 file changed, 1 insertion(+), 41 deletions(-) + +Index: doc/coreutils.texi +=================================================================== +--- doc/coreutils.texi.orig ++++ doc/coreutils.texi +@@ -71,7 +71,6 @@ + * groups: (coreutils)groups invocation. Print group names a user is in. + * head: (coreutils)head invocation. Output the first part of files. + * hostid: (coreutils)hostid invocation. Print numeric host identifier. +-* hostname: (coreutils)hostname invocation. Print or set system name. + * id: (coreutils)id invocation. Print user identity. + * install: (coreutils)install invocation. Copy files and set attributes. + * join: (coreutils)join invocation. Join lines on a common field. +@@ -203,7 +202,7 @@ Free Documentation License''. + * File name manipulation:: dirname basename pathchk mktemp realpath + * Working context:: pwd stty printenv tty + * User information:: id logname whoami groups users who +-* System context:: date arch nproc uname hostname hostid uptime ++* System context:: date arch nproc uname hostid uptime + * SELinux context:: chcon runcon + * Modified command invocation:: chroot env nice nohup stdbuf timeout + * Process control:: kill +@@ -426,7 +425,6 @@ System context + * date invocation:: Print or set system date and time + * nproc invocation:: Print the number of processors + * uname invocation:: Print system information +-* hostname invocation:: Print or set system name + * hostid invocation:: Print numeric host identifier + * uptime invocation:: Print system uptime and load + +@@ -15761,7 +15759,6 @@ information. + * arch invocation:: Print machine hardware name. + * nproc invocation:: Print the number of processors. + * uname invocation:: Print system information. +-* hostname invocation:: Print or set system name. + * hostid invocation:: Print numeric host identifier. + * uptime invocation:: Print system uptime and load. + @end menu +@@ -16623,15 +16620,6 @@ Note this is non-portable (even across G + Print the machine hardware name (sometimes called the hardware class + or hardware type). + +-@item -n +-@itemx --nodename +-@opindex -n +-@opindex --nodename +-@cindex hostname +-@cindex node name +-@cindex network node name +-Print the network node hostname. +- + @item -p + @itemx --processor + @opindex -p +@@ -16685,34 +16673,6 @@ Print the kernel version. + + @exitstatus + +- +-@node hostname invocation +-@section @command{hostname}: Print or set system name +- +-@pindex hostname +-@cindex setting the hostname +-@cindex printing the hostname +-@cindex system name, printing +-@cindex appropriate privileges +- +-With no arguments, @command{hostname} prints the name of the current host +-system. With one argument, it sets the current host name to the +-specified string. You must have appropriate privileges to set the host +-name. Synopsis: +- +-@example +-hostname [@var{name}] +-@end example +- +-The only options are @option{--help} and @option{--version}. @xref{Common +-options}. +- +-@command{hostname} is not installed by default, and other packages +-also supply a @command{hostname} command, so portable scripts should +-not rely on its existence or on the exact behavior documented above. +- +-@exitstatus +- + + @node hostid invocation + @section @command{hostid}: Print numeric host identifier diff --git a/coreutils-remove_kill_documentation.patch b/coreutils-remove_kill_documentation.patch new file mode 100644 index 0000000..36049a0 --- /dev/null +++ b/coreutils-remove_kill_documentation.patch @@ -0,0 +1,126 @@ +--- + doc/coreutils.texi | 90 ----------------------------------------------------- + 1 file changed, 90 deletions(-) + +Index: doc/coreutils.texi +=================================================================== +--- doc/coreutils.texi.orig ++++ doc/coreutils.texi +@@ -74,7 +74,6 @@ + * id: (coreutils)id invocation. Print user identity. + * install: (coreutils)install invocation. Copy files and set attributes. + * join: (coreutils)join invocation. Join lines on a common field. +-* kill: (coreutils)kill invocation. Send a signal to processes. + * link: (coreutils)link invocation. Make hard links between files. + * ln: (coreutils)ln invocation. Make links between files. + * logname: (coreutils)logname invocation. Print current login name. +@@ -205,7 +204,6 @@ Free Documentation License''. + * System context:: date arch nproc uname hostid uptime + * SELinux context:: chcon runcon + * Modified command invocation:: chroot env nice nohup stdbuf timeout +-* Process control:: kill + * Delaying:: sleep + * Numeric operations:: factor numfmt seq + * File permissions:: Access modes +@@ -453,10 +451,6 @@ Modified command invocation + * stdbuf invocation:: Run a command with modified I/O buffering + * timeout invocation:: Run a command with a time limit + +-Process control +- +-* kill invocation:: Sending a signal to processes. +- + Delaying + + * sleep invocation:: Delay for a specified time +@@ -18089,90 +18083,6 @@ the exit status of @var{command} otherwi + @end display + + +-@node Process control +-@chapter Process control +- +-@cindex processes, commands for controlling +-@cindex commands for controlling processes +- +-@menu +-* kill invocation:: Sending a signal to processes. +-@end menu +- +- +-@node kill invocation +-@section @command{kill}: Send a signal to processes +- +-@pindex kill +-@cindex send a signal to processes +- +-The @command{kill} command sends a signal to processes, causing them +-to terminate or otherwise act upon receiving the signal in some way. +-Alternatively, it lists information about signals. Synopses: +- +-@example +-kill [-s @var{signal} | --signal @var{signal} | -@var{signal}] @var{pid}@dots{} +-kill [-l | --list | -t | --table] [@var{signal}]@dots{} +-@end example +- +-@mayConflictWithShellBuiltIn{kill} +- +-The first form of the @command{kill} command sends a signal to all +-@var{pid} arguments. The default signal to send if none is specified +-is @samp{TERM}@. The special signal number @samp{0} does not denote a +-valid signal, but can be used to test whether the @var{pid} arguments +-specify processes to which a signal could be sent. +- +-If @var{pid} is positive, the signal is sent to the process with the +-process ID @var{pid}. If @var{pid} is zero, the signal is sent to all +-processes in the process group of the current process. If @var{pid} +-is @minus{}1, the signal is sent to all processes for which the user has +-permission to send a signal. If @var{pid} is less than @minus{}1, the signal +-is sent to all processes in the process group that equals the absolute +-value of @var{pid}. +- +-If @var{pid} is not positive, a system-dependent set of system +-processes is excluded from the list of processes to which the signal +-is sent. +- +-If a negative @var{pid} argument is desired as the first one, it +-should be preceded by @option{--}. However, as a common extension to +-POSIX, @option{--} is not required with @samp{kill +--@var{signal} -@var{pid}}. The following commands are equivalent: +- +-@example +-kill -15 -1 +-kill -TERM -1 +-kill -s TERM -- -1 +-kill -- -1 +-@end example +- +-The first form of the @command{kill} command succeeds if every @var{pid} +-argument specifies at least one process that the signal was sent to. +- +-The second form of the @command{kill} command lists signal information. +-Either the @option{-l} or @option{--list} option, or the @option{-t} +-or @option{--table} option must be specified. Without any +-@var{signal} argument, all supported signals are listed. The output +-of @option{-l} or @option{--list} is a list of the signal names, one +-per line; if @var{signal} is already a name, the signal number is +-printed instead. The output of @option{-t} or @option{--table} is a +-table of signal numbers, names, and descriptions. This form of the +-@command{kill} command succeeds if all @var{signal} arguments are valid +-and if there is no output error. +- +-The @command{kill} command also supports the @option{--help} and +-@option{--version} options. @xref{Common options}. +- +-A @var{signal} may be a signal name like @samp{HUP}, or a signal +-number like @samp{1}, or an exit status of a process terminated by the +-signal. A signal name can be given in canonical form or prefixed by +-@samp{SIG}@. The case of the letters is ignored, except for the +-@option{-@var{signal}} option which must use upper case to avoid +-ambiguity with lower case option letters. +-@xref{Signal specifications}, for a list of supported +-signal names and numbers. +- + @node Delaying + @chapter Delaying + diff --git a/coreutils-skip-gnulib-test-tls.patch b/coreutils-skip-gnulib-test-tls.patch new file mode 100644 index 0000000..6eba5ff --- /dev/null +++ b/coreutils-skip-gnulib-test-tls.patch @@ -0,0 +1,37 @@ +Subject: Skip the gnulib test 'test-tls' on some platforms + +On i586, x86_64, ppc and ppc64, this test is known to sometimes fail +with a diagnostic like: + + Starting test_tls ...*** Error in `./test-tls': free(): invalid pointer: 0x00007f21500008c0 *** + ======= Backtrace: ========= + /lib64/libc.so.6(+0x7406f)[0x7f215845006f] + /lib64/libc.so.6(+0x7989e)[0x7f215845589e] + /lib64/libpthread.so.0(+0x7ee2)[0x7f215878fee2] + /lib64/libpthread.so.0(+0x813e)[0x7f215879013e] + /lib64/libc.so.6(clone+0x6d)[0x7f21584c3d6d] + +* gnulib-tests/gnulib.mk (test-tls): Comment to skip for now. + +--- + gnulib-tests/gnulib.mk | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +Index: gnulib-tests/gnulib.mk +=================================================================== +--- gnulib-tests/gnulib.mk.orig ++++ gnulib-tests/gnulib.mk +@@ -2485,9 +2485,10 @@ EXTRA_DIST += test-timespec.c macros.h + + ## begin gnulib module tls-tests + +-TESTS += test-tls +-check_PROGRAMS += test-tls +-test_tls_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ ++# Fails on i586 and x86_64. ++#TESTS += test-tls ++#check_PROGRAMS += test-tls ++#test_tls_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ + + EXTRA_DIST += test-tls.c + diff --git a/coreutils-skip-some-sort-tests-on-ppc.patch b/coreutils-skip-some-sort-tests-on-ppc.patch new file mode 100644 index 0000000..525b937 --- /dev/null +++ b/coreutils-skip-some-sort-tests-on-ppc.patch @@ -0,0 +1,52 @@ +Subject: tests: skip some valgrind-ed tests of sort on ppc/ppc64 + +Valgrind diagnoses problems in 'mkstemp64' deep down in glibc on PowerPC: + + Conditional jump or move depends on uninitialised value(s) + at 0xFDB37DC: __udivmoddi4 (in /lib/libc-2.18.90.so) + by 0xFDB3DD7: __umoddi3@GLIBC_2.0 (in /lib/libc-2.18.90.so) + by 0xFDFDF9F: __gen_tempname (in /lib/libc-2.18.90.so) + by 0xFE77563: mkstemp64 (in /lib/libc-2.18.90.so) + by 0x100135D3: mkstemp_safer (mkstemp-safer.c:33) + by 0x10006ECF: create_temp_file (sort.c:942) + by 0x1000A427: maybe_create_temp (sort.c:1176) + by 0x100031BF: main (sort.c:1223) + +* tests/misc/sort-stale-thread-mem.sh: Skip on ppc/ppc64. +* tests/misc/sort-u-FMR.sh: Likewise. + +--- + tests/misc/sort-stale-thread-mem.sh | 4 ++++ + tests/misc/sort-u-FMR.sh | 4 ++++ + 2 files changed, 8 insertions(+) + +Index: tests/misc/sort-stale-thread-mem.sh +=================================================================== +--- tests/misc/sort-stale-thread-mem.sh.orig ++++ tests/misc/sort-stale-thread-mem.sh +@@ -27,6 +27,10 @@ require_valgrind_ + grep '^#define HAVE_PTHREAD_T 1' "$CONFIG_HEADER" > /dev/null || + skip_ 'requires pthreads' + ++case "$( uname -m )" in ++ ppc | ppc64) skip_ "SUSE: disabled for now on ppc/ppc64";; ++esac ++ + # gensort output seems to trigger the failure more often, + # so prefer gensort if it is available. + (gensort -a 10000 in) 2>/dev/null || +Index: tests/misc/sort-u-FMR.sh +=================================================================== +--- tests/misc/sort-u-FMR.sh.orig ++++ tests/misc/sort-u-FMR.sh +@@ -20,6 +20,10 @@ + print_ver_ sort + require_valgrind_ + ++case "$( uname -m )" in ++ ppc | ppc64) skip_ "SUSE: disabled for now on ppc/ppc64";; ++esac ++ + { echo 0; printf '%0900d\n' 1; } > in || framework_failure_ + + valgrind --error-exitcode=1 sort --p=1 -S32b -u in > out || fail=1 diff --git a/coreutils-sysinfo.patch b/coreutils-sysinfo.patch new file mode 100644 index 0000000..a1eaba2 --- /dev/null +++ b/coreutils-sysinfo.patch @@ -0,0 +1,64 @@ +--- + src/uname.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +Index: src/uname.c +=================================================================== +--- src/uname.c.orig ++++ src/uname.c +@@ -338,6 +338,36 @@ main (int argc, char **argv) + # endif + } + #endif ++ if (element == unknown) ++ { ++ struct utsname name; ++ static char processor[sizeof (name.machine)]; ++ if (uname (&name) != 0) ++ error (EXIT_FAILURE, errno, _("cannot get system name")); ++ strcpy (processor, name.machine); ++ element = processor; ++#ifdef __linux__ ++ if (!strcmp (element, "i686")) ++ { ++ /* Check for Athlon */ ++ char line[1024]; ++ FILE *f = fopen ("/proc/cpuinfo", "r"); ++ if (f) ++ { ++ while (fgets (line, sizeof (line), f) > 0) ++ { ++ if (strncmp (line, "vendor_id", 9) == 0) ++ { ++ if (strstr (line, "AuthenticAMD")) ++ element = "athlon"; ++ break; ++ } ++ } ++ fclose (f); ++ } ++ } ++#endif ++ } + if (! (toprint == UINT_MAX && element == unknown)) + print_element (element); + } +@@ -363,6 +393,18 @@ main (int argc, char **argv) + element = hardware_platform; + } + #endif ++ if (element == unknown) ++ { ++ struct utsname name; ++ static char hardware_platform[sizeof (name.machine)]; ++ if (uname (&name) != 0) ++ error (EXIT_FAILURE, errno, _("cannot get system name")); ++ strcpy (hardware_platform, name.machine); ++ if (hardware_platform[0] == 'i' && hardware_platform[2] == '8' ++ && hardware_platform[3] == '6' && hardware_platform[4] == 0) ++ hardware_platform[1] = '3'; ++ element = hardware_platform; ++ } + if (! (toprint == UINT_MAX && element == unknown)) + print_element (element); + } diff --git a/coreutils-test_without_valgrind.patch b/coreutils-test_without_valgrind.patch new file mode 100644 index 0000000..1f7b45a --- /dev/null +++ b/coreutils-test_without_valgrind.patch @@ -0,0 +1,18 @@ +--- + tests/misc/shuf-reservoir.sh | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +Index: tests/misc/shuf-reservoir.sh +=================================================================== +--- tests/misc/shuf-reservoir.sh.orig ++++ tests/misc/shuf-reservoir.sh +@@ -37,8 +37,7 @@ run_shuf_n() + + # Critical memory-related bugs will cause a segfault here + # (with varying numbers of input/output lines) +- seq "$INPUT_LINES" | valgrind --leak-check=$leaklevel --error-exitcode=1 \ +- shuf -n "$OUTPUT_LINES" -o "out_${INPUT_LINES}_${OUTPUT_LINES}" || return 1 ++ seq "$INPUT_LINES" | shuf -n "$OUTPUT_LINES" -o "out_${INPUT_LINES}_${OUTPUT_LINES}" || return 1 + + EXPECTED_LINES="$OUTPUT_LINES" + test "$INPUT_LINES" -lt "$OUTPUT_LINES" && EXPECTED_LINES="$INPUT_LINES" diff --git a/coreutils-tests-shorten-extreme-factor-tests.patch b/coreutils-tests-shorten-extreme-factor-tests.patch new file mode 100644 index 0000000..9df6db2 --- /dev/null +++ b/coreutils-tests-shorten-extreme-factor-tests.patch @@ -0,0 +1,36 @@ +From d3b433bd41c8978c31fee085cc7e6b0554a4c03e Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Wed, 8 Jan 2014 01:15:58 +0100 +Subject: [PATCH] tests: shorten extreme-expensive factor tests + +The extended factor tests alone can take several hours on e.g. i586 +or arm6l. Strip the tests down from 37 to 3. + +* tests/local.mk (factor_tests): From the sequence of the tests +00..36, remove all but t00, t05 and t36. +--- + tests/local.mk | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +Index: tests/local.mk +=================================================================== +--- tests/local.mk.orig ++++ tests/local.mk +@@ -723,14 +723,9 @@ all_tests = \ + # See tests/factor/create-test.sh. + tf = tests/factor + factor_tests = \ +- $(tf)/t00.sh $(tf)/t01.sh $(tf)/t02.sh $(tf)/t03.sh $(tf)/t04.sh \ +- $(tf)/t05.sh $(tf)/t06.sh $(tf)/t07.sh $(tf)/t08.sh $(tf)/t09.sh \ +- $(tf)/t10.sh $(tf)/t11.sh $(tf)/t12.sh $(tf)/t13.sh $(tf)/t14.sh \ +- $(tf)/t15.sh $(tf)/t16.sh $(tf)/t17.sh $(tf)/t18.sh $(tf)/t19.sh \ +- $(tf)/t20.sh $(tf)/t21.sh $(tf)/t22.sh $(tf)/t23.sh $(tf)/t24.sh \ +- $(tf)/t25.sh $(tf)/t26.sh $(tf)/t27.sh $(tf)/t28.sh $(tf)/t29.sh \ +- $(tf)/t30.sh $(tf)/t31.sh $(tf)/t32.sh $(tf)/t33.sh $(tf)/t34.sh \ +- $(tf)/t35.sh $(tf)/t36.sh ++ $(tf)/t00.sh \ ++ $(tf)/t05.sh \ ++ $(tf)/t36.sh + + $(factor_tests): $(tf)/run.sh $(tf)/create-test.sh + $(AM_V_GEN)$(MKDIR_P) $(tf) diff --git a/coreutils-use-python3.patch b/coreutils-use-python3.patch new file mode 100644 index 0000000..bdbebcb --- /dev/null +++ b/coreutils-use-python3.patch @@ -0,0 +1,24 @@ +--- tests/du/move-dir-while-traversing.sh ++++ tests/du/move-dir-while-traversing.sh +@@ -20,9 +20,9 @@ + 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' ++# We use a python3-inotify script, so... ++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 @@ + # 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 + diff --git a/coreutils.changes b/coreutils.changes new file mode 100644 index 0000000..3380bd9 --- /dev/null +++ b/coreutils.changes @@ -0,0 +1,2948 @@ +* Mon Oct 25 2021 zpetrova@suse.com +- coreutils-df-fuse-portal-dummy.patch: + df: Add "fuse.portal" as a dummy file system (used in flatpak + implementations). (bsc#1189152) +* Fri Oct 16 2020 lnussel@suse.de +- prepare usrmerge (boo#1029961) +* Mon Aug 31 2020 mail@bernhard-voelker.de +- gnulib-test-avoid-FP-perror-strerror.patch: Add patch to + avoid false-positive error in gnulib tests 'test-perror2' and + 'test-strerror_r', visible on armv7l. +- coreutils.spec: Reference the patch. +* Thu Jul 16 2020 dimstar@opensuse.org +- Drop suse-module-tools BuildRequires: this was used for the macro + regenerate_initrd_post/posttrans, which have been moved to + rpm-config-SUSE in Jan 2019. +* Sat Jun 13 2020 mail@bernhard-voelker.de +- coreutils-gnulib-disable-test-float.patch: Add patch to temporarily + disable the gnulib test 'test-float' failing on ppc and ppc64le. +- coreutils.spec: Reference the patch. While at it, avoid conditional + Patch and Source entries as that break cross-platform builds from + source RPMs. +* Mon May 4 2020 dmueller@suse.com +- add coreutils-use-python3.patch to minimally port away from + python 2.x use of pyinotify in the testsuite +* Mon Mar 9 2020 mail@bernhard-voelker.de +- Update to 8.32: + * Noteworthy changes in release 8.32 (2020-03-05) [stable] + * * Bug fixes + cp now copies /dev/fd/N correctly on platforms like Solaris where + it is a character-special file whose minor device number is N. + [bug introduced in fileutils-4.1.6] + dd conv=fdatasync no longer reports a "Bad file descriptor" error + when fdatasync is interrupted, and dd now retries interrupted calls + to close, fdatasync, fstat and fsync instead of incorrectly + reporting an "Interrupted system call" error. + [bugs introduced in coreutils-6.0] + df now correctly parses the /proc/self/mountinfo file for unusual entries + like ones with '\r' in a field value ("mount -t tmpfs tmpfs /foo$'\r'bar"), + when the source field is empty ('mount -t tmpfs "" /mnt'), and when the + filesystem type contains characters like a blank which need escaping. + [bugs introduced in coreutils-8.24 with the introduction of reading + the /proc/self/mountinfo file] + factor again outputs immediately when stdout is a tty but stdin is not. + [bug introduced in coreutils-8.24] + ln works again on old systems without O_DIRECTORY support (like Solaris 10), + and on systems where symlink ("x", ".") fails with errno == EINVAL + (like Solaris 10 and Solaris 11). + [bug introduced in coreutils-8.31] + rmdir --ignore-fail-on-non-empty now works correctly for directories + that fail to be removed due to permission issues. Previously the exit status + was reversed, failing for non empty and succeeding for empty directories. + [bug introduced in coreutils-6.11] + 'shuf -r -n 0 file' no longer mistakenly reads from standard input. + [bug introduced with the --repeat feature in coreutils-8.22] + split no longer reports a "output file suffixes exhausted" error + when the specified number of files is evenly divisible by 10, 16, 26, + for --numeric, --hex, or default alphabetic suffixes respectively. + [bug introduced in coreutils-8.24] + seq no longer prints an extra line under certain circumstances (such as + 'seq -f "%%g " 1000000 1000000'). + [bug introduced in coreutils-6.10] + * * Changes in behavior + Several programs now check that numbers end properly. For example, + 'du -d 1x' now reports an error instead of silently ignoring the 'x'. + Affected programs and options include du -d, expr's numeric operands + on non-GMP builds, install -g and -o, ls's TABSIZE environment + variable, mknod b and c, ptx -g and -w, shuf -n, and sort --batch-size + and --parallel. + date now parses military time zones in accordance with common usage: + "A" to "M" are equivalent to UTC+1 to UTC+12 + "N" to "Y" are equivalent to UTC-1 to UTC-12 + "Z" is "zulu" time (UTC). + For example, 'date -d "09:00B" is now equivalent to 9am in UTC+2 time zone. + Previously, military time zones were parsed according to the obsolete + rfc822, with their value negated (e.g., "B" was equivalent to UTC-2). + [The old behavior was introduced in sh-utils 2.0.15 ca. 1999, predating + coreutils package.] + ls issues an error message on a removed directory, on GNU/Linux systems. + Previously no error and no entries were output, and so indistinguishable + from an empty directory, with default ls options. + uniq no longer uses strcoll() to determine string equivalence, + and so will operate more efficiently and consistently. + * * New Features + ls now supports the --time=birth option to display and sort by + file creation time, where available. + od --skip-bytes now can use lseek even if the input is not a regular + file, greatly improving performance in some cases. + stat(1) supports a new --cached= option, used on systems with statx(2) + to control cache coherency of file system attributes, + useful on network file systems. + * * Improvements + stat and ls now use the statx() system call where available, which can + operate more efficiently by only retrieving requested attributes. + stat and tail now know about the "binderfs", "dma-buf-fs", "erofs", + "ppc-cmm-fs", and "z3fold" file systems. + stat -f -c%%T now reports the file system type, and tail -f uses inotify. + * * Build-related + gzip-compressed tarballs are distributed once again +- Refresh patches: + * coreutils-disable_tests.patch + * coreutils-getaddrinfo.patch + * coreutils-i18n.patch + * coreutils-invalid-ids.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +- coreutils-i18n.patch: + * uniq: remove collation handling as required by newer POSIX; see + - https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=8e81d44b5 + - https://www.austingroupbugs.net/view.php?id=963 +- coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch: + * Add patch for 'ls' to restore 8.31 behavior on removed directories. +- coreutils.spec: + * Version: bump version. + * %%check: re-enable regular 'make check' for non-multibuild package. + * reference the above new patch. +- coreutils.keyring: + * Update from upstream (Savannah). +* Tue Jan 28 2020 lnussel@suse.de +- disable single and testsuite builds in rings/staging +- remove duplicate "coreutils" in flavor to make it look nicer in OBS +* Mon Jan 20 2020 mail@bernhard-voelker.de +- minor: remove obsolete comment in spec file. +* Thu Jan 9 2020 lnussel@suse.de +- switch to multibuild +- add coreutils-single subpackage that contains a single binary coreutils tool + similar to busybox +- package LC_CTIME directories also in lang package +- split off doc package +- remove info macros, handled by file trigger nowadays +* Thu Sep 19 2019 lnussel@suse.de +- Do not recommend lang package. The lang package already has a + supplements. +* Mon Mar 11 2019 mail@bernhard-voelker.de +- Update to 8.31: + * Noteworthy changes in release 8.31 (2019-03-10) [stable] + * * Bug fixes + 'base64 a b' now correctly diagnoses 'b' as the extra operand, not 'a'. + [bug introduced in coreutils-5.3.0] + When B already exists, 'cp -il A B' no longer immediately fails + after asking the user whether to proceed. + [This bug was present in "the beginning".] + df no longer corrupts displayed multibyte characters on macOS. + [bug introduced with coreutils-8.18] + seq no longer outputs inconsistent decimal point characters + for the last number, when locales are misconfigured. + [bug introduced in coreutils-7.0] + shred, sort, and split no longer falsely report ftruncate errors + when outputting to less-common file types. For example, the shell + command 'sort /dev/null -o /dev/stdout | cat' no longer fails with + an "error truncating" diagnostic. + [bug was introduced with coreutils-8.18 for sort and split, and + (for shared memory objects only) with fileutils-4.1 for shred] + sync no longer fails for write-only file arguments. + [bug introduced with argument support to sync in coreutils-8.24] + 'tail -f file | filter' no longer exits immediately on AIX. + [bug introduced in coreutils-8.28] + 'tail -f file | filter' no longer goes into an infinite loop + if filter exits and SIGPIPE is ignored. + [bug introduced in coreutils-8.28] + * * Changes in behavior + cksum, dd, hostid, hostname, link, logname, sleep, tsort, unlink, + uptime, users, whoami, yes: now always process --help and --version options, + regardless of any other arguments present before any optional '--' + end-of-options marker. + nohup now processes --help and --version as first options even if other + parameters follow. + 'yes a -- b' now outputs 'a b' instead of including the end-of-options + marker as before: 'a -- b'. + echo now always processes backslash escapes when the POSIXLY_CORRECT + environment variable is set. + When possible 'ln A B' now merely links A to B and reports an error + if this fails, instead of statting A and B before linking. This + uses fewer system calls and avoids some races. The old statting + approach is still used in situations where hard links to directories + are allowed (e.g., NetBSD when superuser). + ls --group-directories-first will also group symlinks to directories. + 'test -a FILE' is not supported anymore. Long ago, there were concerns about + the high probability of humans confusing the -a primary with the -a binary + operator, so POSIX changed this to 'test -e FILE'. Scripts using it were + already broken and non-portable; the -a unary operator was never documented. + wc now treats non breaking space characters as word delimiters + unless the POSIXLY_CORRECT environment variable is set. + * * New features + id now supports specifying multiple users. + 'date' now supports the '+' conversion specification flag, + introduced in POSIX.1-2017. + printf, seq, sleep, tail, and timeout now accept floating point + numbers in either the current or the C locale. For example, if the + current locale's decimal point is ',', 'sleep 0,1' and 'sleep 0.1' + now mean the same thing. Previously, these commands accepted only + C-locale syntax with '.' as the decimal point. The new behavior is + more compatible with other implementations in non-C locales. + test now supports the '-N FILE' unary operator (like e.g. bash) to check + whether FILE exists and has been modified since it was last read. + env now supports '--default-signal[=SIG]', '--ignore-signal[=SIG]', and + '--block-signal[=SIG], to setup signal handling before executing a program. + env now supports '--list-signal-handling' to indicate non-default + signal handling before executing a program. + * * New commands + basenc is added to complement existing base64,base32 commands, + and encodes and decodes printable text using various common encodings: + base64,base64url,base32,base32hex,base16,base2,z85. + * * Improvements + ls -l now better aligns abbreviated months containing digits, + which is common in Asian locales. + stat and tail now know about the "sdcardfs" file system on Android. + stat -f -c%%T now reports the file system type, and tail -f uses inotify. + stat now prints file creation time when supported by the file system, + on GNU Linux systems with glibc >= 2.28 and kernel >= 4.11. +- Refresh patches (line number changes only): + * coreutils-disable_tests.patch + * coreutils-i18n.patch + * coreutils-misc.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +- coreutils.spec: + * Version: bump version. + * URL: Use https scheme. + * %%description: Add 'basenc' tool. + * Change gitweb to cgit URL with https in a comment. +- coreutils.keyring: + * Update for added section headers ('GPG keys of '). +* Tue Jul 3 2018 mail@bernhard-voelker.de +- Update to 8.30: + * Noteworthy changes in release 8.30 (2018-07-01) [stable] + * * Bug fixes + 'cp --symlink SRC DST' will again correctly validate DST. + If DST is a regular file and SRC is a symlink to DST, + then cp will no longer allow that operation to clobber DST. + Also with -d, if DST is a symlink, then it can always be replaced, + even if it points to SRC on a separate device. + [bugs introduced with coreutils-8.27] + 'cp -n -u' and 'mv -n -u' now consistently ignore the -u option. + Previously, this option combination suffered from race conditions + that caused -u to sometimes override -n. + [bug introduced with coreutils-7.1] + 'cp -a --no-preserve=mode' now sets appropriate default permissions + for non regular files like fifos and character device nodes etc., + and leaves mode bits of existing files unchanged. + Previously it would have set executable bits on created special files, + and set mode bits for existing files as if they had been created. + [bug introduced with coreutils-8.20] + 'cp --remove-destination file symlink' now removes the symlink + even if it can't be traversed. + [bug introduced with --remove-destination in fileutils-4.1.1] + ls no longer truncates the abbreviated month names that have a + display width between 6 and 12 inclusive. Previously this would have + output ambiguous months for Arabic or Catalan locales. + 'ls -aA' is now equivalent to 'ls -A', since -A now overrides -a. + [bug introduced in coreutils-5.3.0] + 'mv -n A B' no longer suffers from a race condition that can + overwrite a simultaneously-created B. This bug fix requires + platform support for the renameat2 or renameatx_np syscalls, found + in recent Linux and macOS kernels. As a side effect, ‘mv -n A A’ + now silently does nothing if A exists. + [bug introduced with coreutils-7.1] + * * Changes in behavior + 'cp --force file symlink' now removes the symlink even if + it is self referential. + ls --color now matches file extensions case insensitively. + * * New features + cp --reflink now supports --reflink=never to enforce a standard copy. + env supports a new -v/--debug option to show verbose information about + each processing step. + env supports a new -S/--split-string=S option to split a single argument + string into multiple arguments. Used to pass multiple arguments in scripts + (shebang lines). + md5sum accepts a new option: --zero (-z) to delimit the output lines with a + NUL instead of a newline character. This also disables file name escaping. + This also applies to sha*sum and b2sum. + rm --preserve-root now supports the --preserve-root=all option to + reject any command line argument that is mounted to a separate file system. + * * Improvements + cut supports line lengths up to the max file size on 32 bit systems. + Previously only offsets up to SIZE_MAX-1 were supported. + stat and tail now know about the "exfs" file system, which is a + version of XFS. stat -f --format=%%T now reports the file system type, + and tail -f uses inotify. + wc avoids redundant processing of ASCII text in multibyte locales, + which is especially significant on macOS. + * * Build-related + Adjust to glibc >= 2.28 (bsc#1182550, jsc#SLE-13520, jsc#SLE-13756) +- Refresh patches (line number changes only): + * coreutils-build-timeout-as-pie.patch + * coreutils-disable_tests.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +- coreutils.spec: + * (License): osc changed the value from "GPL-3.0+" to "GPL-3.0-or-later". + * (build): Make sure that parse-datetime.{c,y} ends up in debuginfo (rh#1555079). +- coreutils-i18n.patch: + * src/exand.c,src/unexpand.c: Avoid -Wcomment warning. + * src/cut.c (cut_characters_or_cut_bytes_no_split): Change idx from size_t + to uintmax_t type to avoid a regression on i586, armv7l and ppc. + Compare upstream, non-MB commit: + https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=d1a754c8272 + (cut_fields_mb): Likewise for field_idx. + * tests/misc/cut.pl: Remove downstream tweaks as upstream MB tests are + working since a while. +- coreutils.keyring: Update Assaf Gordon's GPG public key. +* Thu Feb 22 2018 fvogt@suse.com +- Use %%license (boo#1082318) +* Thu Dec 28 2017 mail@bernhard-voelker.de +- Update to 8.29: + * Noteworthy changes in release 8.29 (2017-12-27) [stable] + * * Bug fixes + b2sum no longer crashes when processing certain truncated check files. + [bug introduced with b2sum coreutils-8.26] + dd now ensures the correct cache ranges are specified for the "nocache" + and "direct" flags. Previously some pages in the page cache were not + invalidated. [bug introduced for "direct" in coreutils-7.5, + and with the "nocache" implementation in coreutils-8.11] + df no longer hangs when given a fifo argument. + [bug introduced in coreutils-7.3] + ptx -S no longer infloops for a pattern which returns zero-length matches. + [the bug dates back to the initial implementation] + shred --remove will again repeatedly rename files with shortening names + to attempt to hide the original length of the file name. + [bug introduced in coreutils-8.28] + stty no longer crashes when processing settings with -F also specified. + [bug introduced in fileutils-4.0] + tail --bytes again supports non seekable inputs on all systems. + On systems like android it always tried to process as seekable inputs. + [bug introduced in coreutils-8.24] + timeout will again notice its managed command exiting, even when + invoked with blocked CHLD signal, or in a narrow window where + this CHLD signal from the exiting child was missed. In each case + timeout would have then waited for the time limit to expire. + [bug introduced in coreutils-8.27] + * * New features + timeout now supports the --verbose option to diagnose forced termination. + * * Improvements + dd now supports iflag=direct with arbitrary sized files on all file systems. + tail --bytes=NUM will efficiently seek to the end of block devices, + rather than reading from the start. + Utilities which do not support long options (other than the default --help + and --version), e.g. cksum and sleep, now use more consistent error diagnostic + for unknown long options. + * * Build-related + Default man pages are now distributed which are used if perl is + not available on the build system, or when cross compiling. +- Refresh patches (line number changes only): + * coreutils-i18n.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +* Mon Sep 4 2017 mail@bernhard-voelker.de +- Update to 8.28 + (for details see included NEWS file) +- Refresh patches: + * coreutils-disable_tests.patch + * coreutils-i18n.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +- coreutils.keyring: Update from upstream (Savannah). +- Remove now-upstream patches: + * coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch + * coreutils-tests-port-to-timezone-2017a.patch +- coreutils.spec: Add "BuildRequires: user(bin)" for the tests. +* Wed Aug 16 2017 ghe@suse.com +- Drop coreutils-ocfs2_reflinks.patch + OCFS2 file system has supported file clone ioctls like btrfs, + then, coreutils doesn't need this patch from the kernel v4.10-rc1 +* Tue May 2 2017 mail@bernhard-voelker.de +- coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch: + Add upstream patch to fix an heap overflow security issue + in date(1) and touch(1) with a large TZ variable + (CVE-2017-7476, rh#1444774, boo#1037124). +* Fri Mar 10 2017 mail@bernhard-voelker.de +- Update to 8.27 + (for details see included NEWS file) +- Refresh patches: + * coreutils-build-timeout-as-pie.patch + * coreutils-disable_tests.patch + * coreutils-getaddrinfo.patch + * coreutils-i18n.patch + * coreutils-ocfs2_reflinks.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-tests-shorten-extreme-factor-tests.patch + * coreutils-testsuite.spec +- coreutils.keyring: Update (now ascii-armored) by + 'osc service localrun download_files'. +- coreutils-tests-port-to-timezone-2017a.patch: Add patch to + workaround a FP test failure with newer timezone-2017a. +* Fri Dec 2 2016 mail@bernhard-voelker.de +- Update to 8.26 + (for details see included NEWS file) +- coreutils.spec (%%description): Add b2sum, a new utility. + (BuildRequires): Add timezone to enable new 'date-debug.sh' test. +- coreutils-i18n.patch: Sync I18N patch from Fedora, as the diff + for the old i18n implementation of expand/unexpand has become + unmaintainable: + git://pkgs.fedoraproject.org/coreutils.git +- Remove now-upstream patches: + * coreutils-df-hash-in-filter.patch + * coreutils-diagnose-fts-readdir-failure.patch + * coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch + * coreutils-maint-fix-dependency-of-man-arch.1.patch +- Refresh/merge all other patches: + * coreutils-invalid-ids.patch + * coreutils-ocfs2_reflinks.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-sysinfo.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +* Tue Nov 1 2016 mail@bernhard-voelker.de +- coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch: + Add upstream patch to fix "md5sum --check --ignore-missing" which + treated files with checksums starting with "00" as missing. +* Thu Jul 28 2016 mail@bernhard-voelker.de +- coreutils-maint-fix-dependency-of-man-arch.1.patch: Add Upstream + patch to fix the build dependency between src/arch -> man/arch.1 + which lead to spurious build failures. +- coreutils-df-hash-in-filter.patch: Refresh with -p0. +* Fri Jul 22 2016 pth@suse.de +- Add coreutils-df-hash-in-filter.patch that speeds up df. +* Wed Jul 6 2016 mail@bernhard-voelker.de +- coreutils-diagnose-fts-readdir-failure.patch: Add upstream patch + to diagnose readdir() failures in fts-based utilities: rm, chmod, + du, etc. (boo#984910) +* Fri Jan 29 2016 mail@bernhard-voelker.de +- Update to 8.25 + (for details see included NEWS file) +- coreutils.spec (%%description): Add base32, a new utility. +- Remove now-upstream patch: + * coreutils-tests-avoid-FP-of-ls-stat-free-color.patch +- Refresh/merge all other patches: + * coreutils-build-timeout-as-pie.patch + * coreutils-disable_tests.patch + * coreutils-i18n.patch + * coreutils-invalid-ids.patch + * coreutils-misc.patch + * coreutils-ocfs2_reflinks.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-test_without_valgrind.patch + * coreutils-tests-shorten-extreme-factor-tests.patch +* Sun Sep 20 2015 mail@bernhard-voelker.de +- coreutils-i18n.patch: Sync I18N patch from semi-official repository + (shared among distributions, maintained by Padraig Brady): + https://github.com/pixelb/coreutils/tree/i18n + This fixes the following issues in multi-byte locales: + * sort: fix large mem leak with --month-sort (boo#945361, rh#1259942): + https://github.com/pixelb/coreutils/commit/b429f5d8c7 + * sort: fix assertion with some inputs to --month-sort + https://github.com/pixelb/coreutils/commit/31e8211aca +* Sun Aug 30 2015 mail@bernhard-voelker.de +- coreutils-tests-avoid-FP-of-ls-stat-free-color.patch: Add upstream + patch on top of v8.24 to avoid a FP test failure with glibc>=2.22. +* Thu Jul 16 2015 mail@bernhard-voelker.de +- Sync I18N patch from semi-official repository (shared among + distributions, maintained by Padraig Brady): + https://github.com/pixelb/coreutils/tree/i18n + * coreutils-i18n.patch: Improve cut(1) performance in field-mode + in UTF8 locales. Squash in sort-keycompare-mb.patch. + * sort-keycompare-mb.patch: Remove. +- coreutils-build-timeout-as-pie.patch: Refresh. +* Thu Jul 9 2015 pth@suse.de +- Update to 8.24: + * * Bug fixes + * dd supports more robust SIGINFO/SIGUSR1 handling for outputting statistics. + Previously those signals may have inadvertently terminated the process. + * df --local no longer hangs with inaccessible remote mounts. + [bug introduced in coreutils-8.21] + * du now silently ignores all directory cycles due to bind mounts. + Previously it would issue a warning and exit with a failure status. + [bug introduced in coreutils-8.1 and partially fixed in coreutils-8.23] + * chroot again calls chroot(DIR) and chdir("/"), even if DIR is "/". + This handles separate bind mounted "/" trees, and environments + depending on the implicit chdir("/"). + [bugs introduced in coreutils-8.23] + * cp no longer issues an incorrect warning about directory hardlinks when a + source directory is specified multiple times. Now, consistent with other + file types, a warning is issued for source directories with duplicate names, + or with -H the directory is copied again using the symlink name. + * factor avoids writing partial lines, thus supporting parallel operation. + [the bug dates back to the initial implementation] + * head, od, split, tac, tail, and wc no longer mishandle input from files in + /proc and /sys file systems that report somewhat-incorrect file sizes. + * mkdir --parents -Z now correctly sets the context for the last component, + even if the parent directory exists and has a different default context. + [bug introduced with the -Z restorecon functionality in coreutils-8.22] + * numfmt no longer outputs incorrect overflowed values seen with certain + large numbers, or with numbers with increased precision. + [bug introduced when numfmt was added in coreutils-8.21] + * numfmt now handles leading zeros correctly, not counting them when + settings processing limits, and making them optional with floating point. + [bug introduced when numfmt was added in coreutils-8.21] + * paste no longer truncates output for large input files. This would happen + for example with files larger than 4GiB on 32 bit systems with a '\n' + character at the 4GiB position. + [the bug dates back to the initial implementation] + * rm indicates the correct number of arguments in its confirmation prompt, + on all platforms. [bug introduced in coreutils-8.22] + * shuf -i with a single redundant operand, would crash instead of issuing + a diagnostic. [bug introduced in coreutils-8.22] + * tail releases inotify resources when unused. Previously it could exhaust + resources with many files, or with -F if files were replaced many times. + [bug introduced in coreutils-7.5] + * tail -f again follows changes to a file after it's renamed. + [bug introduced in coreutils-7.5] + * tail --follow no longer misses changes to files if those files were + replaced before inotify watches were created. + [bug introduced in coreutils-7.5] + * tail --follow consistently outputs all data for a truncated file. + [bug introduced in the beginning] + * tail --follow=name correctly outputs headers for multiple files + when those files are being created or renamed. + [bug introduced in coreutils-7.5] + * * New features + * chroot accepts the new --skip-chdir option to not change the working directory + to "/" after changing into the chroot(2) jail, thus retaining the current wor- + king directory. The new option is only permitted if the new root directory is + the old "/", and therefore is useful with the --group and --userspec options. + * dd accepts a new status=progress level to print data transfer statistics + on stderr approximately every second. + * numfmt can now process multiple fields with field range specifications similar + to cut, and supports setting the output precision with the --format option. + * split accepts a new --separator option to select a record separator character + other than the default newline character. + * stty allows setting the "extproc" option where supported, which is + a useful setting with high latency links. + * sync no longer ignores arguments, and syncs each specified file, or with the + - -file-system option, the file systems associated with each specified file. + * tee accepts a new --output-error option to control operation with pipes + and output errors in general. + * * Changes in behavior + * df no longer suppresses separate exports of the same remote device, as + these are generally explicitly mounted. The --total option does still + suppress duplicate remote file systems. + [suppression was introduced in coreutils-8.21] + * mv no longer supports moving a file to a hardlink, instead issuing an error. + The implementation was susceptible to races in the presence of multiple mv + instances, which could result in both hardlinks being deleted. Also on case + insensitive file systems like HFS, mv would just remove a hardlinked 'file' + if called like `mv file File`. The feature was added in coreutils-5.0.1. + * numfmt --from-unit and --to-unit options now interpret suffixes as SI units, + and IEC (power of 2) units are now specified by appending 'i'. + * tee will exit early if there are no more writable outputs. + * tee does not treat the file operand '-' as meaning standard output any longer, + for better conformance to POSIX. This feature was added in coreutils-5.3.0. + * timeout --foreground no longer sends SIGCONT to the monitored process, + which was seen to cause intermittent issues with GDB for example. + * * Improvements + * cp,install,mv will convert smaller runs of NULs in the input to holes, + and cp --sparse=always avoids speculative preallocation on XFS for example. + * cp will read sparse files more efficiently when the destination is a + non regular file. For example when copying a disk image to a device node. + * mv will try a reflink before falling back to a standard copy, which is + more efficient when moving files across BTRFS subvolume boundaries. + * stat and tail now know about IBRIX. stat -f --format=%%T now reports the file + system type, and tail -f uses polling for files on IBRIX file systems. + * wc -l processes short lines much more efficiently. + * References from --help and the man pages of utilities have been corrected + in various cases, and more direct links to the corresponding online + documentation are provided. +- Patches adapted because of changed sources: + coreutils-disable_tests.patch + coreutils-i18n.patch + coreutils-misc.patch + coreutils-ocfs2_reflinks.patch + coreutils-remove_hostname_documentation.patch + coreutils-remove_kill_documentation.patch + coreutils-skip-gnulib-test-tls.patch + coreutils-tests-shorten-extreme-factor-tests.patch + sort-keycompare-mb.patch +- Patches removed because they're included in 8.24: + coreutils-chroot-perform-chdir-unless-skip-chdir.patch + coreutils-df-doc-df-a-includes-duplicate-file-systems.patch + coreutils-df-improve-mount-point-selection.patch + coreutils-df-show-all-remote-file-systems.patch + coreutils-df-total-suppress-separate-remotes.patch + coreutils-doc-adjust-reference-to-info-nodes-in-man-pages.patch + coreutils-fix_false_du_failure_on_newer_xfs.patch + coreutils-fix-man-deps.patch + coreutils-tests-aarch64-env.patch + coreutils-tests-make-inotify-rotate-more-robust-and-efficient.patch + coreutils-tests-rm-ext3-perf-increase-timeout.patch +* Wed Jun 3 2015 mail@bernhard-voelker.de +- coreutils-doc-adjust-reference-to-info-nodes-in-man-pages.patch: + add upstream patch: + doc: adjust reference to info nodes in man pages (boo#933396) +- coreutils-i18n.patch: Use a later version of the previous patch + to fix the sort I18N issue (boo#928749, CVE-2015-4041) to also + avoid CVE-2015-4042. + https://github.com/pixelb/coreutils/commit/bea5e36cc876 +* Tue May 12 2015 mail@bernhard-voelker.de +- Download keyring file from Savannah; prefer HTTPS over FTP + for remote sources. +* Tue May 12 2015 mail@bernhard-voelker.de +- Fix memory handling error with case insensitive sort using UTF-8 + (boo#928749): coreutils-i18n.patch + src/sort.c (keycompare_mb): Ensure the buffer is big enough + to handle anything output from wctomb(). Theoretically any + input char could be converted to multiple output chars, + and so we need to multiply the storage by MB_CUR_MAX. +* Tue Apr 7 2015 crrodriguez@opensuse.org +- If coreutils changes, for consistency, we must regenerate + the initrd. +* Thu Apr 2 2015 mpluskal@suse.com +- Add gpg signature +* Thu Mar 26 2015 rguenther@suse.com +- For openSUSE > 13.2 drop coreutils-build-timeout-as-pie.patch and + instead add a BuildRequire for gcc-PIE. +* Thu Feb 5 2015 mail@bernhard-voelker.de +- coreutils-tests-aarch64-env.patch: Add patch to avoid false + positive failures of the coreutils-testsuite on OBS/aarch64: + work around execve() reversing the order of "env" output. +* Mon Jan 19 2015 mail@bernhard-voelker.de +- Add upstream patches for df(1) from upstream, thus aligning with SLES12: + * df: improve mount point selection with inaccurate mount list: + - coreutils-df-improve-mount-point-selection.patch + * doc: mention that df -a includes duplicate file systems (deb#737399) + - coreutils-df-doc-df-a-includes-duplicate-file-systems.patch + * df: ensure -a shows all remote file system entries (deb#737399) + - coreutils-df-show-all-remote-file-systems.patch + * df: only suppress remote mounts of separate exports with --total + (deb#737399, rh#920806, boo#866010, boo#901905) + - coreutils-df-total-suppress-separate-remotes.patch +- Refresh patches: + * coreutils-chroot-perform-chdir-unless-skip-chdir.patch + * coreutils-tests-make-inotify-rotate-more-robust-and-efficient.patch +* Sat Nov 1 2014 mail@bernhard-voelker.de + Avoid spurious false positive failures of the testsuite on OBS due + to high load. +- coreutils-tests-rm-ext3-perf-increase-timeout.patch: + Add patch to increase timeout. +- coreutils-tests-make-inotify-rotate-more-robust-and-efficient.patch: + Add upstream patch. +* Sat Sep 27 2014 schwab@linux-m68k.org +- sort-keycompare-mb.patch: make sure to NUL-terminate the sort keys. + Fixes http://bugs.gnu.org/18540 +* Thu Sep 18 2014 pth@suse.de +- Add coreutils-fix_false_du_failure_on_newer_xfs.patch that fixes a false + negative in the testsuite. +- Add coreutils-disable_tests.patch to not run a tests that fail inside the OBS. +- Add coreutils-test_without_valgrind.patch to not use valgrind in shuf-reservoir. +* Fri Aug 1 2014 mail@bernhard-voelker.de +- Add patches for upstream glitches: + - coreutils-fix-man-deps.patch + - coreutils-chroot-perform-chdir-unless-skip-chdir.patch +- Refresh patches: + - coreutils-build-timeout-as-pie.patch + - coreutils-getaddrinfo.patch + - coreutils-i18n.patch + - coreutils-misc.patch + - coreutils-ocfs2_reflinks.patch + - coreutils-remove_hostname_documentation.patch + - coreutils-remove_kill_documentation.patch + - coreutils-skip-gnulib-test-tls.patch + - coreutils-tests-shorten-extreme-factor-tests.patch +- Remove now-upstream patches: + - coreutils-copy-fix-selinux-existing-dirs.patch + - coreutils-gnulib-tests-ppc64le.patch + - coreutils-tests-avoid-FP-cp-cpuinfo.patch + - coreutils-test-avoid-FP-when-no-ACL-support.patch + - coreutils-ln-avoid-segfault-for-empty-target.patch + - coreutils-date-avoid-crash-in-TZ-parsing.patch + - coreutils-shuf-repeat-avoid-crash-when-input-empty.patch + - coreutils-improve_df_--human_and_--si,_help_and_man_page.patch + - coreutils-avoid_sizeof_charPP__static_analysis_warning.patch + - coreutils-also_deduplicate_virtual_file_systems.patch + - coreutils-fix_handling_of_symlinks_in_mount_list.patch + - coreutils-ignore_non_file_system_entries_in_proc_mounts.patch + - coreutils-avoid_clang_-Wtautological-constant-out-of-range-compare_warning.patch + - coreutils-use_the_last_device_name_provided_by_the_system.patch + - coreutils-avoid_compiler_warnings_with_some_assert_implementations.patch + - coreutils-use_all_of_the_last_device_details_provided.patch + - coreutils-output_placeholder_values_for_inaccessible_mount_points.patch + - coreutils-look_for_accessible_mount_points_for_specified_devices.patch + - coreutils-report_correct_device_in_presence_of_eclipsed_mounts.patch + - coreutils-avoid_an_inconsequential_mem_leak.patch +- Update to 8.23 (2014-07-18) [stable] + * * Bug fixes + chmod -Rc no longer issues erroneous warnings for files with special bits set. + [bug introduced in coreutils-6.0] + cp -a, mv, and install --preserve-context, once again set the correct SELinux + context for existing directories in the destination. Previously they set + the context of an existing directory to that of its last copied descendent. + [bug introduced in coreutils-8.22] + cp -a, mv, and install --preserve-context, no longer seg fault when running + with SELinux enabled, when copying from file systems that return an error + when reading the SELinux context for a file. + [bug introduced in coreutils-8.22] + cp -a and mv now preserve xattrs of symlinks copied across file systems. + [bug introduced with extended attribute preservation feature in coreutils-7.1] + date could crash or go into an infinite loop when parsing a malformed TZ="". + [bug introduced with the --date='TZ="" ..' parsing feature in coreutils-5.3.0] + dd's ASCII and EBCDIC conversions were incompatible with common practice and + with POSIX, and have been corrected as follows. First, conv=ascii now + implies conv=unblock, and conv=ebcdic and conv=ibm now imply conv=block. + Second, the translation tables for dd conv=ascii and conv=ebcdic have been + corrected as shown in the following table, where A is the ASCII value, W is + the old, wrong EBCDIC value, and E is the new, corrected EBCDIC value; all + values are in octal. + A W E + 041 117 132 + 133 112 255 + 135 132 275 + 136 137 232 + 174 152 117 + 176 241 137 + 313 232 152 + 325 255 112 + 345 275 241 + [These dd bugs were present in "the beginning".] + df has more fixes related to the newer dynamic representation of file systems: + Duplicates are elided for virtual file systems like tmpfs. + Details for the correct device are output for points mounted multiple times. + Placeholder values are output for inaccessible file systems, rather than + than error messages or values for the wrong file system. + [These bugs were present in "the beginning".] + df now outputs all appropriate entries in the presence of bind mounts. + On some systems, entries would have been incorrectly elided due to + them being considered "dummy" mounts. + [bug introduced in coreutils-8.22] + du now silently ignores directory cycles introduced with bind mounts. + Previously it would issue a warning and exit with a failure status. + [bug introduced in coreutils-8.1] + head --bytes=-N and --lines=-N now handles devices more + consistently, not ignoring data from virtual devices like /dev/zero, + or on BSD systems data from tty devices. + [bug introduced in coreutils-5.0.1] + head --bytes=-N - no longer fails with a bogus diagnostic when stdin's + seek pointer is not at the beginning. + [bug introduced with the --bytes=-N feature in coreutils-5.0.1] + head --lines=-0, when the input does not contain a trailing '\n', + now copies all input to stdout. Previously nothing was output in this case. + [bug introduced with the --lines=-N feature in coreutils-5.0.1] + id, when invoked with no user name argument, now prints the correct group ID. + Previously, in the default output format, it would print the default group ID + in the password database, which may be neither real nor effective. For e.g., + when run set-GID, or when the database changes outside the current session. + [bug introduced in coreutils-8.1] + ln -sf now replaces symbolic links whose targets can't exist. Previously + it would display an error, requiring --no-dereference to avoid the issue. + [bug introduced in coreutils-5.3.0] + ln -sr '' F no longer segfaults. Now works as expected. + [bug introduced with the --relative feature in coreutils-8.16] + numfmt now handles blanks correctly in all unibyte locales. Previously + in locales where character 0xA0 is a blank, numfmt would mishandle it. + [bug introduced when numfmt was added in coreutils-8.21] + ptx --format long option parsing no longer falls through into the --help case. + [bug introduced in TEXTUTILS-1_22i] + ptx now consistently trims whitespace when processing multiple files. + [This bug was present in "the beginning".] + seq again generates correct output with start or end values = -0. + [bug introduced in coreutils-8.20.] + shuf --repeat no longer dumps core if the input is empty. + [bug introduced with the --repeat feature in coreutils-8.22] + sort when using multiple threads now avoids undefined behavior with mutex + destruction, which could cause deadlocks on some implementations. + [bug introduced in coreutils-8.6] + tail -f now uses polling mode for VXFS to cater for its clustered mode. + [bug introduced with inotify support added in coreutils-7.5] + * * New features + od accepts a new option: --endian=TYPE to handle inputs with different byte + orders, or to provide consistent output on systems with disparate endianness. + configure accepts the new option --enable-single-binary to build all the + selected programs in a single binary called "coreutils". The selected + programs can still be called directly using symlinks to "coreutils" or + shebangs with the option --coreutils-prog= passed to this program. The + install behavior is determined by the option --enable-single-binary=symlinks + or --enable-single-binary=shebangs (the default). With the symlinks option, + you can't make a second symlink to any program because that will change the + name of the called program, which is used by coreutils to determine the + desired program. The shebangs option doesn't suffer from this problem, but + the /proc/$pid/cmdline file might not be updated on all the platforms. The + functionality of each program is not affected but this single binary will + depend on all the required dynamic libraries even to run simple programs. + If you desire to build some tools outside the single binary file, you can + pass the option --enable-single-binary-exceptions=PROG_LIST with the comma + separated list of programs you want to build separately. This flag + considerably reduces the overall size of the installed binaries which makes + it suitable for embedded system. + * * Changes in behavior + chroot with an argument of "/" no longer implicitly changes the current + directory to "/", allowing changing only user credentials for a command. + chroot --userspec will now unset supplemental groups associated with root, + and instead use the supplemental groups of the specified user. + cut -d$'\n' again outputs lines identified in the --fields list, having + not done so in v8.21 and v8.22. Note using this non portable functionality + will result in the delayed output of lines. + ls with none of LS_COLORS or COLORTERM environment variables set, + will now honor an empty or unknown TERM environment variable, + and not output colors even with --colors=always. + * * Improvements + chroot has better --userspec and --group look-ups, with numeric IDs never + causing name look-up errors. Also look-ups are first done outside the chroot, + in case the look-up within the chroot fails due to library conflicts etc. + install now allows the combination of the -D and -t options. + numfmt supports zero padding of numbers using the standard printf + syntax of a leading zero, for example --format="%%010f". + Also throughput was improved by up to 800%% by avoiding redundant processing. + shred now supports multiple passes on GNU/Linux tape devices by rewinding + the tape before each pass, avoids redundant writes to empty files, + uses direct I/O for all passes where possible, and attempts to clear + inode storage used for small files on some file systems. + split avoids unnecessary input buffering, immediately writing input to output + which is significant with --filter or when writing to fifos or stdout etc. + stat and tail work better with HFS+, HFSX, LogFS and ConfigFS. stat -f + - -format=%%T now reports the file system type, and tail -f now uses inotify, + rather than the default of issuing a warning and reverting to polling. +* Fri Jul 25 2014 pth@suse.de +- Incorporate 9 bugfixes, one documentation update and two maintenance + patches that won't harm (bnc#888215), See NEWS for specifics: + coreutils-improve_df_--human_and_--si,_help_and_man_page.patch + coreutils-avoid_sizeof_charPP__static_analysis_warning.patch + coreutils-also_deduplicate_virtual_file_systems.patch + coreutils-fix_handling_of_symlinks_in_mount_list.patch + coreutils-ignore_non_file_system_entries_in_proc_mounts.patch + coreutils-avoid_clang_-Wtautological-constant-out-of-range-compare_warning.patch + coreutils-use_the_last_device_name_provided_by_the_system.patch + coreutils-avoid_compiler_warnings_with_some_assert_implementations.patch + coreutils-use_all_of_the_last_device_details_provided.patch + coreutils-output_placeholder_values_for_inaccessible_mount_points.patch + coreutils-look_for_accessible_mount_points_for_specified_devices.patch + coreutils-report_correct_device_in_presence_of_eclipsed_mounts.patch + coreutils-avoid_an_inconsequential_mem_leak.patch +* Sun Mar 16 2014 mail@bernhard-voelker.de +- Add upstream patch (gnu#16855): + * coreutils-shuf-repeat-avoid-crash-when-input-empty.patch: Add + patch for shuf: with -r, don't dump core if the input is empty. +* Sun Mar 16 2014 mail@bernhard-voelker.de +- Add upstream patch (gnu#16872): + * coreutils-date-avoid-crash-in-TZ-parsing.patch: Add patch for + date: fix crash or infinite loop when parsing a malformed TZ="". +* Sun Mar 16 2014 mail@bernhard-voelker.de +- Add upstream patch (gnu#17010): + * coreutils-ln-avoid-segfault-for-empty-target.patch: Add patch + to avoid that ln(1) segfaults for an empty, relative target. +* Mon Feb 24 2014 pth@suse.de +- Add three patches from SLE12 that aren't upstream: + coreutils-misc.patch (fixes for tests) + coreutils-getaddrinfo.patch (fake success as there's no network + in the build system) + coreutils-ocfs2_reflinks.patch (support ocfs2 reflinks in cp) +* Fri Jan 24 2014 mail@bernhard-voelker.de +- Testsuite: avoid a failure of tests/mkdir/p-acl.sh on armv7l. + * coreutils-test-avoid-FP-when-no-ACL-support.patch: Add upstream + patch to improve the check for a working ACL support. +- Refresh patches with QUILT_REFRESH_ARGS="-p0 --no-timestamps" + for easier patch handling. +* Thu Jan 9 2014 mail@bernhard-voelker.de +- Add upstream patch (coreutils-copy-fix-selinux-existing-dirs.patch): + cp -a: set the correct SELinux context on already existing + destination directories (rh#1045122). +- Merge I18n fixes from Fedora (coreutils-i18n.patch): + * sort: fix sorting by non-first field (rh#1003544) + * cut: avoid using slower multi-byte code in non-UTF-8 locales + (rh#1021403, rh#499220). +- Testsuite: skip some tests: + * coreutils-skip-some-sort-tests-on-ppc.patch: Add patch to + skip 2 valgrind'ed sort tests on ppc/ppc64. + * coreutils-skip-gnulib-test-tls.patch: Add patch to skip + the gnulib test 'test-tls' on i586, x86_64, ppc and ppc64. + * coreutils-tests-avoid-FP-cp-cpuinfo.patch: Add patch to skip a + test when cp fails for /proc/cpuinfo which happens on aarch64. + * coreutils-tests-shorten-extreme-factor-tests.patch: Add patch + to skip most of the extreme-expensive factor tests. +* Sat Jan 4 2014 mail@bernhard-voelker.de +- Refresh patches to match the new version. + * coreutils-build-timeout-as-pie.patch: Update line number. + * coreutils-gnulib-tests-ppc64le.patch: Likewise. + * coreutils-invalid-ids.patch: Likewise. + * coreutils-remove_hostname_documentation.patch: Likewise. + * coreutils-remove_kill_documentation.patch: Likewise. + * coreutils-sysinfo.patch: Likewise. + * coreutils-i18n.patch: Likewise. +- Additional changes in coreutils-i18n.patch: + * Accommodate to upstream changes in cut.c and uniq.c. + * Fix some compiler warnings. + * Fix 145-mb test in tests/misc/uniq.pl. + * Skip sort's "2[01]a" test cases for now + to avoid a test failure on i586/x86_64. +- Remove now-upstream and therefore obsolete patches. + * coreutils-8.21.de.po.xz: Remove, upstream is latest. + * coreutils-gnulib-tests-fix-nap-race-obs.patch: + Remove, now upstream. + * coreutils-gnulib-tests-fix-nap-race.patch: Likewise. + * longlong-aarch64.patch: Likewise. +- Update to 8.22 (2013-12-13) [stable] + * * Bug fixes + df now processes the mount list correctly in the presence of unstatable + mount points. Previously it may have failed to output some mount points. + [bug introduced in coreutils-8.21] + df now processes symbolic links and relative paths to special files containing + a mounted file system correctly. Previously df displayed the statistics about + the file system the file is stored on rather than the one inside. + [This bug was present in "the beginning".] + df now processes disk device nodes correctly in the presence of bind mounts. + Now df shows the base mounted file system rather than the last one mounted. + [This bug was present in "the beginning".] + install now removes the target file if the strip program failed for any + reason. Before, that file was left behind, sometimes even with wrong + permissions. + [This bug was present in "the beginning".] + ln --relative now updates existing symlinks correctly. Previously it based + the relative link on the dereferenced path of an existing link. + [This bug was introduced when --relative was added in coreutils-8.16.] + ls --recursive will no longer exit with "serious" exit code (2), if there + is an error reading a directory not specified on the command line. + [Bug introduced in coreutils-5.3.0] + mkdir, mkfifo, and mknod now work better when creating a file in a directory + with a default ACL whose umask disagrees with the process's umask, on a + system such as GNU/Linux where directory ACL umasks override process umasks. + [bug introduced in coreutils-6.0] + mv will now replace empty directories in the destination with directories + from the source, when copying across file systems. + [This bug was present in "the beginning".] + od -wN with N larger than 64K on a system with 32-bit size_t would + print approximately 2*N bytes of extraneous padding. + [Bug introduced in coreutils-7.0] + rm -I now prompts for confirmation before removing a write protected file. + [Bug introduced in coreutils-6.8] + shred once again uses direct I/O on systems requiring aligned buffers. + Also direct I/O failures for odd sized writes at end of file are now handled. + [The "last write" bug was introduced in coreutils-5.3.0 but masked + by the alignment bug introduced in coreutils-6.0] + tail --retry -f now waits for the files specified to appear. Before, tail + would immediately exit when such a file is initially inaccessible. + [This bug was introduced when inotify support was added in coreutils-7.5] + tail -F has improved handling of symlinks. Previously tail didn't respond + to the symlink target (re)appearing after being (re)created. + [This bug was introduced when inotify support was added in coreutils-7.5] + * * New features + cp, install, mkdir, mknod, mkfifo and mv now support "restorecon" + functionality through the -Z option, to set the SELinux context + appropriate for the new item location in the file system. + csplit accepts a new option: --suppressed-matched, to elide the lines + used to identify the split points. + df --output now accepts a 'file' field, to propagate a specified + command line argument through to the output. + du accepts a new option: --inodes to show the number of inodes instead + of the blocks used. + id accepts a new option: --zero (-z) to delimit the output entries by + a NUL instead of a white space character. + id and ls with -Z report the SMACK security context where available. + mkdir, mkfifo and mknod with -Z set the SMACK context where available. + id can now lookup by user ID, in addition to the existing name lookup. + join accepts a new option: --zero-terminated (-z). As with the sort,uniq + option of the same name, this makes join consume and produce NUL-terminated + lines rather than newline-terminated lines. + uniq accepts a new option: --group to print all items, while separating + unique groups with empty lines. + shred accepts new parameters to the --remove option to give greater + control over that operation, which can greatly reduce sync overhead. + shuf accepts a new option: --repeat (-r), which can repeat items in + the output. + * * Changes in behavior + cp --link now dereferences a symbolic link as source before creating the + hard link in the destination unless the -P,--no-deref option is specified. + Previously, it would create a hard link of the symbolic link, even when + the dereferencing options -L or -H were specified. + cp, install, mkdir, mknod and mkfifo no longer accept an argument to the + short -Z option. The --context equivalent still takes an optional argument. + dd status=none now suppresses all non fatal diagnostic messages, + not just the transfer counts. + df no longer accepts the long-obsolescent --megabytes option. + stdbuf now requires at least one buffering mode option to be specified, + as per the documented interface. + * * Improvements + base64 encoding throughput for bulk data is increased by about 60%%. + md5sum can use libcrypto hash routines where allowed to potentially + get better performance through using more system specific logic. + sha1sum for example has improved throughput by 40%% on an i3-2310M. + This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum. + stat and tail work better with EFIVARFS, EXOFS, F2FS, HOSTFS, SMACKFS, SNFS + and UBIFS. stat -f --format=%%T now reports the file system type, and tail -f + now uses inotify for files on all those except SNFS, rather than the default + (for unknown file system types) of issuing a warning and reverting to polling. + shuf outputs subsets of large inputs much more efficiently. + Reservoir sampling is used to limit memory usage based on the number of + outputs, rather than the number of inputs. + shred increases the default write block size from 12KiB to 64KiB + to align with other utilities and reduce the system call overhead. + split --line-bytes=SIZE, now only allocates memory as needed rather + than allocating SIZE bytes at program start. + stty now supports configuring "stick" (mark/space) parity where available. + * * Build-related + factor now builds on aarch64 based systems [bug introduced in coreutils-8.20] +* Thu Dec 19 2013 uweigand@de.ibm.com +- coreutils-gnulib-tests-ppc64le.patch: Fix imported gnulib long double + math tests for little-endian PowerPC. +* Thu Dec 19 2013 mail@bernhard-voelker.de +- Fix issue with binary input in non-C locale (rh#1036289) + (coreutils-i18n.patch): Initialize memory for some edge cases + in the i18n patch for uniq and join. +* Wed Dec 11 2013 mail@bernhard-voelker.de +- Avoid false sort test failure (coreutils-i18n.patch): + As for the C locale, skip the multi-byte test case + 'output-is-input-mb.p'. +* Sat Dec 7 2013 schwab@linux-m68k.org +- Require valgrind only when it exists +* Sun Dec 1 2013 mail@bernhard-voelker.de +- Update I18N patch from Fedora: + (coreutils-i18n.patch) + * sort: fix multibyte incompabilities (rh#821264) + * pr -e, with a mix of backspaces and TABs, could corrupt the + heap in multibyte locales (analyzed by J.Koncicky) + * path in the testsuite to cover i18n regressions + * Enable cut and sort-merge perl tests for multibyte as well +- Refresh longlong-aarch64.patch. +* Wed Aug 7 2013 mail@bernhard-voelker.de +- Remove "BuildRequires: help2man" as it is included. +* Tue Aug 6 2013 pth@suse.de +- Remove the the unnecessary povision of itself as rpmbuild takes + care of that. +- Remove all traces of coreutils-8.9-singlethreaded-sort.patch in + the spec file. +* Tue Jul 23 2013 mail@bernhard-voelker.de +- Undo the previous change. + Remove configure options gl_cv_func_printf_directive_n and + gl_cv_func_printf_infinite_long_double again because of constant + factory build failures on x86_64 and i586. The argument for + adding them was that the fortify checks would be bypassed + by the gnulib "reimplementation of printf", but that is not + the case: instead, gnulib just adds some wrapping code to ensure + a consistent behaviour on all supported platforms. +* Mon Jul 8 2013 schwab@suse.de +- Override broken configure checks +- coreutils-gl_printf_safe.patch: remove unused patch +* Sun Jun 16 2013 jengelh@inai.de +- Explicitly list libattr-devel as BuildRequires +- More robust make install call +* Fri Jun 7 2013 schwab@suse.de +- longlong-aarch64.patch: fix build on aarch64 +* Fri Jun 7 2013 mail@bernhard-voelker.de +- Remove su(1) and kill(1) - both are provided by util-linux now. + * su.pamd, su.default, coreutils-su.patch: Remove patch and PAM + config files related to su(1). + * coreutils-remove_kill_documentation.patch: Add patch to remove + kill from the texinfo manual. + * coreutils.spec: Remove above, su-related patch and sources. + Remove Requires:pam and BuildRequires:pam-devel. + Remove Provides:/bin/{su,kill}. + Remove paragraph mentioning su(1) and kill(1) in %%description. + Remove `moving su trickery` and other left-overs from %%install, + %%post and %%files. + Remove %%posttrans and %%verifyscript sections (as these contained + su-related stuff). + Add code to %%install to remove kill's program and man page. +* Mon May 20 2013 mail@bernhard-voelker.de +- Try to fix nap() races in gnulib-tests. + (coreutils-gnulib-tests-fix-nap-race.patch: add upstream patch) + (coreutils-gnulib-tests-fix-nap-race-obs.patch: add openSUSE patch for OBS) +* Wed May 15 2013 mhrusecky@suse.com +- Provides: /bin/{kill,su} + * for compatibility with programs requiring these (like lsb) until these will + be provided by util-linux +* Thu Apr 4 2013 mail@bernhard-voelker.de +- Fix source url for coreutils-testsuite. +* Thu Mar 21 2013 mmeister@suse.com +- Added url as source. + Please see http://en.opensuse.org/SourceUrls +* Thu Mar 21 2013 mail@bernhard-voelker.de +- Fix multibyte issue in unexpand (rh#821262) + (coreutils-i18n.patch: patch by Roman Kollár ) +- Fix cut to terminate mbdelim string + Otherwise, cut might do an unbounded strdup of the delimiter string + in i18n mode (https://bugzilla.redhat.com/show_bug.cgi?id=911929) + (coreutils-i18n.patch, from Mark Wielaard ) +- Add su(1) again + Now, su(1) will be provided via a symlink trick + to the file installed with a ".core" suffix. + By this, we can upgrade to 8.21 without having to wait + for a util-linux version providing it. + * coreutils-su.patch: Add cumulative su patch from previous Base:System + version 8.17, ported to 8.21 build structure. This supersedes the + following partial patches: + coreutils-8.6-compile-su-with-fpie.diff, + coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff, + coreutils-8.6-log-all-su-attempts.diff, + coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff, + coreutils-8.6-pam-support-for-su.diff, + coreutils-8.6-set-sane-default-path.diff, + coreutils-8.6-update-man-page-for-pam.diff, + coreutils-bnc#697897-setsid.patch. + * pam, pam-devel: Add as requirements, also during build. + * coreutils.spec (%%description): Clarify that su is included although removed + upstreams. + (%%install): Install su+kill files with suffix ".core". + (%%post): Move setting permissions on su from %%posttrans to %%install. + (%%posttrans): Create symlinks to files with ".core" suffix unless already + existing. +- Install kill(1) with the same symlink trick. +- Remove now-obsolete patches and files: + * coreutils-8.17.de.po.xz: + * coreutils-8.17.tar.xz: + Remove sources + translation of previous version + * coreutils-acl-nofollow.patch: + * coreutils-basename_documentation.patch: + * coreutils-cp-corrupt-fragmented-sparse.patch: + * coreutils-df-always-hide-rootfs.patch: + * coreutils-skip-du-slink-test.patch: + Fixed upstream. + * coreutils-getaddrinfo.patch: + * coreutils-misc.patch: + * coreutils-no_silent-rule.patch: + Remove test and build related patches. + * coreutils-ptr_int_casts.patch: + Remove because merged into coreutils-i18n.patch. +- Add files: + * coreutils-8.21.tar.xz: + Add tarball of the new upstream version + * coreutils-8.21.de.po.xz: + Add language file. +- Update patches: + * coreutils-i18n.patch + Merge some Fedora changes to keep the i18n patch like theirs. + Fix and cleanup sort's multibyte test with incorporated test data. + * coreutils-remove_hostname_documentation.patch +- Add patch to build 'timeout' as PIE (OBS requires it). + This patch actually was included in one of the old su patches. + * new patch name: coreutils-build-timeout-as-pie.patch +- Temporary disable some questionable patches (by commenting in the spec file): + * coreutils-gl_printf_safe.patch + * coreutils-8.9-singlethreaded-sort.patch +- Change build / spec file: + * Bump version from 8.17 to 8.21. + * Fix macro invocation in "Provides" for stat. + * Remove ancient "Obsoletes" entries. + * Remove/add the above removed/added sources and patches. + * Temporarily comment the code for statically linking LIB_GMP + (as it does not work). + * Remove -Wall from CFLAGS as it is already included in OBS' default options. + * Remove the --without-included-regex option to use + coreutils' regex implementation. + * Remove custom gl_cv_func_printf_directive_n and gl_cv_func_isnanl_works. + * Touch "man/*.x" to force the rebuild of the man pages. + * Make sort's multi-byte test script executable in %%check section. + * Hardcode package name for "%%find_lang" and "%%files lang -f" lines. + * In the %%files section, add the COPYING and THANKS files. + Furthermore, fix the path to the LC_TIME files. + * Change package description to accomodate to added programs + (hostid, nproc, realpath, stdbuf, truncate) + and mention the hacky installation of programs to move (kill, su). +- Update to 8.21 (2013-02-14) [stable] + * * New programs + numfmt: reformat numbers + * * New features + df now accepts the --output[=FIELD_LIST] option to define the list of columns + to include in the output, or all available columns if the FIELD_LIST is + omitted. Note this enables df to output both block and inode fields together. + du now accepts the --threshold=SIZE option to restrict the output to entries + with such a minimum SIZE (or a maximum SIZE if it is negative). + du recognizes -t SIZE as equivalent, for compatibility with FreeBSD. + * * Bug fixes + cp --no-preserve=mode now no longer exits non-zero. + [bug introduced in coreutils-8.20] + cut with a range like "N-" no longer allocates N/8 bytes. That buffer + would never be used, and allocation failure could cause cut to fail. + [bug introduced in coreutils-8.10] + cut no longer accepts the invalid range 0-, which made it print empty lines. + Instead, cut now fails and emits an appropriate diagnostic. + [This bug was present in "the beginning".] + cut now handles overlapping to-EOL ranges properly. Before, it would + interpret "-b2-,3-" like "-b3-". Now it's treated like "-b2-". + [This bug was present in "the beginning".] + cut no longer prints extraneous delimiters when a to-EOL range subsumes + another range. Before, "echo 123|cut --output-delim=: -b2-,3" would print + "2:3". Now it prints "23". [bug introduced in 5.3.0] + cut -f no longer inspects input line N+1 before fully outputting line N, + which avoids delayed output for intermittent input. + [bug introduced in TEXTUTILS-1_8b] + factor no longer loops infinitely on 32 bit powerpc or sparc systems. + [bug introduced in coreutils-8.20] + install -m M SOURCE DEST no longer has a race condition where DEST's + permissions are temporarily derived from SOURCE instead of from M. + pr -n no longer crashes when passed values >= 32. Also, line numbers are + consistently padded with spaces, rather than with zeros for certain widths. + [bug introduced in TEXTUTILS-1_22i] + seq -w ensures that for numbers input in scientific notation, + the output numbers are properly aligned and of the correct width. + [This bug was present in "the beginning".] + seq -w ensures correct alignment when the step value includes a precision + while the start value does not, and the number sequence narrows. + [This bug was present in "the beginning".] + seq -s no longer prints an erroneous newline after the first number, and + outputs a newline after the last number rather than a trailing separator. + Also seq no longer ignores a specified step value when the end value is 1. + [bugs introduced in coreutils-8.20] + timeout now ensures that blocking of ALRM signals is not inherited from + its parent, which would cause timeouts to be ignored. + [the bug dates back to the initial implementation] + * * Changes in behavior + df --total now prints '-' into the target column (mount point) of the + summary line, accommodating the --output option where the target field + can be in any column. If there is no source column, then df prints + 'total' in the target column. + df now properly outputs file system information with bind mounts present on + the system by skipping duplicate entries (identified by the device number). + Consequently, df also elides the early-boot pseudo file system type "rootfs". + nl no longer supports the --page-increment option, which has been + deprecated since coreutils-7.5. Use --line-increment instead. + * * Improvements + readlink now supports multiple arguments, and a complementary + - z, --zero option to delimit output items with the NUL character. + stat and tail now know about CEPH. stat -f --format=%%T now reports the file + system type, and tail -f uses polling for files on CEPH file systems. + stty now supports configuring DTR/DSR hardware flow control where available. + * * Build-related + Perl is now more of a prerequisite. It has long been required in order + to run (not skip) a significant percentage of the tests. Now, it is + also required in order to generate proper man pages, via help2man. The + generated man/*.1 man pages are no longer distributed. Building without + perl, you would create stub man pages. Thus, while perl is not an + official prerequisite (build and "make check" will still succeed), any + resulting man pages would be inferior. In addition, this fixes a bug + in distributed (not from clone) Makefile.in that could cause parallel + build failure when building from modified sources, as is common practice + for a patched distribution package. + factor now builds on x86_64 with x32 ABI, 32 bit MIPS, and all HPPA systems, + by avoiding incompatible asm. [bug introduced in coreutils-8.20] + A root-only test predicate would always fail. Its job was to determine + whether our dummy user, $NON_ROOT_USERNAME, was able to run binaries from + the build directory. As a result, all dependent tests were always skipped. + Now, those tests may be run once again. [bug introduced in coreutils-8.20] +- Update to 8.20 (2012-10-23) [stable] + * * New features + dd now accepts 'status=none' to suppress all informational output. + md5sum now accepts the --tag option to print BSD-style output with GNU + file name escaping. This also affects sha1sum, sha224sum, sha256sum, + sha384sum and sha512sum. + * * Bug fixes + cp could read from freed memory and could even make corrupt copies. + This could happen with a very fragmented and sparse input file, + on GNU/Linux file systems supporting fiemap extent scanning. + This bug also affects mv when it resorts to copying, and install. + [bug introduced in coreutils-8.11] + cp --no-preserve=mode now no longer preserves the original file's + permissions but correctly sets mode specified by 0666 & ~umask + du no longer emits a "disk-corrupted"-style diagnostic when it detects + a directory cycle that is due to a bind-mounted directory. Instead, + it detects this precise type of cycle, diagnoses it as such and + eventually exits nonzero. + factor (when using gmp) would mistakenly declare some composite numbers + to be prime, e.g., 465658903, 2242724851, 6635692801 and many more. + The fix makes factor somewhat slower (~25%%) for ranges of consecutive + numbers, and up to 8 times slower for some worst-case individual numbers. + [bug introduced in coreutils-7.0, with GNU MP support] + ls now correctly colors dangling symlinks when listing their containing + directories, with orphaned symlink coloring disabled in LS_COLORS. + [bug introduced in coreutils-8.14] + rm -i -d now prompts the user then removes an empty directory, rather + than ignoring the -d option and failing with an 'Is a directory' error. + [bug introduced in coreutils-8.19, with the addition of --dir (-d)] + rm -r S/ (where S is a symlink-to-directory) no longer gives the invalid + "Too many levels of symbolic links" diagnostic. + [bug introduced in coreutils-8.6] + seq now handles arbitrarily long non-negative whole numbers when the + increment is 1 and when no format-changing option is specified. + Before, this would infloop: + b=100000000000000000000; seq $b $b + [the bug dates back to the initial implementation] + * * Changes in behavior + nproc now diagnoses with an error, non option command line parameters. + * * Improvements + factor's core has been rewritten for speed and increased range. + It can now factor numbers up to 2^128, even without GMP support. + Its speed is from a few times better (for small numbers) to over + 10,000 times better (just below 2^64). The new code also runs a + deterministic primality test for each prime factor, not just a + probabilistic test. + seq is now up to 70 times faster than it was in coreutils-8.19 and prior, + but only with non-negative whole numbers, an increment of 1, and no + format-changing options. + stat and tail know about ZFS, VZFS and VMHGFS. stat -f --format=%%T now + reports the file system type, and tail -f now uses inotify for files on + ZFS and VZFS file systems, rather than the default (for unknown file + system types) of issuing a warning and reverting to polling. tail -f + still uses polling for files on VMHGFS file systems. + * * Build-related + root-only tests now check for permissions of our dummy user, + $NON_ROOT_USERNAME, before trying to run binaries from the build directory. + Before, we would get hard-to-diagnose reports of failing root-only tests. + Now, those tests are skipped with a useful diagnostic when the root tests + are run without following the instructions in README. + We now build most directories using non-recursive make rules. I.e., + rather than running make in man/, lib/, src/, tests/, instead, the top + level Makefile.am includes a $dir/local.mk that describes how to build + the targets in the corresponding directory. Two directories remain + unconverted: po/, gnulib-tests/. One nice side-effect is that the more + accurate dependencies have eliminated a nagging occasional failure that + was seen when running parallel "make syntax-check". +- Update to 8.19 (2012-08-20) [stable] + * * Bug fixes + df now fails when the list of mounted file systems (/etc/mtab) cannot + be read, yet the file system type information is needed to process + certain options like -a, -l, -t and -x. + [This bug was present in "the beginning".] + sort -u could fail to output one or more result lines. + For example, this command would fail to print "1": + (yes 7 | head -11; echo 1) | sort --p=1 -S32b -u + [bug introduced in coreutils-8.6] + sort -u could read freed memory. + For example, this evokes a read from freed memory: + perl -le 'print "a\n"."0"x900'|valgrind sort --p=1 -S32b -u>/dev/null + [bug introduced in coreutils-8.6] + * * New features + rm now accepts the --dir (-d) option which makes it remove empty directories. + Since removing empty directories is relatively safe, this option can be + used as a part of the alias rm='rm --dir'. This improves compatibility + with Mac OS X and BSD systems which also honor the -d option. +- Update to 8.18 (2012-08-12) [stable] + * * Bug fixes + cksum now prints checksums atomically so that concurrent + processes will not intersperse their output. + [the bug dates back to the initial implementation] + date -d "$(printf '\xb0')" would print 00:00:00 with today's date + rather than diagnosing the invalid input. Now it reports this: + date: invalid date '\260' + [This bug was present in "the beginning".] + df no longer outputs control characters present in the mount point name. + Such characters are replaced with '?', so for example, scripts consuming + lines output by df, can work reliably. + [This bug was present in "the beginning".] + df --total now exits with an appropriate diagnostic and error code, when + file system --type options do not lead to a processed file system. + [This bug dates back to when --total was added in coreutils-7.0] + head --lines=-N (-n-N) now resets the read pointer of a seekable input file. + This means that "head -n-3" no longer consumes all of its input, and lines + not output by head may be processed by other programs. For example, this + command now prints the final line, 2, while before it would print nothing: + seq 2 > k; (head -n-1 > /dev/null; cat) < k + [This bug was present in "the beginning".] + ls --color would mis-color relative-named symlinks in / + [bug introduced in coreutils-8.17] + split now ensures it doesn't overwrite the input file with generated output. + [the bug dates back to the initial implementation] + stat and df now report the correct file system usage, + in all situations on GNU/Linux, by correctly determining the block size. + [df bug since coreutils-5.0.91, stat bug since the initial implementation] + tail -f no longer tries to use inotify on AUFS or PanFS file systems + [you might say this was introduced in coreutils-7.5, along with inotify + support, but even now, its magic number isn't in the usual place.] + * * New features + stat -f recognizes the new remote file system types: aufs, panfs. + * * Changes in behavior + su: this program has been removed. We stopped installing "su" by + default with the release of coreutils-6.9.90 on 2007-12-01. Now, + that the util-linux package has the union of the Suse and Fedora + patches as well as enough support to build on the Hurd, we no longer + have any reason to include it here. + * * Improvements + sort avoids redundant processing in the presence of inaccessible inputs, + or unwritable output. Sort now diagnoses certain errors at start-up, + rather than after potentially expensive processing. + sort now allocates no more than 75%% of physical memory by default, + to better share system resources, and thus operate more efficiently. + [The default max memory usage changed from 50%% to 100%% in coreutils-8.16] +* Sun Jan 27 2013 coolo@suse.com +- do not require texinfo for building, texlive is a bit too heavy +* Sun Jan 20 2013 mail@bernhard-voelker.de +- Avoid segmentation fault in "join -i" with long line input + (bnc#798541, VUL-1, CVE-2013-0223) + * src/join.c: Instead of usig unreliable alloca() stack allocation, + use heap allocation via xmalloc()+free(). + (coreutils-i18n.patch, from Philipp Thomas ) +- Avoid segmentation fault in "sort -d" and "sort -M" with long line input + (bnc#798538, VUL-1, CVE-2013-0221) + * src/sort.c: Instead of usig unreliable alloca() stack allocation, + use heap allocation via xmalloc()+free(). + (coreutils-i18n.patch, from Philipp Thomas ) +- Avoid segmentation fault in "uniq" with long line input + (bnc#796243, VUL-1, CVE-2013-0222) + * src/cut.c: Instead of usig unreliable alloca() stack allocation, + use heap allocation via xmalloc()+free(). + (coreutils-i18n.patch) +- Fix test-suite errors (bnc#798261). + * tests/cp/fiemap-FMR: Fix path to src directory and declare + require_valgrind_ function. + (coreutils-cp-corrupt-fragmented-sparse.patch) + * tests/misc/cut: + Fix src/cut.c to properly pass output-delimiter tests. + Synchronize cut.c related part of the i18n patch with Fedora's. + Merge coreutils-i18n-infloop.patch into coreutils-i18n.patch. + Merge coreutils-i18n-uninit.patch into coreutils-i18n.patch. + In tests/misc/cut, do not replace the non-i18n error messages. + (coreutils-i18n.patch) + * tests/rm/ext3-perf: + This test failed due to heavy parallel CPU and/or disk load because it + is based on timeouts. Do not run the test-suite with 'make -jN. + (coreutils.spec, coreutils-testsuite.spec) + * tests/du/slink: + This test fails on OBS infrastructure and will be removed upstreams + in coreutils-8.21 anyway. Skip the test until we upgrade. + Upstream discussion: + http://lists.gnu.org/archive/html/coreutils/2013-01/msg00053.html + (coreutils-skip-du-slink-test.patch) + * Further spec changes: + Run more tests: also run "very expensive" tests; add acl, python-pyinotify, + strace and valgrind to the build requirements. + Remove patch5 and patch6 as they are now merged into coreutils-i18n.patch + (see above). + (coreutils.spec, coreutils-testsuite.spec) +- Maintenance changes: + (coreutils.spec, coreutils-testsuite.spec) + * Add perl and texinfo to the build requirements as they are needed to + re-generate the man pages and the texinfo documentation. + * Remove already-active "-Wall" compiler option from CFLAGS variable. + * Install the compressed test-suite.log into the documentation directory + of the coreutils-testsuite package (section %%check and %%files). + * Properly guard the spec sections for the coreutils and the + coreutils-testsuite package. + * Update patches to reflect new line numbers. +* Thu Jan 10 2013 phisama@suse.de +- Hardcode the name passed to find_lang so that it works for + coreutils-testsuite too. +* Thu Jan 10 2013 pth@suse.de +- Don't call autoreconf on distributions older then 12.0 + because their autoconf is too old, so also patch Makefile.in + in addition to Makefile.am where needed. +* Tue Dec 4 2012 mail@bernhard-voelker.de +- Update default posix version to 200112 (bnc#783352). +- Add coreutils-df-always-hide-rootfs.patch: + Hide rootfs in df (df not using yet /proc/self/mountinfo). +* Mon Nov 19 2012 idonmez@suse.com +- Statically link to gmp otherwise expr depends on gmp and gmp + configure script depends on expr which creates a build cycle. +* Thu Nov 8 2012 pth@suse.de +- Add the missing parts in coreutil.spec so that the testsuite is + only run when coreutils-testsuite is built. Also add additional + BuildRequires for the testsuite. +* Tue Nov 6 2012 pth@suse.de +- Add script pre_checkin.sh that creates spec and changes for + coreutils-testsuite from their coreutils counterparts. +* Sun Oct 28 2012 mail@bernhard-voelker.de +- Add upstream patch: + * cp could read from freed memory and could even make corrupt copies. + This could happen with a very fragmented and sparse input file, + on GNU/Linux file systems supporting fiemap extent scanning. + This bug also affects mv when it resorts to copying, and install. + [bug introduced in coreutils-8.11] (bnc#788459 gnu#12656) +* Fri Sep 21 2012 froh@suse.com +- fix coreutils-8.9-singlethreaded-sort.patch to + respect OMP_NUM_THREADS again. +* Tue Jun 19 2012 pth@suse.de +- Update to 8.17: + * * Bug fixes + * stat no longer reports a negative file size as a huge positive + number. [bug present since 'stat' was introduced in + fileutils-4.1.9] + * * New features + * split and truncate now allow any seekable files in situations + where the file size is needed, instead of insisting on regular + files. + * fmt now accepts the --goal=WIDTH (-g) option. + * stat -f recognizes new file system types: bdevfs, inodefs, qnx6 + * * Changes in behavior + * cp,mv,install,cat,split: now read and write a minimum of 64KiB at + a time. This was previously 32KiB and increasing to 64KiB was + seen to increase throughput by about 10%% when reading cached + files on 64 bit GNU/Linux. + * cp --attributes-only no longer truncates any existing destination + file, allowing for more general copying of attributes from one + file to another. +- Bring german message catalog up-to-date +* Tue May 15 2012 schwab@linux-m68k.org +- Build factor with gmp support +* Mon May 7 2012 pth@suse.de +- Two new upstream patches: + * id and groups, when invoked with no user name argument, would + print the default group ID listed in the password database, and + sometimes that ID would be neither real nor effective. For + example, when run set-GID, or in a session for which the default + group has just been changed, the new group ID would be listed, + even though it is not yet effective. + * 'cp S D' is no longer subject to a race: if an existing D were + removed between the initial stat and subsequent + open-without-O_CREAT, cp would fail with a confusing diagnostic + saying that the destination, D, was not found. Now, in this + unusual case, it retries the open (but with O_CREAT), and hence + usually succeeds. With NFS attribute caching, the condition was + particularly easy to trigger, since there, the removal of D could + precede the initial stat. [This bug was present in "the + beginning".] (bnc#760926). +* Fri Apr 27 2012 pth@suse.de +- Make stdbuf binary find libstdbuf.so by looking in the right + path (bnc#741241). +* Mon Apr 16 2012 pth@suse.de +- Update to 8.16: + - Improvements: + * As a GNU extension, 'chmod', 'mkdir', and 'install' now accept + operators '-', '+', '=' followed by octal modes; + * Also, ordinary numeric modes with five or more digits no longer + preserve setuid and setgid bits, so that 'chmod 00755 FOO' now + clears FOO's setuid and setgid bits. + * dd now accepts the count_bytes, skip_bytes iflags and the + seek_bytes oflag, to more easily allow processing portions of a + file. + * dd now accepts the conv=sparse flag to attempt to create sparse + output, by seeking rather than writing to the output file. + * ln now accepts the --relative option, to generate a relative + symbolic link to a target, irrespective of how the target is + specified. + * split now accepts an optional "from" argument to + - -numeric-suffixes, which changes the start number from the + default of 0. + * split now accepts the --additional-suffix option, to append an + additional static suffix to output file names. + * basename now supports the -a and -s options, which allow + processing of more than one argument at a time. Also the + complementary -z option was added to delimit output items with + the NUL character. + * dirname now supports more than one argument. Also the complementary + z option was added to delimit output items with the NUL character. + - Bug fixes + * du --one-file-system (-x) would ignore any non-directory + specified on the command line. For example, "touch f; du -x f" + would print nothing. [bug introduced in coreutils-8.15] + * mv now lets you move a symlink onto a same-inode destination + file that has two or more hard links. + * "mv A B" could succeed, yet A would remain. + * realpath no longer mishandles a root directory. + - Improvements + * ls can be much more efficient, especially with large directories + on file systems for which getfilecon-, ACL-check- and XATTR- + check-induced syscalls fail with ENOTSUP or similar. + * 'realpath --relative-base=dir' in isolation now implies + '--relative-to=dir' instead of causing a usage failure. + * split now supports an unlimited number of split files as default + behavior. + For a detaild list se NEWS in the documentation. +- Add up-to-date german translation. +* Mon Apr 16 2012 pth@suse.de +- Add two upstream patches that speed up ls (bnc#752943): + * Cache (l)getfilecon calls to avoid the vast majority of the failing + underlying getxattr syscalls. + * Avoids always-failing queries for whether a file has a nontrivial + ACL and for whether a file has certain "capabilities". +* Fri Mar 9 2012 pth@suse.de +- Update to 8.15: + * * New programs + realpath: print resolved file names. + * * Bug fixes + du --one-file-system (-x) would ignore any non-directory specified on + the command line. For example, "touch f; du -x f" would print nothing. + [bug introduced in coreutils-8.14] + du -x no longer counts root directories of other file systems. + [bug introduced in coreutils-5.1.0] + ls --color many-entry-directory was uninterruptible for too long + [bug introduced in coreutils-5.2.1] + ls's -k option no longer affects how ls -l outputs file sizes. + It now affects only the per-directory block counts written by -l, + and the sizes written by -s. This is for compatibility with BSD + and with POSIX 2008. Because -k is no longer equivalent to + - -block-size=1KiB, a new long option --kibibyte stands for -k. + [bug introduced in coreutils-4.5.4] + ls -l would leak a little memory (security context string) for each + nonempty directory listed on the command line, when using SELinux. + [bug probably introduced in coreutils-6.10 with SELinux support] + split -n 1/2 FILE no longer fails when operating on a growing file, or + (on some systems) when operating on a non-regular file like /dev/zero. + It would report "/dev/zero: No such file or directory" even though + the file obviously exists. Same for -n l/2. + [bug introduced in coreutils-8.8, with the addition of the -n option] + stat -f now recognizes the FhGFS and PipeFS file system types. + tac no longer fails to handle two or more non-seekable inputs + [bug introduced in coreutils-5.3.0] + tail -f no longer tries to use inotify on GPFS or FhGFS file systems + [you might say this was introduced in coreutils-7.5, along with inotify + support, but the new magic numbers weren't in the usual places then.] + * * Changes in behavior + df avoids long UUID-including file system names in the default listing. + With recent enough kernel/tools, these long names would be used, pushing + second and subsequent columns far to the right. Now, when a long name + refers to a symlink, and no file systems are specified, df prints the + usually-short referent instead. + tail -f now uses polling (not inotify) when any of its file arguments + resides on a file system of unknown type. In addition, for each such + argument, tail -f prints a warning with the FS type magic number and a + request to report it to the bug-reporting address. +- Bring german message catalog up to date. +- Include upstream fix for du. +- Include upstream patch fixing basename documentation. +* Mon Feb 6 2012 rschweikert@suse.com +- keep binaries in /usr (UserMerge project) +* Mon Dec 19 2011 lnussel@suse.de +- Adjust license for coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff + [bnc#735081]. +* Fri Dec 2 2011 cfarrell@suse.com +- license update: GPL-3.0+ + Consolidate to GPL-3.0+ and use SPDX format + (http://www.spdx.org/licenses). More or less compatible to Fedora package + (who don^t use full SPDX implementation) +* Wed Nov 30 2011 coolo@suse.com +- add automake as buildrequire to avoid implicit dependency +* Mon Oct 17 2011 pth@suse.de +- Add upstream patch that fixes three bugs in tac: + - remove sole use of sprintf in favor of stpcpy + - don't misbehave with multiple non-seekable inputs + - don't leak a file descriptor for each non-seekable input +* Fri Oct 14 2011 pth@suse.de +- Uniformly use german quotes not french ones in german messages. +* Thu Oct 13 2011 pth@suse.de +- Update to 8.14. Changes since 8.12: + Bug fixes: + - ls --dereference no longer outputs erroneous "argetm" strings for + dangling symlinks when an 'ln=target' entry is in $LS_COLORS. + [bug introduced in fileutils-4.0] + - ls -lL symlink once again properly prints "+" when the referent has + an ACL. [bug introduced in coreutils-8.13] + - sort -g no longer infloops for certain inputs containing NaNs [bug + introduced in coreutils-8.5] + - chown and chgrp with the -v --from= options, now output the correct + owner. I.E. for skipped files, the original ownership is output, + not the new one. [bug introduced in sh-utils-2.0g] + - cp -r could mistakenly change the permissions of an existing + destination directory. [bug introduced in coreutils-6.8] + - cp -u -p would fail to preserve one hard link for each up-to-date + copy of a src-hard-linked name in the destination tree. I.e., if + s/a and s/b are hard-linked and dst/s/a is up to date, "cp -up s + dst" would copy s/b to dst/s/b rather than simply linking dst/s/b + to dst/s/a. [This bug appears to have been present in "the + beginning".] + - fts-using tools (rm, du, chmod, chgrp, chown, chcon) no longer use + memory proportional to the number of entries in each directory they + process. Before, rm -rf 4-million-entry-directory would consume + about 1GiB of memory. Now, it uses less than 30MB, no matter how + many entries there are. [this bug was inherent in the use of fts: + thus, for rm the bug was introduced in coreutils-8.0. The prior + implementation of rm did not use as much memory. du, chmod, chgrp + and chown started using fts in 6.0. chcon was added in + coreutils-6.9.91 with fts support. ] + - pr -T no longer ignores a specified LAST_PAGE to stop at. [bug + introduced in textutils-1.19q] + - printf '%%d' '"' no longer accesses out-of-bounds memory in the + diagnostic. [bug introduced in sh-utils-1.16] + - split --number l/... no longer creates extraneous files in certain + cases. [bug introduced in coreutils-8.8] + - timeout now sends signals to commands that create their own process + group. timeout is no longer confused when starting off with a + child process. [bugs introduced in coreutils-7.0] + - unexpand -a now aligns correctly when there are spaces spanning a + tabstop, followed by a tab. In that case a space was dropped, + causing misalignment. We also now ensure that a space never + precedes a tab. [bug introduced in coreutils-5.3.0] + New features: + - date now accepts ISO 8601 date-time strings with "T" as the + separator. It has long parsed dates like "2004-02-29 16:21:42" + with a space between the date and time strings. Now it also parses + "2004-02-29T16:21:42" and fractional-second and time-zone-annotated + variants like "2004-02-29T16:21:42.333-07:00" + - md5sum accepts the new --strict option. With --check, it makes the + tool exit non-zero for any invalid input line, rather than just warning. + This also affects sha1sum, sha224sum, sha384sum and sha512sum. + - split accepts a new --filter=CMD option. With it, split filters + output through CMD. CMD may use the $FILE environment variable, + which is set to the nominal output file name for each invocation of + CMD. For example, to split a file into 3 approximately equal + parts, which are then compressed: + split -n3 --filter='xz > $FILE.xz' big + Note the use of single quotes, not double quotes. That creates + files named xaa.xz, xab.xz and xac.xz. + - timeout accepts a new --foreground option, to support commands not + started directly from a shell prompt, where the command is + interactive or needs to receive signals initiated from the + terminal. + Improvements: + - md5sum --check now supports the -r format from the corresponding + BSD tool. This also affects sha1sum, sha224sum, sha384sum and + sha512sum. + - pwd now works also on systems without openat. On such systems, pwd + would fail when run from a directory whose absolute name contained + more than PATH_MAX / 3 components. The df, stat and readlink + programs are also affected due to their use of the canonicalize_* + functions. + - join --check-order now prints "join: FILE:LINE_NUMBER: bad_line" + for an unsorted input, rather than e.g., "join: file 1 is not in + sorted order". + - shuf outputs small subsets of large permutations much more + efficiently. For example `shuf -i1-$((2**32-1)) -n2` no longer + exhausts memory. + - stat -f now recognizes the GPFS, MQUEUE and PSTOREFS file system + types. + - timeout now supports sub-second timeouts. + Changes in behavior: + - chmod, chown and chgrp now output the original attributes in + messages, when -v or -c specified. + - cp -au (where --preserve=links is implicit) may now replace newer + files in the destination, to mirror hard links from the source. +* Sat Sep 17 2011 jengelh@medozas.de +- Remove redundant tags/sections from specfile +* Tue Aug 2 2011 lchiquitto@suse.com +- file-has-acl: use acl_extended_file_nofollow if available to + avoid triggering unwanted AutoFS mounts (bnc#701659). +* Tue May 3 2011 pth@suse.de +- Remove services. +* Tue May 3 2011 ro@suse.de +- delete coreutils-testsuite.spec +* Thu Apr 28 2011 pth@suse.de +- Update to 8.12: + * Bug fixes + tail's --follow=name option no longer implies --retry on systems + with inotify support. [bug introduced in coreutils-7.5] + * Changes in behavior + cp's extent-based (FIEMAP) copying code is more reliable in the face + of varying and undocumented file system semantics: + - it no longer treats unwritten extents specially + - a FIEMAP-based extent copy always uses the FIEMAP_FLAG_SYNC flag. + Before, it would incur the performance penalty of that sync only + for 2.6.38 and older kernels. We thought all problems would be + resolved for 2.6.39. + - it now attempts a FIEMAP copy only on a file that appears sparse. + Sparse files are relatively unusual, and the copying code incurs + the performance penalty of the now-mandatory sync only for them. +- Add complete german meesage catalogue. +* Thu Apr 14 2011 pth@suse.de +- Update to 8.11: + * Bug fixes + cp -a --link would not create a hardlink to a symlink, instead + copying the symlink and then not preserving its timestamp. + [bug introduced in coreutils-8.0] + cp now avoids FIEMAP issues with BTRFS before Linux 2.6.38, + which could result in corrupt copies of sparse files. + [bug introduced in coreutils-8.10] + cut could segfault when invoked with a user-specified output + delimiter and an unbounded range like "-f1234567890-". + [bug introduced in coreutils-5.3.0] + du would infloop when given --files0-from=DIR + [bug introduced in coreutils-7.1] + sort no longer spawns 7 worker threads to sort 16 lines + [bug introduced in coreutils-8.6] + touch built on Solaris 9 would segfault when run on Solaris 10 + [bug introduced in coreutils-8.8] + wc would dereference a NULL pointer upon an early out-of-memory error + [bug introduced in coreutils-7.1] + * * New features + dd now accepts the 'nocache' flag to the iflag and oflag options, + which will discard any cache associated with the files, or + processed portion thereof. + dd now warns that 'iflag=fullblock' should be used, + in various cases where partial reads can cause issues. + * * Changes in behavior + cp now avoids syncing files when possible, when doing a FIEMAP copy. + The sync is only needed on Linux kernels before 2.6.39. + [The sync was introduced in coreutils-8.10] + cp now copies empty extents efficiently, when doing a FIEMAP copy. + It no longer reads the zero bytes from the input, and also can + efficiently create a hole in the output file when --sparse=always + is specified. + df now aligns columns consistently, and no longer wraps entries + with longer device identifiers, over two lines. + install now rejects its long-deprecated --preserve_context option. + Use --preserve-context instead. + test now accepts "==" as a synonym for "=" +* Tue Apr 5 2011 pth@suse.de +- Adapt coreutils-testsuite.spec to changes in patches. +* Tue Apr 5 2011 pth@suse.de +- Remove unneeded split_suffix patch. +* Mon Apr 4 2011 pth@suse.de +- Remove the last patch as it isn't needed. It was an old patch + that removed the documentation for both hostname and hostid. + I've modified that to only remove the hostname documentation. +* Fri Apr 1 2011 pth@suse.de +- Readd documentation of hostname and hostid to texinfo + documentation. +- Remove obsolete and unused german translation. +* Thu Feb 10 2011 pth@suse.de +- Update to 8.10: + * Bug fixes + - du would abort with a failed assertion when two conditions are + met: part of the hierarchy being traversed is moved to a higher + level in the directory tree, and there is at least one more + command line directory argument following the one containing + the moved sub-tree. [bug introduced in coreutils-5.1.0] + - join --header now skips the ordering check for the first line + even if the other file is empty. [bug introduced in + coreutils-8.5] + - rm -f no longer fails for EINVAL or EILSEQ on file systems that + reject file names invalid for that file system. + - uniq -f NUM no longer tries to process fields after end of + line. [bug introduced in coreutils-7.0] + * New features + - cp now copies sparse files efficiently on file systems with + FIEMAP support (ext4, btrfs, xfs, ocfs2). Before, it had to + read 2^20 bytes when copying a 1MiB sparse file. Now, it + copies bytes only for the non-sparse sections of a file. + Similarly, to induce a hole in the output file, it had to + detect a long sequence of zero bytes. Now, it knows precisely + where each hole in an input file is, and can reproduce them + efficiently in the output file. mv also benefits when it + resorts to copying, e.g., between file systems. + - join now supports -o 'auto' which will automatically infer the + output format from the first line in each file, to ensure the + same number of fields are output for each line. + * Changes in behavior + - join no longer reports disorder when one of the files is empty. + This allows one to use join as a field extractor like: + join -a1 -o 1.3,1.1 - /dev/null +- Add upstream patch that fixes a segfault in cut. +- Add upstream patch to fix sparse fiemap tests. +- Fix i18n patch for join. +* Fri Jan 14 2011 uli@suse.de +- sort threading still broken, it deadlocks occasionally; set + default number of threads to 1 as a workaround +* Wed Jan 5 2011 pth@suse.de +- Update to 8.9: + Bug fixes + split no longer creates files with a suffix length that + is dependent on the number of bytes or lines per file. + [bug introduced in coreutils-8.8] +* Mon Jan 3 2011 pth@suse.de +- Update to 8.8. Changes since 8.6: + Bug fixes: + cp -u no longer does unnecessary copying merely because the source + has finer-grained time stamps than the destination. + od now prints floating-point numbers without losing information, and + it no longer omits spaces between floating-point columns in some cases. + sort -u with at least two threads could attempt to read through a + corrupted pointer. [bug introduced in coreutils-8.6] + sort with at least two threads and with blocked output would busy-loop + (spinlock) all threads, often using 100%% of available CPU cycles to + do no work. I.e., "sort < big-file | less" could waste a lot of power. + [bug introduced in coreutils-8.6] + sort with at least two threads no longer segfaults due to use of pointers + into the stack of an expired thread. [bug introduced in coreutils-8.6] + sort --compress no longer mishandles subprocesses' exit statuses, + no longer hangs indefinitely due to a bug in waiting for subprocesses, + and no longer generates many more than NMERGE subprocesses. + sort -m -o f f ... f no longer dumps core when file descriptors are limited. + csplit no longer corrupts heap when writing more than 999 files, + nor does it leak memory for every chunk of input processed + [the bugs were present in the initial implementation] + tail -F once again notices changes in a currently unavailable + remote directory [bug introduced in coreutils-7.5] + Changes in behavior: + sort will not create more than 8 threads by default due to diminishing + performance gains. Also the --parallel option is no longer restricted + to the number of available processors. + cp --attributes-only now completely overrides --reflink. + Previously a reflink was needlessly attempted. + stat's %%X, %%Y, and %%Z directives once again print only the integer + part of seconds since the epoch. This reverts a change from + coreutils-8.6, that was deemed unnecessarily disruptive. + To obtain a nanosecond-precision time stamp for %%X use %%.X; + if you want (say) just 3 fractional digits, use %%.3X. + Likewise for %%Y and %%Z. + stat's new %%W format directive would print floating point seconds. + However, with the above change to %%X, %%Y and %%Z, we've made %%W work + the same way as the others. + New features: + split accepts the --number option to generate a specific number of files. +- Add a complete german translation. +- Add upstreams patch for suffix calculation in split. +* Wed Dec 22 2010 pth@novell.com +- Use software services. +- Remove coreutils tarball. +- Don't use version specific patches as it breaks automatic + updates. +* Wed Nov 17 2010 coolo@novell.com +- remove the prerequire on permissions - this will create a bad + cycle, coreutils is just too core +* Tue Nov 16 2010 lnussel@suse.de +- split pam patch into separate independent files so the main + feature can be shared with other distros +- don't hard require coreutils-lang +* Thu Nov 11 2010 pth@suse.de +- Update to 8.6: + o bugfixes + * du no longer multiply counts a file that is a directory or whose + link count is 1. + * du -H and -L now consistently count pointed-to files instead of + symbolic links, and correctly diagnose dangling symlinks. + * du --ignore=D now ignores directory D even when that directory is + found to be part of a directory cycle. + * split now diagnoses read errors rather than silently exiting. + * tac would perform a double-free when given an input line longer + than 16KiB. + * tail -F once again notices changes in a currently unavailable + directory, and works around a Linux kernel bug where inotify runs + out of resources. + * tr now consistently handles case conversion character classes. + o New features + * cp now accepts the --attributes-only option to not copy file data. + * du recognizes -d N as equivalent to --max-depth=N + * sort now accepts the --debug option, to highlight the part of the + line significant in the sort, and warns about questionable options. + * sort now supports -d, -f, -i, -R, and -V in any combination. + * stat now accepts the %%m format directive to output the mount point + for a file. It also accepts the %%w and %%W format directives for + outputting the birth time of a file, if one is available. + o Changes in behavior + * df now consistently prints the device name for a bind mounted file, + rather than its aliased target. + * du now uses less than half as much memory when operating on trees + with many hard-linked files. + * ls -l now uses the traditional three field time style rather than + the wider two field numeric ISO style in locales where a style has + not been specified. + * rm's -d now evokes an error; before, it was silently ignored. + * sort -g now uses long doubles for greater range and precision. + * sort -h no longer rejects numbers with leading or trailing ".", and + no longer accepts numbers with multiple ".". It now considers all + zeros to be equal. + * sort now uses the number of available processors to parallelize + the sorting operation. + * stat now provides translated output when no format is specified. + * stat no longer accepts the --context (-Z) option. + * stat no longer accepts the %%C directive when the --file-system + option is in effect. + * stat now outputs the full sub-second resolution for the atime, + mtime, and ctime values since the Epoch, when using the %%X, %%Y, and + %%Z directives of the --format option. + * touch's --file option is no longer recognized. Use --reference=F + (-r) instead. + * truncate now supports setting file sizes relative to a reference + file. Also errors are no longer suppressed for unsupported file + types, and relative sizes are restricted to supported file types. + See NEWS in the package documentation for more verbose description. +- Add a man page for [ (a link to test1). +- Fix assignment of a char to a char * in join.c +- Add permissions verifying for su. +- Use RELRO for su. +* Tue Aug 31 2010 aj@suse.de +- Recommend instead of require lang package since it's not mandatory. +* Thu Jul 1 2010 jengelh@medozas.de +- Use %%_smp_mflags +* Tue Jun 29 2010 pth@suse.de +- Fix 'sort -V' not working because the i18n (mb handling) patch + wasn't updated to handle the new option (bnc#615073). +* Mon Jun 28 2010 pth@suse.de +- Fix typo in spec file (%% missing from version). +* Fri Jun 18 2010 kukuk@suse.de +- Last part of fix for [bnc#533249]: Don't run account part of + PAM stack for su as root. Requires pam > 1.1.1. +* Fri May 7 2010 pth@novell.com +- Update to 8.5: + Bug fixes + * cp and mv once again support preserving extended attributes. + * cp now preserves "capabilities" when also preserving file ownership.7 + * ls --color once again honors the 'NORMAL' dircolors directive. + [bug introduced in coreutils-6.11] + * sort -M now handles abbreviated months that are aligned using + blanks in the locale database. Also locales with 8 bit characters + are handled correctly, including multi byte locales with the caveat + that multi byte characters are matched case sensitively. + * sort again handles obsolescent key formats (+POS -POS) correctly. + Previously if -POS was specified, 1 field too many was used in the + sort. [bug introduced in coreutils-7.2] + New features + * join now accepts the --header option, to treat the first line of + each file as a header line to be joined and printed + unconditionally. + * timeout now accepts the --kill-after option which sends a kill + signal to the monitored command if it's still running the specified + duration after the initial signal was sent. + * who: the "+/-" --mesg (-T) indicator of whether a user/tty is + accepting messages could be incorrectly listed as "+", when in + fact, the user was not accepting messages (mesg no). Before, who + would examine only the permission bits, and not consider the group + of the TTY device file. Thus, if a login tty's group would change + somehow e.g., to "root", that would make it unwritable (via + write(1)) by normal users, in spite of whatever the permission bits + might imply. Now, when configured using the + - -with-tty-group[=NAME] option, who also compares the group of the + TTY device with NAME (or "tty" if no group name is specified). + Changes in behavior + * ls --color no longer emits the final 3-byte color-resetting escape + sequence when it would be a no-op. + * join -t '' no longer emits an error and instead operates on each + line as a whole (even if they contain NUL characters). + For other changes since 7.1 see NEWS. +- Split-up coreutils-%%%%{version}.diff as far as possible. +- Prefix all patches with coreutils-. +- All patches have the .patch suffix. +- Use the i18n patch from Archlinux as it fixes at least one test + suite failure. +* Tue May 4 2010 pth@novell.com +- Fix security bug in distcheck (bnc#564373). +- refresh patches to apply cleanly. +* Tue Mar 2 2010 lnussel@suse.de +- enable hostid (bnc#584562) +* Sat Dec 12 2009 jengelh@medozas.de +- add baselibs.conf as a source +* Mon Mar 23 2009 pth@suse.de +- Add .ogv to dircolors (bnc#487561). +* Sun Feb 22 2009 schwab@suse.de +- Update to coreutils 7.1. + * * New features + Add extended attribute support available on certain filesystems like ext2 + and XFS. + cp: Tries to copy xattrs when --preserve=xattr or --preserve=all specified + mv: Always tries to copy xattrs + install: Never copies xattrs + cp and mv accept a new option, --no-clobber (-n): silently refrain + from overwriting any existing destination file + dd accepts iflag=cio and oflag=cio to open the file in CIO (concurrent I/O) + mode where this feature is available. + install accepts a new option, --compare (-C): compare each pair of source + and destination files, and if the destination has identical content and + any specified owner, group, permissions, and possibly SELinux context, then + do not modify the destination at all. + ls --color now highlights hard linked files, too + stat -f recognizes the Lustre file system type + * * Bug fixes + chgrp, chmod, chown --silent (--quiet, -f) no longer print some diagnostics + [bug introduced in coreutils-5.1] + cp uses much less memory in some situations + cp -a now correctly tries to preserve SELinux context (announced in 6.9.90), + doesn't inform about failure, unlike with --preserve=all + du --files0-from=FILE no longer reads all of FILE into RAM before + processing the first file name + seq 9223372036854775807 9223372036854775808 now prints only two numbers + on systems with extended long double support and good library support. + Even with this patch, on some systems, it still produces invalid output, + from 3 to at least 1026 lines long. [bug introduced in coreutils-6.11] + seq -w now accounts for a decimal point added to the last number + to correctly print all numbers to the same width. + wc --files0-from=FILE no longer reads all of FILE into RAM, before + processing the first file name, unless the list of names is known + to be small enough. + * * Changes in behavior + cp and mv: the --reply={yes,no,query} option has been removed. + Using it has elicited a warning for the last three years. + dd: user specified offsets that are too big are handled better. + Previously, erroneous parameters to skip and seek could result + in redundant reading of the file with no warnings or errors. + du: -H (initially equivalent to --si) is now equivalent to + - -dereference-args, and thus works as POSIX requires + shred: now does 3 overwrite passes by default rather than 25. + ls -l now marks SELinux-only files with the less obtrusive '.', + rather than '+'. A file with any other combination of MAC and ACL + is still marked with a '+'. +* Wed Nov 19 2008 werner@suse.de +- Enable stat(1) to detect (k)AFS and CIFS network file systems +* Tue Nov 18 2008 schwab@suse.de +- Move stat to /bin. +* Tue Oct 21 2008 schwab@suse.de +- Fix pam cleanup. +* Thu Sep 18 2008 schwab@suse.de +- Move readlink and md5sum to /bin. +* Wed Aug 20 2008 schwab@suse.de +- Add libselinux-devel to BuildRequires. +* Tue Jun 24 2008 schwab@suse.de +- Fix sort field limit in multibyte case. +* Wed Jun 4 2008 schwab@suse.de +- Update to coreutils 6.12. + * * Bug fixes + chcon, runcon: --help output now includes the bug-reporting address + cp -p copies permissions more portably. For example, on MacOS X 10.5, + "cp -p some-fifo some-file" no longer fails while trying to copy the + permissions from the some-fifo argument. + id with no options now prints the SELinux context only when invoked + with no USERNAME argument. + id and groups once again print the AFS-specific nameless group-ID (PAG). + Printing of such large-numbered, kernel-only (not in /etc/group) group-IDs + was suppressed in 6.11 due to ignorance that they are useful. + uniq: avoid subtle field-skipping malfunction due to isblank misuse. + In some locales on some systems, isblank(240) (aka  ) is nonzero. + On such systems, uniq --skip-fields=N would fail to skip the proper + number of fields for some inputs. + tac: avoid segfault with --regex (-r) and multiple files, e.g., + "echo > x; tac -r x x". [bug present at least in textutils-1.8b, from 1992] + * * Changes in behavior + install once again sets SELinux context, when possible + [it was deliberately disabled in 6.9.90] +* Sat Apr 19 2008 schwab@suse.de +- Update to coreutils 6.11. + * * Bug fixes + configure --enable-no-install-program=groups now works. + "cp -fR fifo E" now succeeds with an existing E. Before this fix, using + - fR to copy a fifo or "special" file onto an existing file would fail + with EEXIST. Now, it once again unlinks the destination before trying + to create the destination file. [bug introduced in coreutils-5.90] + dd once again works with unnecessary options like if=/dev/stdin and + of=/dev/stdout. [bug introduced in fileutils-4.0h] + id now uses getgrouplist, when possible. This results in + much better performance when there are many users and/or groups. + ls no longer segfaults on files in /proc when linked with an older version + of libselinux. E.g., ls -l /proc/sys would dereference a NULL pointer. + md5sum would segfault for invalid BSD-style input, e.g., + echo 'MD5 (' | md5sum -c - Now, md5sum ignores that line. + sha1sum, sha224sum, sha384sum, and sha512sum are affected, too. + [bug introduced in coreutils-5.1.0] + md5sum -c would accept a NUL-containing checksum string like "abcd\0..." + and would unnecessarily read and compute the checksum of the named file, + and then compare that checksum to the invalid one: guaranteed to fail. + Now, it recognizes that the line is not valid and skips it. + sha1sum, sha224sum, sha384sum, and sha512sum are affected, too. + [bug present in the original version, in coreutils-4.5.1, 1995] + "mkdir -Z x dir" no longer segfaults when diagnosing invalid context "x" + mkfifo and mknod would fail similarly. Now they're fixed. + mv would mistakenly unlink a destination file before calling rename, + when the destination had two or more hard links. It no longer does that. + [bug introduced in coreutils-5.3.0] + "paste -d'\' file" no longer overruns memory (heap since coreutils-5.1.2, + stack before then) [bug present in the original version, in 1992] + "pr -e" with a mix of backspaces and TABs no longer corrupts the heap + [bug present in the original version, in 1992] + "ptx -F'\' long-file-name" would overrun a malloc'd buffer and corrupt + the heap. That was triggered by a lone backslash (or odd number of them) + at the end of the option argument to --flag-truncation=STRING (-F), + - -word-regexp=REGEXP (-W), or --sentence-regexp=REGEXP (-S). + "rm -r DIR" would mistakenly declare to be "write protected" -- and + prompt about -- full DIR-relative names longer than MIN (PATH_MAX, 8192). + "rmdir --ignore-fail-on-non-empty" detects and ignores the failure + in more cases when a directory is empty. + "seq -f %% 1" would issue the erroneous diagnostic "seq: memory exhausted" + rather than reporting the invalid string format. + [bug introduced in coreutils-6.0] + * * New features + join now verifies that the inputs are in sorted order. This check can + be turned off with the --nocheck-order option. + sort accepts the new option --sort=WORD, where WORD can be one of + general-numeric, month, numeric or random. These are equivalent to the + options --general-numeric-sort/-g, --month-sort/-M, --numeric-sort/-n + and --random-sort/-R, resp. + * * Improvements + id and groups work around an AFS-related bug whereby those programs + would print an invalid group number, when given no user-name argument. + ls --color no longer outputs unnecessary escape sequences + seq gives better diagnostics for invalid formats. + * * Portability + rm now works properly even on systems like BeOS and Haiku, + which have negative errno values. + * * Consistency + install, mkdir, rmdir and split now write --verbose output to stdout, + not to stderr. +* Fri Apr 11 2008 schwab@suse.de +- Work around a recent glibc/getopt.c diagnostic change. +- Fix frexpl test. +* Thu Apr 10 2008 ro@suse.de +- added baselibs.conf file to build xxbit packages + for multilib support +* Mon Feb 18 2008 dmueller@suse.de +- split off -lang subpackage to reduce one CD media size +* Mon Feb 4 2008 kukuk@suse.de +- sux is deprecated since 3 years, let's finaly remove symlink. +* Tue Jan 22 2008 schwab@suse.de +- Update to coreutils 6.10. + * * Bug fixes + Fix a non-portable use of sed in configure.ac. + [bug introduced in coreutils-6.9.92] +* Sun Jan 13 2008 rguenther@suse.de +- Reapply dropped patch: + adjust test-getaddrinfo to not fail w/o network connection +* Sat Jan 12 2008 schwab@suse.de +- Update to coreutils 6.9.92. + * * Bug fixes + cp --parents no longer uses uninitialized memory when restoring the + permissions of a just-created destination directory. + [bug introduced in coreutils-6.9.90] + tr's case conversion would fail in a locale with differing numbers + of lower case and upper case characters. E.g., this would fail: + env LC_CTYPE=en_US.ISO-8859-1 tr '[:upper:]' '[:lower:]' + [bug introduced in coreutils-6.9.90] + * * Improvements + "touch -d now writable-but-owned-by-someone-else" now succeeds + whenever that same command would succeed without "-d now". + Before, it would work fine with no -d option, yet it would + fail with the ostensibly-equivalent "-d now". +* Mon Jan 7 2008 schwab@suse.de +- Update to coreutils 6.9.91. + * * Bug fixes + "ls -l" would not output "+" on SELinux hosts unless -Z was also given. + "rm" would fail to unlink a non-directory when run in an environment + in which the user running rm is capable of unlinking a directory. + [bug introduced in coreutils-6.9] +* Mon Jan 7 2008 jblunck@suse.de +- fix a cp bug with -p --parents +* Wed Dec 12 2007 rguenther@suse.de +- adjust test-getaddrinfo to not fail w/o network connection +* Mon Dec 10 2007 ro@suse.de +- change source archive compression back to .bz2 to avoid another + dependency in the lowest basesystem +* Mon Dec 3 2007 schwab@suse.de +- Update to coreutils-6.9.90. + * * New programs + arch: equivalent to uname -m, not installed by default + But don't install this program on Solaris systems. + chcon: change the SELinux security context of a file + mktemp: create a temporary file or directory (or names) + runcon: run a program in a different SELinux security context + * * Programs no longer installed by default + hostname, su + * * Changes in behavior + cp, by default, refuses to copy through a dangling destination symlink + Set POSIXLY_CORRECT if you require the old, risk-prone behavior. + pr -F no longer suppresses the footer or the first two blank lines in + the header. This is for compatibility with BSD and POSIX. + tr now warns about an unescaped backslash at end of string. + The tr from coreutils-5.2.1 and earlier would fail for such usage, + and Solaris' tr ignores that final byte. + * * New features + Add SELinux support, based on the patch from Fedora: + * cp accepts new --preserve=context option. + * "cp -a" works with SELinux: + Now, cp -a attempts to preserve context, but failure to do so does + not change cp's exit status. However "cp --preserve=context" is + similar, but failure *does* cause cp to exit with nonzero status. + * install accepts new "-Z, --context=C" option. + * id accepts new "-Z" option. + * stat honors the new %%C format directive: SELinux security context string + * ls accepts a slightly modified -Z option. + * ls: contrary to Fedora version, does not accept --lcontext and --scontext + cp -p tries to preserve the GID of a file even if preserving the UID + is not possible. + uniq accepts a new option: --zero-terminated (-z). As with the sort + option of the same name, this makes uniq consume and produce + NUL-terminated lines rather than newline-terminated lines. + wc no longer warns about character decoding errors in multibyte locales. + This means for example that "wc /bin/sh" now produces normal output + (though the word count will have no real meaning) rather than many + error messages. + * * New build options + By default, "make install" no longer attempts to install (or even build) su. + To change that, use ./configure --enable-install-program=su. + If you also want to install the new "arch" program, do this: + ./configure --enable-install-program=arch,su. + You can inhibit the compilation and installation of selected programs + at configure time. For example, to avoid installing "hostname" and + "uptime", use ./configure --enable-no-install-program=hostname,uptime + Note: currently, "make check" passes, even when arch and su are not + built (that's the new default). However, if you inhibit the building + and installation of other programs, don't be surprised if some parts + of "make check" fail. + * * Remove deprecated options + df no longer accepts the --kilobytes option. + du no longer accepts the --kilobytes or --megabytes options. + ls no longer accepts the --kilobytes option. + ptx longer accepts the --copyright option. + who no longer accepts -i or --idle. + * * Improved robustness + ln -f can no longer silently clobber a just-created hard link. + In some cases, ln could be seen as being responsible for data loss. + For example, given directories a, b, c, and files a/f and b/f, we + should be able to do this safely: ln -f a/f b/f c && rm -f a/f b/f + However, before this change, ln would succeed, and thus cause the + loss of the contents of a/f. + stty no longer silently accepts certain invalid hex values + in its 35-colon commmand-line argument + * * Bug fixes + chmod no longer ignores a dangling symlink. Now, chmod fails + with a diagnostic saying that it cannot operate on such a file. + [bug introduced in coreutils-5.1.0] + cp attempts to read a regular file, even if stat says it is empty. + Before, "cp /proc/cpuinfo c" would create an empty file when the kernel + reports stat.st_size == 0, while "cat /proc/cpuinfo > c" would "work", + and create a nonempty one. [bug introduced in coreutils-6.0] + cp --parents no longer mishandles symlinks to directories in file + name components in the source, e.g., "cp --parents symlink/a/b d" + no longer fails. Also, 'cp' no longer considers a destination + symlink to be the same as the referenced file when copying links + or making backups. For example, if SYM is a symlink to FILE, + "cp -l FILE SYM" now reports an error instead of silently doing + nothing. The behavior of 'cp' is now better documented when the + destination is a symlink. + "cp -i --update older newer" no longer prompts; same for mv + "cp -i" now detects read errors on standard input, and no longer consumes + too much seekable input; same for ln, install, mv, and rm. + cut now diagnoses a range starting with zero (e.g., -f 0-2) as invalid; + before, it would treat it as if it started with 1 (-f 1-2). + "cut -f 2-0" now fails; before, it was equivalent to "cut -f 2-" + cut now diagnoses the '-' in "cut -f -" as an invalid range, rather + than interpreting it as the unlimited range, "1-". + date -d now accepts strings of the form e.g., 'YYYYMMDD +N days', + in addition to the usual 'YYYYMMDD N days'. + du -s now includes the size of any stat'able-but-inaccessible directory + in the total size. + du (without -s) prints whatever it knows of the size of an inaccessible + directory. Before, du would print nothing for such a directory. + ls -x DIR would sometimes output the wrong string in place of the + first entry. [introduced in coreutils-6.8] + ls --color would mistakenly color a dangling symlink as if it were + a regular symlink. This would happen only when the dangling symlink + was not a command-line argument and in a directory with d_type support. + [introduced in coreutils-6.0] + ls --color, (with a custom LS_COLORS envvar value including the + ln=target attribute) would mistakenly output the string "target" + before the name of each symlink. [introduced in coreutils-6.0] + od's --skip (-j) option now works even when the kernel says that a + nonempty regular file has stat.st_size = 0. This happens at least + with files in /proc and linux-2.6.22. + "od -j L FILE" had a bug: when the number of bytes to skip, L, is exactly + the same as the length of FILE, od would skip *no* bytes. When the number + of bytes to skip is exactly the sum of the lengths of the first N files, + od would skip only the first N-1 files. [introduced in textutils-2.0.9] + ./printf %%.10000000f 1 could get an internal ENOMEM error and generate + no output, yet erroneously exit with status 0. Now it diagnoses the error + and exits with nonzero status. [present in initial implementation] + seq no longer mishandles obvious cases like "seq 0 0.000001 0.000003", + so workarounds like "seq 0 0.000001 0.0000031" are no longer needed. + seq would mistakenly reject some valid format strings containing %%%%, + and would mistakenly accept some invalid ones. e.g., %%g%%%% and %%%%g, resp. + "seq .1 .1" would mistakenly generate no output on some systems + Obsolete sort usage with an invalid ordering-option character, e.g., + "env _POSIX2_VERSION=199209 sort +1x" no longer makes sort free an + invalid pointer [introduced in coreutils-6.5] + sorting very long lines (relative to the amount of available memory) + no longer provokes unaligned memory access + split --line-bytes=N (-C N) no longer creates an empty file + [this bug is present at least as far back as textutils-1.22 (Jan, 1997)] + tr -c no longer aborts when translating with Set2 larger than the + complement of Set1. [present in the original version, in 1992] + tr no longer rejects an unmatched [:lower:] or [:upper:] in SET1. + [present in the original version] +* Thu Nov 29 2007 schwab@suse.de +- Update to coreutils-6.9.89.48 snapshot. +* Mon Jul 23 2007 schwab@suse.de +- Fix random sort. +- Fix invalid free. +- Fix misalignment. +* Sun May 20 2007 schwab@suse.de +- Fix compiling with glibc 2.6. +* Sun May 20 2007 schwab@suse.de +- Fix fchownat test. +* Mon Apr 2 2007 schwab@suse.de +- Fix ls -x. +* Fri Mar 23 2007 schwab@suse.de +- Update to coreutils 6.9. + * * Bug fixes + cp -x (--one-file-system) would fail to set mount point permissions + The default block size and output format for df -P are now unaffected by + the DF_BLOCK_SIZE, BLOCK_SIZE, and BLOCKSIZE environment variables. It + is still affected by POSIXLY_CORRECT, though. + Using pr -m -s (i.e. merging files, with TAB as the output separator) + no longer inserts extraneous spaces between output columns. +* Wed Mar 14 2007 lnussel@suse.de +- su: actually use /etc/pam.d/su-l when running su - (#254428) +* Mon Mar 5 2007 lnussel@suse.de +- su: don't chdir("/") before fork() (#251287) +* Fri Mar 2 2007 lnussel@suse.de +- split off and rework PAM patch for su: + * run pam_open_session as root (#245706) + * use separate pam configs for "su" and "su -" (RedHat #198639) + * detect pam libs in configure script, add option to disable it + * don't set argv[0] to "-su", use upstream behavior instead + * don't use getlogin() for setting PAM_RUSER +* Sun Feb 25 2007 schwab@suse.de +- Update to coreutils 6.8. + * * Bug fixes + chgrp, chmod, and chown now honor the --preserve-root option. + Before, they would warn, yet continuing traversing and operating on /. + chmod no longer fails in an environment (e.g., a chroot) with openat + support but with insufficient /proc support. + "cp --parents F/G D" no longer creates a directory D/F when F is not + a directory (and F/G is therefore invalid). + "cp --preserve=mode" would create directories that briefly had + too-generous permissions in some cases. For example, when copying a + directory with permissions 777 the destination directory might + temporarily be setgid on some file systems, which would allow other + users to create subfiles with the same group as the directory. Fix + similar problems with 'install' and 'mv'. + cut no longer dumps core for usage like "cut -f2- f1 f2" with two or + more file arguments. This was due to a double-free bug, introduced + in coreutils-5.3.0. + dd bs= operands now silently override any later ibs= and obs= + operands, as POSIX and tradition require. + "ls -FRL" always follows symbolic links on Linux. Introduced in + coreutils-6.0. + A cross-partition "mv /etc/passwd ~" (by non-root) now prints + a reasonable diagnostic. Before, it would print this: + "mv: cannot remove `/etc/passwd': Not a directory". + pwd and "readlink -e ." no longer fail unnecessarily when a parent + directory is unreadable. + "rm -rf /etc/passwd" (run by non-root) now prints a diagnostic. + Before it would print nothing. + "rm --interactive=never F" no longer prompts for an unwritable F + * * New features + sort's new --compress-program=PROG option specifies a compression + program to use when writing and reading temporary files. + This can help save both time and disk space when sorting large inputs. + * * New features + sort accepts the new option -C, which acts like -c except no diagnostic + is printed. Its --check option now accepts an optional argument, and + - -check=quiet and --check=silent are now aliases for -C, while + - -check=diagnose-first is an alias for -c or plain --check. +* Tue Jan 9 2007 schwab@suse.de +- Fix localized month sorting [#231790]. +* Wed Dec 13 2006 schwab@suse.de +- Fix acl tests. +* Sat Dec 9 2006 schwab@suse.de +- Update to coreutils 6.7. + * * Bug fixes + When cp -p copied a file with special mode bits set, the same bits + were set on the copy even when ownership could not be preserved. + This could result in files that were setuid to the wrong user. + To fix this, special mode bits are now set in the copy only if its + ownership is successfully preserved. Similar problems were fixed + with mv when copying across file system boundaries. This problem + affects all versions of coreutils through 6.6. + cp --preserve=ownership would create output files that temporarily + had too-generous permissions in some cases. For example, when + copying a file with group A and mode 644 into a group-B sticky + directory, the output file was briefly readable by group B. + Fix similar problems with cp options like -p that imply + - -preserve=ownership, with install -d when combined with either -o + or -g, and with mv when copying across file system boundaries. + This bug affects coreutils 6.0 through 6.6. + du --one-file-system (-x) would skip subdirectories of any directory + listed as second or subsequent command line argument. This bug affects + coreutils-6.4, 6.5 and 6.6. +* Wed Nov 22 2006 schwab@suse.de +- Update to coreutils 6.6. + * * Bug fixes + ls would segfault (dereference a NULL pointer) for a file with a + nameless group or owner. This bug was introduced in coreutils-6.5. + A bug in the latest official m4/gettext.m4 (from gettext-0.15) + made configure fail to detect gettext support, due to the unusual + way in which coreutils uses AM_GNU_GETTEXT. + * * Improved robustness + Now, du (and the other fts clients: chmod, chgrp, chown) honor a + trailing slash in the name of a symlink-to-directory even on + Solaris 9, by working around its buggy fstatat implementation. +* Mon Nov 20 2006 schwab@suse.de +- Update to coreutils 6.5. + * * Bug fixes + du (and the other fts clients: chmod, chgrp, chown) would exit early + when encountering an inaccessible directory on a system with native + openat support (i.e., linux-2.6.16 or newer along with glibc-2.4 + or newer). This bug was introduced with the switch to gnulib's + openat-based variant of fts, for coreutils-6.0. + "ln --backup f f" now produces a sensible diagnostic + * * New features + rm accepts a new option: --one-file-system +* Mon Oct 23 2006 schwab@suse.de +- Update to coreutils 6.4. + * * Bug fixes + chgrp and chown would malfunction when invoked with both -R and -H and + with one or more of the following: --preserve-root, --verbose, --changes, + - -from=o:g (chown only). This bug was introduced with the switch to + gnulib's openat-based variant of fts, for coreutils-6.0. + cp --backup dir1 dir2, would rename an existing dir2/dir1 to dir2/dir1~. + This bug was introduced in coreutils-6.0. + With --force (-f), rm no longer fails for ENOTDIR. + For example, "rm -f existing-non-directory/anything" now exits + successfully, ignoring the error about a nonexistent file. +* Mon Oct 9 2006 schwab@suse.de +- Update to coreutils 6.3. + * * Improved robustness + pinky no longer segfaults on Darwin 7.9.0 (MacOS X 10.3.9) due to a + buggy native getaddrinfo function. + rm works around a bug in Darwin 7.9.0 (MacOS X 10.3.9) that would + sometimes keep it from removing all entries in a directory on an HFS+ + or NFS-mounted partition. + sort would fail to handle very large input (around 40GB) on systems with a + mkstemp function that returns a file descriptor limited to 32-bit offsets. + * * Bug fixes + chmod would fail unnecessarily in an unusual case: when an initially- + inaccessible argument is rendered accessible by chmod's action on a + preceding command line argument. This bug also affects chgrp, but + it is harder to demonstrate. It does not affect chown. The bug was + introduced with the switch from explicit recursion to the use of fts + in coreutils-5.1.0 (2003-10-15). + cp -i and mv -i occasionally neglected to prompt when the copy or move + action was bound to fail. This bug dates back to before fileutils-4.0. + With --verbose (-v), cp and mv would sometimes generate no output, + or neglect to report file removal. + For the "groups" command: + "groups" no longer prefixes the output with "user :" unless more + than one user is specified; this is for compatibility with BSD. + "groups user" now exits nonzero when it gets a write error. + "groups" now processes options like --help more compatibly. + shuf would infloop, given 8KB or more of piped input + * * Portability + Versions of chmod, chown, chgrp, du, and rm (tools that use openat etc.) + compiled for Solaris 8 now also work when run on Solaris 10. +* Wed Oct 4 2006 agruen@suse.de +- cp: Replace the old --attributes=regex option with + - -preserve=xattrs. Only copy extended attributes if this + option is given. Use libattr's new copy_attr_action() function + to check which attributes to copy in /etc/xattr.conf. +* Tue Sep 19 2006 schwab@suse.de +- Disable broken autopoint. +* Mon Sep 18 2006 schwab@suse.de +- Update to coreutils 6.2. + * * Changes in behavior + mkdir -p and install -d (or -D) now use a method that forks a child + process if the working directory is unreadable and a later argument + uses a relative file name. This avoids some race conditions, but it + means you may need to kill two processes to stop these programs. + rm now rejects attempts to remove the root directory, e.g., `rm -fr /' + now fails without removing anything. Likewise for any file name with + a final `./' or `../' component. + tail now ignores the -f option if POSIXLY_CORRECT is set, no file + operand is given, and standard input is any FIFO; formerly it did + this only for pipes. + * * Infrastructure changes + Coreutils now uses gnulib via the gnulib-tool script. + If you check the source out from CVS, then follow the instructions + in README-cvs. Although this represents a large change to the + infrastructure, it should cause no change in how the tools work. + * * Bug fixes + cp --backup no longer fails when the last component of a source file + name is "." or "..". + "ls --color" would highlight other-writable and sticky directories + no differently than regular directories on a file system with + dirent.d_type support. + "mv -T --verbose --backup=t A B" now prints the " (backup: B.~1~)" + suffix when A and B are directories as well as when they are not. + mv and "cp -r" no longer fail when invoked with two arguments + where the first one names a directory and the second name ends in + a slash and doesn't exist. E.g., "mv dir B/", for nonexistent B, + now succeeds, once more. This bug was introduced in coreutils-5.3.0. +* Fri Sep 1 2006 schwab@suse.de +- Fix sbin patch [#202632]. +* Mon Aug 21 2006 schwab@suse.de +- Update to coreutils 6.1. + * * Changes in behavior + df now considers BSD "kernfs" file systems to be dummies + * * Bug fixes + cp --sparse preserves sparseness at the end of a file, even when + the file's apparent size is not a multiple of its block size. + [introduced with the original design, in fileutils-4.0r, 2000-04-29] + df (with a command line argument) once again prints its header + [introduced in coreutils-6.0] + ls -CF would misalign columns in some cases involving non-stat'able files + [introduced in coreutils-6.0] +* Tue Aug 15 2006 schwab@suse.de +- Update to coreutils 6.0. + * * Improved robustness + df: if the file system claims to have more available than total blocks, + report the number of used blocks as being "total - available" + (a negative number) rather than as garbage. + dircolors: a new autoconf run-test for AIX's buggy strndup function + prevents malfunction on that system; may also affect cut, expand, + and unexpand. + fts no longer changes the current working directory, so its clients + (chmod, chown, chgrp, du) no longer malfunction under extreme conditions. + pwd and other programs using lib/getcwd.c work even on file systems + where dirent.d_ino values are inconsistent with those from stat.st_ino. + rm's core is now reentrant: rm --recursive (-r) now processes + hierarchies without changing the working directory at all. + * * Changes in behavior + basename and dirname now treat // as different from / on platforms + where the two are distinct. + chmod, install, and mkdir now preserve a directory's set-user-ID and + set-group-ID bits unless you explicitly request otherwise. E.g., + `chmod 755 DIR' and `chmod u=rwx,go=rx DIR' now preserve DIR's + set-user-ID and set-group-ID bits instead of clearing them, and + similarly for `mkdir -m 755 DIR' and `mkdir -m u=rwx,go=rx DIR'. To + clear the bits, mention them explicitly in a symbolic mode, e.g., + `mkdir -m u=rwx,go=rx,-s DIR'. To set them, mention them explicitly + in either a symbolic or a numeric mode, e.g., `mkdir -m 2755 DIR', + `mkdir -m u=rwx,go=rx,g+s' DIR. This change is for convenience on + systems where these bits inherit from parents. Unfortunately other + operating systems are not consistent here, and portable scripts + cannot assume the bits are set, cleared, or preserved, even when the + bits are explicitly mentioned. For example, OpenBSD 3.9 `mkdir -m + 777 D' preserves D's setgid bit but `chmod 777 D' clears it. + Conversely, Solaris 10 `mkdir -m 777 D', `mkdir -m g-s D', and + `chmod 0777 D' all preserve D's setgid bit, and you must use + something like `chmod g-s D' to clear it. + `cp --link --no-dereference' now works also on systems where the + link system call cannot create a hard link to a symbolic link. + This change has no effect on systems with a Linux-based kernel. + csplit and nl now use POSIX syntax for regular expressions, not + Emacs syntax. As a result, character classes like [[:print:]] and + interval expressions like A\{1,9\} now have their usual meaning, + . no longer matches the null character, and \ must precede the + and + ? operators. + date: a command like date -d '2006-04-23 21 days ago' would print + the wrong date in some time zones. (see the test for an example) + df now considers "none" and "proc" file systems to be dummies and + therefore does not normally display them. Also, inaccessible file + systems (which can be caused by shadowed mount points or by chrooted + bind mounts) are now dummies, too. + expr no longer complains about leading ^ in a regular expression + (the anchor is ignored), or about regular expressions like A** (the + second "*" is ignored). expr now exits with status 2 (not 3) for + errors it detects in the expression's values; exit status 3 is now + used only for internal errors (such as integer overflow, which expr + now checks for). + install and mkdir now implement the X permission symbol correctly, + e.g., `mkdir -m a+X dir'; previously the X was ignored. + install now creates parent directories with mode u=rwx,go=rx (755) + instead of using the mode specified by the -m option; and it does + not change the owner or group of parent directories. This is for + compatibility with BSD and closes some race conditions. + ln now uses different (and we hope clearer) diagnostics when it fails. + ln -v now acts more like FreeBSD, so it generates output only when + successful and the output is easier to parse. + ls now defaults to --time-style='locale', not --time-style='posix-long-iso'. + However, the 'locale' time style now behaves like 'posix-long-iso' + if your locale settings appear to be messed up. This change + attempts to have the default be the best of both worlds. + mkfifo and mknod no longer set special mode bits (setuid, setgid, + and sticky) with the -m option. + nohup's usual diagnostic now more precisely specifies the I/O + redirections, e.g., "ignoring input and appending output to + nohup.out". Also, nohup now redirects stderr to nohup.out (or + $HOME/nohup.out) if stdout is closed and stderr is a tty; this is in + response to Open Group XCU ERN 71. + rm --interactive now takes an optional argument, although the + default of using no argument still acts like -i. + rm no longer fails to remove an empty, unreadable directory + seq changes: + seq defaults to a minimal fixed point format that does not lose + information if seq's operands are all fixed point decimal numbers. + You no longer need the `-f%%.f' in `seq -f%%.f 1048575 1024 1050623', + for example, since the default format now has the same effect. + seq now lets you use %%a, %%A, %%E, %%F, and %%G formats. + seq now uses long double internally rather than double. + sort now reports incompatible options (e.g., -i and -n) rather than + silently ignoring one of them. + stat's --format=FMT option now works the way it did before 5.3.0: + FMT is automatically newline terminated. The first stable release + containing this change was 5.92. + stat accepts the new option --printf=FMT, where FMT is *not* + automatically newline terminated. + stat: backslash escapes are interpreted in a format string specified + via --printf=FMT, but not one specified via --format=FMT. That includes + octal (\ooo, at most three octal digits), hexadecimal (\xhh, one or + two hex digits), and the standard sequences (\a, \b, \f, \n, \r, \t, + \v, \", \\). + With no operand, 'tail -f' now silently ignores the '-f' only if + standard input is a FIFO or pipe and POSIXLY_CORRECT is set. + Formerly, it ignored the '-f' when standard input was a FIFO, pipe, + or socket. + * * Scheduled for removal + ptx's --copyright (-C) option is scheduled for removal in 2007, and + now evokes a warning. Use --version instead. + rm's --directory (-d) option is scheduled for removal in 2006. This + option has been silently ignored since coreutils 5.0. On systems + that support unlinking of directories, you can use the "unlink" + command to unlink a directory. + Similarly, we are considering the removal of ln's --directory (-d, + - F) option in 2006. Please write to if this + would cause a problem for you. On systems that support hard links + to directories, you can use the "link" command to create one. + * * New programs + base64: base64 encoding and decoding (RFC 3548) functionality. + sha224sum: print or check a SHA224 (224-bit) checksum + sha256sum: print or check a SHA256 (256-bit) checksum + sha384sum: print or check a SHA384 (384-bit) checksum + sha512sum: print or check a SHA512 (512-bit) checksum + shuf: Shuffle lines of text. + * * New features + chgrp now supports --preserve-root, --no-preserve-root (default), + as it was documented to do, and just as chmod, chown, and rm do. + New dd iflag= and oflag= flags: + 'directory' causes dd to fail unless the file is a directory, on + hosts that support this (e.g., Linux kernels, version 2.1.126 and + later). This has limited utility but is present for completeness. + 'noatime' causes dd to read a file without updating its access + time, on hosts that support this (e.g., Linux kernels, version + 2.6.8 and later). + 'nolinks' causes dd to fail if the file has multiple hard links, + on hosts that support this (e.g., Solaris 10 and later). + ls accepts the new option --group-directories-first, to make it + list directories before files. + rm now accepts the -I (--interactive=once) option. This new option + prompts once if rm is invoked recursively or if more than three + files are being deleted, which is less intrusive than -i prompting + for every file, but provides almost the same level of protection + against mistakes. + shred and sort now accept the --random-source option. + sort now accepts the --random-sort (-R) option and `R' ordering option. + sort now supports obsolete usages like "sort +1 -2" unless + POSIXLY_CORRECT is set. However, when conforming to POSIX + 1003.1-2001 "sort +1" still sorts the file named "+1". + wc accepts a new option --files0-from=FILE, where FILE contains a + list of NUL-terminated file names. + * * Bug fixes + cat with any of the options, -A -v -e -E -T, when applied to a + file in /proc or /sys (linux-specific), would truncate its output, + usually printing nothing. + cp -p would fail in a /proc-less chroot, on some systems + When `cp -RL' encounters the same directory more than once in the + hierarchy beneath a single command-line argument, it no longer confuses + them with hard-linked directories. + fts-using tools (chmod, chown, chgrp, du) no longer fail due to + a double-free bug -- it could be triggered by making a directory + inaccessible while e.g., du is traversing the hierarchy under it. + fts-using tools (chmod, chown, chgrp, du) no longer misinterpret + a very long symlink chain as a dangling symlink. Before, such a + misinterpretation would cause these tools not to diagnose an ELOOP error. + ls --indicator-style=file-type would sometimes stat a symlink + unnecessarily. + ls --file-type worked like --indicator-style=slash (-p), + rather than like --indicator-style=file-type. + mv: moving a symlink into the place of an existing non-directory is + now done atomically; before, mv would first unlink the destination. + mv -T DIR EMPTY_DIR no longer fails unconditionally. Also, mv can + now remove an empty destination directory: mkdir -p a b/a; mv a b + rm (on systems with openat) can no longer exit before processing + all command-line arguments. + rm is no longer susceptible to a few low-probability memory leaks. + rm -r no longer fails to remove an inaccessible and empty directory + rm -r's cycle detection code can no longer be tricked into reporting + a false positive (introduced in fileutils-4.1.9). + shred --remove FILE no longer segfaults on Gentoo systems + sort would fail for large inputs (~50MB) on systems with a buggy + mkstemp function. sort and tac now use the replacement mkstemp + function, and hence are no longer subject to limitations (of 26 or 32, + on the maximum number of files from a given template) on HP-UX 10.20, + SunOS 4.1.4, Solaris 2.5.1 and OSF1/Tru64 V4.0F&V5.1. + tail -f once again works on a file with the append-only + attribute (affects at least Linux ext2, ext3, xfs file systems) +* Tue Aug 8 2006 schwab@suse.de +- Move sux to %%{_bindir}. +* Mon Jun 26 2006 schwab@suse.de +- Update to coreutils 5.97. + * * Bug fixes + rebuild with better autoconf test for when the lstat replacement + function is needed -- required for Solaris 9 + cat with any of the options, -A -v -e -E -T, when applied to a + file in /proc or /sys (linux-specific), would truncate its output, + usually printing nothing. + * * Improved robustness + dircolors: a new autoconf run-test for AIX's buggy strndup function + prevents malfunction on that system; may also affect cut, expand, + and unexpand. + * * New features + chgrp now supports --preserve-root, --no-preserve-root (default), + as it was documented to do, and just as chmod, chown, and rm do. +* Thu Jun 22 2006 schwab@suse.de +- Fix conflict with . +* Mon May 22 2006 schwab@suse.de +- Update to coreutils 5.96. +* Sat May 13 2006 schwab@suse.de +- Update to coreutils 5.95. +* Fri Apr 7 2006 cthiel@suse.de +- added Obsoletes: libselinux (hack for bug #156519) +* Mon Feb 13 2006 schwab@suse.de +- Fix spurious failure with cp -LR. +- Move check for /proc. +* Mon Jan 30 2006 schwab@suse.de +- Always print newline after format in stat [#145905]. +- Barf if /proc is not mounted. +* Wed Jan 25 2006 mls@suse.de +- converted neededforbuild to BuildRequires +* Thu Jan 19 2006 meissner@suse.de +- Do not strip /bin/su. +* Wed Jan 11 2006 schwab@suse.de +- Fix infloop when ignoring characters [#141756]. +* Mon Dec 19 2005 kukuk@suse.de +- Add fallback if futimesat does not work +* Mon Dec 5 2005 ke@suse.de +- Fix typo in German translation file; reported by Olaf Hering + [#105863]. +* Mon Dec 5 2005 schwab@suse.de +- Drop SELinux support. +* Tue Nov 15 2005 uli@suse.de +- some tests fail on ARM (QEMU problem?); ignore for now +* Sun Nov 6 2005 schwab@suse.de +- Update to coreutils 5.93. +* Wed Nov 2 2005 schwab@suse.de +- Update to coreutils 5.92. +- Fix invalid use of va_list. +- Add some fixes from cvs. +* Thu Oct 20 2005 schwab@suse.de +- Reenable DEFAULT_POSIX2_VERSION. +* Wed Oct 19 2005 agruen@suse.de +- Add acl and xattr patches. +* Mon Oct 17 2005 schwab@suse.de +- Update to coreutils 5.91. +* Sat Oct 1 2005 schwab@suse.de +- Update to coreutils 5.90. +- Disable acl patches for now. +* Sun Sep 25 2005 schwab@suse.de +- Fix warning. +* Wed Aug 24 2005 werner@suse.de +- Let `su' handle /sbin and /usr/sbin in path +* Mon Aug 1 2005 kukuk@suse.de +- And yet another uninitialized variable fix. +* Fri Jul 29 2005 schwab@suse.de +- Fix another uninitialized variable. +* Wed Jul 6 2005 schwab@suse.de +- Fix uninitialized variable. +* Mon Jul 4 2005 schwab@suse.de +- Update i18n patch. +* Mon Jun 20 2005 schwab@suse.de +- Fix last change. +* Wed Jun 15 2005 kukuk@suse.de +- Compile/link su with -fpie/-pie +* Sat May 21 2005 kukuk@suse.de +- Add support for /etc/default/su +* Mon May 2 2005 kukuk@suse.de +- Don't overwrite PATH if su is called with "-" option. +* Wed Mar 2 2005 schwab@suse.de +- Fix merge error [#67103]. +* Mon Feb 28 2005 schwab@suse.de +- Call pam_getenvlist before pam_end. +* Mon Feb 28 2005 schwab@suse.de +- Link su to sux [#66830]. +* Wed Feb 2 2005 schwab@suse.de +- Handle xfs and jfs in stat [#50415]. +* Wed Feb 2 2005 schwab@suse.de +- Handle subfs like autofs. +* Tue Jan 25 2005 schwab@suse.de +- Fix path_concat. +* Thu Jan 20 2005 schwab@suse.de +- Use pam_xauth [#42238]. +* Fri Jan 14 2005 schwab@suse.de +- Fix merge error [#49853]. +* Tue Jan 11 2005 schwab@suse.de +- Update to coreutils 5.3.0. +* Mon Nov 8 2004 kukuk@suse.de +- Use common-* PAM config files for su PAM configuration +* Mon Oct 25 2004 schwab@suse.de +- Fix last change. +- Fix selinux patch. +* Tue Oct 19 2004 ro@suse.de +- remove no language support (nb is already there) +* Sat Oct 2 2004 agruen@suse.de +- #46609: Fix chown and chgrp utilities for uid == (uid_t) -1 and + gid == (gid_t) -1 case. +- Add missing #include to have NULL defined in lib/acl.c +* Thu Sep 9 2004 schwab@suse.de +- Fix uninitialized variable [#44929]. +- Fix selinux patch. +* Wed Aug 25 2004 schwab@suse.de +- Fix hardlink accounting patch. +* Mon May 24 2004 schwab@suse.de +- Update testsuite for change in chown. +* Mon May 24 2004 schwab@suse.de +- Precompute length in caller of ismbblank to avoid quadratic behaviour + [#40741]. +* Mon May 17 2004 schwab@suse.de +- Fix handling of symlinks in chown [#40691]. +* Sat Apr 17 2004 schwab@suse.de +- Pacify autobuild. +* Fri Apr 2 2004 schwab@suse.de +- Add support for IUTF8 in stty. +* Tue Mar 30 2004 schwab@suse.de +- Fix merge error in selinux patch [#37431]. +* Mon Mar 29 2004 schwab@suse.de +- Fix hardlink accounting in du. +* Mon Mar 22 2004 schwab@suse.de +- Fix race in the testsuite. +* Mon Mar 15 2004 kukuk@suse.de +- Update SELinux patch to new libselinux interface +* Mon Mar 15 2004 schwab@suse.de +- Fix date parsing. +* Sat Mar 13 2004 schwab@suse.de +- Update to coreutils 5.2.1. + * Includes mv fix. + * Fix sparse handling in cp. + * Fix descriptor leak in nohup. + * Fix POSIX issues in expr. + * Always allow user.group in chown. +* Fri Mar 12 2004 schwab@suse.de +- Fix sysinfo patch [#35337]. +* Fri Mar 12 2004 schwab@suse.de +- Fix preserving links in mv. +* Wed Mar 3 2004 schwab@suse.de +- Fix help output from mkdir. +* Fri Feb 20 2004 schwab@suse.de +- Update to coreutils 5.2.0. +* Mon Feb 9 2004 schwab@suse.de +- Update to coreutils 5.1.3. +* Mon Feb 2 2004 agruen@suse.de +- Update acl and xattr patches, and add some Changelog text. +* Mon Jan 26 2004 schwab@suse.de +- Update to coreutils 5.1.2. +* Fri Jan 23 2004 schwab@suse.de +- Don't link [ to test. +* Mon Jan 19 2004 schwab@suse.de +- Update to coreutils 5.1.1. +- Default to POSIX.2-1992. +* Fri Jan 16 2004 kukuk@suse.de +- Add pam-devel to neededforbuild +* Fri Jan 9 2004 schwab@suse.de +- Fix spurious test failure. +* Thu Jan 8 2004 schwab@suse.de +- Update to coreutils 5.1.0. +* Fri Dec 12 2003 schwab@suse.de +- Fix use of AC_SEARCH_LIBS. +* Tue Dec 9 2003 schwab@suse.de +- Cleanup SELinux patch. +* Tue Dec 9 2003 kukuk@suse.de +- Add SELinux patch. +* Wed Nov 26 2003 schwab@suse.de +- Fix sorting of months in multibyte case [#33299]. +* Wed Oct 22 2003 schwab@suse.de +- Fix building without extended attributes. +* Wed Oct 15 2003 schwab@suse.de +- Cleanup sysinfo patch. +* Fri Sep 19 2003 kukuk@suse.de +- Add missing textutil to Provides +* Mon Aug 25 2003 agruen@suse.de +- Fix uname command to report reasonable processor and platform + information (coreutils-sysinfo.diff: based on similar RedHat + patch). +* Mon Jul 21 2003 schwab@suse.de +- Fix typo in i18n patch for join. +* Fri Jul 18 2003 schwab@suse.de +- Avoid abort in sort on inconsistent locales [#26506]. +* Tue Jul 15 2003 okir@suse.de +- make su export variables declared via pam_putenv +* Wed May 28 2003 kukuk@suse.de +- PAM fixes for su: + - Move pam_open_session call before dropping privilegs, session + management needs max. possible credentials and needs to be done + before we change into the home directory of the user. + - Don't set PAM_TTY and PAM_RUSER to fake names. + - Use conversion function from libpam_misc. +* Fri May 16 2003 schwab@suse.de +- Fix exit status from su. +* Thu Apr 24 2003 ro@suse.de +- fix head calling syntax +* Mon Apr 7 2003 schwab@suse.de +- Only delete info entries when removing last version. +* Fri Apr 4 2003 schwab@suse.de +- Update to coreutils 5.0. +* Mon Mar 31 2003 schwab@suse.de +- Update to coreutils 4.5.12. +* Thu Mar 20 2003 schwab@suse.de +- Update to coreutils 4.5.11. +* Mon Mar 10 2003 schwab@suse.de +- Fix LFS bug in du [#24960]. +* Thu Feb 27 2003 schwab@suse.de +- Readd textutils i18n patches. +* Thu Feb 27 2003 agruen@suse.de +- Per hint from Andreas Schwab, don't use awk in autoconf. (The + improved test is simpler, too.) +* Thu Feb 27 2003 agruen@suse.de +- Fix autoconf test for attr_copy_file that caused all binaries + to be linked needlessly against libattr.so. +* Tue Feb 25 2003 agruen@suse.de +- Extended attribute copying: Use the newly exported + attr_copy_check_permissions() callback exported by libattr.so, + so that the EA copying done by coreutils is consistent with + other apps [#24244]. +* Mon Feb 24 2003 schwab@suse.de +- Update to coreutils 4.5.8. + * Fixes bugs in du. +* Mon Feb 17 2003 agruen@suse.de +- Add extended attribute copying patch: Affects cp, mv, install. + See the cp manual page for details on the changes in cp. The + mv utility always tries to copy extended attributes; install + never does. +* Mon Feb 10 2003 schwab@suse.de +- Update to coreutils 4.5.7. +* Fri Feb 7 2003 kukuk@suse.de +- Use pam_unix2.so instead of pam_unix.so, use same rules for + password changing as passwd. +* Thu Feb 6 2003 schwab@suse.de +- Use %%install_info. +* Thu Feb 6 2003 schwab@suse.de +- Update to coreutils 4.5.6. +* Mon Feb 3 2003 schwab@suse.de +- Package created, combining textutils, sh-utils and fileutils. diff --git a/coreutils.keyring b/coreutils.keyring new file mode 100644 index 0000000..bb24fcc --- /dev/null +++ b/coreutils.keyring @@ -0,0 +1,1103 @@ +GPG keys of Jim Meyering +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.16 (GNU/Linux) + +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 +TnkVUAMK/I6f2VdwhfVyhaUPMsldfG7YgsLFAZk2POcUgKx5fxSkCbuR8JuACKzS +9VLRYpApI+sitMT+zoAaKEZYNRSWNvEvxGlmYklL/FpN8o/SjQoxg3yYMB6LGRiG +2+yr6cOsoYbCdkYHfbMKC003YDQc0x7JwoJqtcWgA99k6mToJuNjY3IuynvIH/WD +u4ci1tp2GIhGBBARAgAGBQJMNm3EAAoJEBBVNce8HC5gnCEAnjl5+RP/sJr6sEV+ +xenaqhA7x1G9AJ9aSVu+IlQuYocl6Kt+ZEIjT5nmGokCHAQQAQIABgUCTD2XbgAK +CRDsbnDffAimYoqPD/0UV4K/9ENdyc084RcDZ4OoUWfbwfNKUmOoNm6cFUr0m+lR ++NL1STRCACTblTuBRdGILYvAAOk/QSjJchtV+VwgJrnmcxJawVZqieb96cIr70rL +blLhU3ONoAe7HvLhNkfJr8TFWzOw8oEOFIMCiIOjkbzeTmaXcf0q6s3nCVXnhNUz +1VrTP2en5puzxTfjVmAF20hVOICsuVgFnVwO2DOAkel50eA3/19Lc0P4TYuOp5ql +lcl65y8yPSsX+DPJC9k5Wf3JuN6aXF1seo7soqXfabF8njqnpo0uZUNZM+HTfOr1 +gAaLiKYtDzdOsEsrfX0/JmJP44e7tqor+tP8etuYqfzIS9m78wfJv+RG9lR4kOhh +IGbf+MxjznmVX4Wf2yf8GEK/hxo0Td90OXlWQUR9JBZb9k2vcb26T5A9RMs0rSbx +JKj2NRJW9nTHAnhZgENXv4nO/wnWISVVjdcQIZJzJCNZzves/Tbw98GFHQwMjiFH +w2FET7J+ImFVnI/ooDApWsytdqqiXlhL4qzA3OvFDvHOpaqikf0XouwX834CN/8O +ukVByOWra0xlItjYePvCqocKNVtBRdDVIkPqf3FKKbPWRJPgY800Jt9hRk3BNSjB +u0TZUBCkIlL+X2KI/M0x/yIHnCKCrtwPA4zeCSav3KSUMA+bAEI1B9ymCm3rPbQi +SmltIE1leWVyaW5nIDxtZXllcmluZ0ByZWRoYXQuY29tPokCNwQTAQgAIQUCTBdx +PQIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRB/2fzLAAvu7kNcD/9WFW3z +QWqHf5mpbGQpLKGu3xSAEznbpzE+9igObP0UOxhE1F/cyZnUJ3j4NI2m6bQpxYuH +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 +L7lK987RIZayL0odb+oCJv+R9I5fu9Tt +=+qse +-----END PGP PUBLIC KEY BLOCK----- +GPG keys of Bob Proulx +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBFdggy0BEADFA8M0PxYhQdI9LlkkP3jfkDDsKmyofklaJouGHc3h+IjoXkdJ +A1C/UaEjaVLxb4aBm7znZrk44Je88MxidwCTeZwgJje2R397IKW3WtRtIfUz5sH3 +uEoO1AWB9U/SzbO/V7CueXO8S+UT9/kOWFAtRGceDzBEzXdnMobuBlUbKzs86QW4 +0kJEWc8I6dzdiLojabFYXWVYD+5VeiIsY0P4g7RZQ0pkurb2+py8XgsXTyuoljah +bHTp5Q7Ioyxeb25fIQ0rea9kCWbm9DNtyoFlmNj04+NPgYiHAtHnLrQSWWu87Oy9 +saVmKd+dJqvY48h15rYnm+A5llbqgZlq+dNsj6V6MPgToGBYcQtWJ2BjpGwJ7gfe +hgi1rAFNhDF/TbtlMBhumxW3YD/INVaI213u+21mMkOgRz5Q/iB9I+JtxO7SNWg0 +es0+7vTGWb6S5BAlWuMq0t8Zfx+s0qdPeeMhm4Qsgw62LoFlWeSN22/m5fWhtQOU +KhBt17q9XdI68Ixx+NqPxJefG6PVR2bobnYWpHBn5CTu8R3cfFvPHl5MDbcJVAOE +CYYaEq6ltGJ+k+Rytb9HEudBSdzDxad0udTk7FUMcnJXbgfOO+6FcgY9pwvcktqZ +uBCmkIOxUQGkmtYN5o+qO0ybkIXigZdCCmT1oIcC6n2c/RrhJhwimTZBuwARAQAB +tBtCb2IgUHJvdWx4IDxib2JAcHJvdWx4LmNvbT6JAlQEEwEIAD4CGwMFCwkIBwMF +FQoJCAsFFgIDAQACHgECF4AWIQRjsWaDhBzj3CXTxutCGvomOH+ajgUCXXga8AUJ +B/jLQwAKCRBCGvomOH+ajjBhD/4tDrr+VU6Lq7KkG74pTRW15Pfyw4gTy1yDyZyG +pptDEHPI4yzavs2vbpRLqMlFQg4rdBfrH+AeUfjGg8WFO0xfVqo57L/Ow5q90FoI +XsivZ0ZnJx3l4UIbR2TZpbhdCDzE8ccoK4u5eU8WsivoFAUTICT3af1jzFffX0DR +fSssvdjp5Ap6FoMpLhLRiXD8D+KYG03nM/EYnFM8WluHInYJ8nIlP+umPzuaYEio +nBuu6izOXiQ0er19J0+VEolmqshiL+XHltyjI5EfPxgCdOJiSVIxAFKK7E9uUyaC +8jIn8xUDCVELjfRhJIPYf+ea/TLn7VqpzDuQ1MjBkGBTNWhnk2SFisEh1tRiZliP +U5HINgpuGhp0dL5QgBzIz06CGd2nPbQIo2sKSnyx0tdm572kI2WxbJ4JJOwat5WM +6y6no5GmNU5zXi9z1/94PiMtXLY4y6BWre5Q4uTb60vxWz/mkwxm2z6IsHRev1y2 +m+4kO/NNZdYV2BBT+SXON+bRu/0BClG58zQNCKZl7A9Rxr4XnWvjANUYwPZWZkb6 +w8drYjF82bv9EfotZhtsRzFT/PFt9wErIsfrpLIf9KkIBZqGKuKOMckSa1cZL7UG +GfWLjhqIj3grYdxQRI34mOc4hAF9sqSTXw8sK23egFkNjmNYNsH+ETdYCl5Uvvb/ +eEJyYYhGBBMRCAAGBQJXYJESAAoJENKUXDvBNlC27esAnRDOPvu2SJ2l4YvLpl6j +qzf4r4sKAJ9GFzeofvcY/mZNrSb3jGE6SqVxg4kBHAQQAQgABgUCV2CuWwAKCRBE +jjgzAFuz8zEJB/4yZ4dX5AL5Ty4DGdfn8TnB4tP/FdO9573Jz1Toj7eXclNHuiUI +IkkHY8B1FWp9iWeJcmGQcjoPCgTIDFdAVQRqHNnq+LZvzONPIB/61MvD0bb9GC2a +J8uPxe6aDnTaStL07uy7S6dNY2MxnQWi0hhX2PVm838ClOv+dvPiKfzzFyjcsoDT +Jqxtlr6WwUOyAae9HDU1vkG8KkWVaXdERPYUNIfz/Zoqc36HFjc+PtMDP2toIJ2r +7kezmaNbanHzcS9AWYICjLFL0OgSfSM6Mdh8yuqB8kGTjH+ZOhtAL6OSdiLjf6AM +VfelVv7VrKK7swOMzE1ihH72ukWcTP2n96YTiQIcBBMBCAAGBQJXYLfwAAoJEEVX +DF7IPmq8vZsQAKHdWQ2Hdwd+500HfKd7hskTx9balcULi//sAam3hJPBcffgD7cl +Rd/Dn3CQwY3PYmKYUHIWXCkNCZG2g8jAUqu2SRdN7rsxbXHw4vvGAHCWZREAFowH +iMki1vL4+moB3vvCl0sA8svFcHMvXdzENXC45G/J/ew6cSWBY+vLrijal5YagoZt +oJ5D0WNDek/V1SDgsSO2Tv6IuQmojwTCpQ6XNH7FDYbhRRAmFf+qEr/JnVkcT/6Z +DkPj1X5Ufi4U8YPd/SMe9q2KJ7az0EZTvoDgjXxmjwAENeRvbdG+Cd3wjLaFqOlJ +WvQJYabiANlspRg+uhwghZUkuGk+eUkFpObyBXVmbM7zvYFy/6BTvOEE/m9w8nEq +2MgTOXuTvlMXL8IqPcsNnREd+bBpVXgiOw1fNB7DcxLL1Qgt78SOOrgzMLg7j3jt +Q5bL4Ag9ssLKsf1VRbJvHLg/fW5kQpAWaQJrwef3VwUMpYApC2Co/07YcNED8nub +3sBNcnzQL0seJqqPxMgeBNntnfguypfuzjA59REf8XvNeWVX41h94l8nKhQ/7a00 +UZD5c9zDoo1JYWKn7fQ8At/vplBMOhLM8H9dJD+D3I/pu0gKmFw6oi/n0ki+kj/z +84+JBtwILhN2maEg2FtAjFEUUcBg2m3c4mhgcCZJMBCI8BZa5U33XmLZiQIcBBAB +CgAGBQJXZJOHAAoJEPSVSpCAqyrSw8kP/Rm8+K/e0rJvwnvqEg/FazByux8nHc+c +oecpcgjZ3bchHpUuZ06JG3vFRgToasppinYv3AHFB6mtF01/eXKW/0wli7rvb3gC +g9f8H8NfM5jJzDJjNRjR+3oWWzEVzpQLIlpeQS31dRwBLHl7TWwkuTN1/llsA6mf ++OLvNXd4ks+K9o+nFWegRSD/owFzH4tg59cgAfERxTeEgwKGJV5GNbjotXJIS10J +quH4jfSoc48Yo73t6ALgaC4yr9V1ZhrTKoBU+l6bwDg7vIfMNDeH1FenrMvFGQUO +JM5VcP1VUS2eLz13L2DIXd3hmBUD3ua537dSDua+d4p9rDpibHTHKrJbs+WdPLJi +Fm2ARmjbCjGCXB7MMRa+PI0jyjZ784TqwHjCwOP+2AcL1DvnSDU0upKub6qtqU6w +2LIcLJilIxw27+Exr1ecflUcKLq3o2hJSzTUj+8nT0wQ3ie6lmfCl26RUQZRtGI8 +QtDQFxJ6D1GULC6njabPXpd5EeeRWizgFi5p9k5WuSm+lSeWbE8tRzLmY+Qfx0mf +TLdn2TnGweYJwiwLQRshzA9fLMvch8yHxGrGZUJ58zynsPKG1Mop1wnvytzBN6cD +ptYAS6Fy+d4B8S1h4rmio2wa5+M9lk6fNwmMBqfDNuHKlcuPzo0y2wTd6Uo/0iPr +FfO5ZVpJM2S8iQIcBBABCgAGBQJX6US3AAoJEPCV97sBj+KzLN8QAKeEVz0twtuT +eUD6fJWaus3vyViBlfzePvr8TAvhEsdXUkYQ/RwmSHVVZHRfuRYeEqgbm0PWWRkd +Drw37HcZd8AXE9SseRaWi3yUPbxTjqu1FzDXnUNvjnb3e/zNqTv54yd4NJrSB+6M +mFa/NnNTKls95O8H8jgL7oPL/SKO6ZjxdZiACFhLSsRwzx2Xmu+tsal3FGsUS0Qe +gxUX6Bu1ADs3Oih2Z8iJvFUy44YJkllMl6JhrhvgWnqjo2bG2535qAgMfOlkl29D +rF4PRLAe0MVKA9RhemKj0tfzJR95CWrKLR35ZOa9Au5i766LbzEItseap//APV++ +3QuGobV16rDGXOSTGgZ+xv7L3sideZZao8JQF9fK8LtNpxGz7Wfq8Vg0HWgJdSNJ +fM33Nt8VeAXbqYdpPto5dfZrfjA8c46ulrVGTqgTx1aWpV9EdyaIMLmYG1snMLGQ +1HrAw0owkQGIiF3AtWXgKRDGuJ3ouXasLBIAWyvVg25XknHift3O7cnWLMwSGnA2 +MRvp1DOIvzFriJ5mlzl/E5MBx2sVZBEqzc7I+K5MGfpkrFjyrmHy4PzPOgYAb6Hv +VBx8SSEWUhlL/HJG5Fp/nbm+FQZunhdZ/eHn3IVSUCj8Ags+pCE4hhMa9djfmR1k +46HwVqc4hc/HGWGexfpb61/hD0zH9zZfiQIcBBABCAAGBQJX7ABZAAoJENVHlGMn +ADo/FZIP/Ak2YNa8R15HqG5QRKrtiKC0+PDbjoB0/M/IGEjHEDxGd8xmZMzicxjy +3i2oMy7v+FlahdbgIJwrnNLzp+pE0BnSBL8x/cpsW3vPmefOc8kF3StCpEBKxCYm +y8eR8zkkqDE1fDrmkoFW+OnZzrJ2zOshn2mXeSTeAFvVZHqabZ29j7z+rI+LKfM/ +nhGICBzyPr6t7E1s9tu/XUUmQrwg5UAaqaRQkwNbWYXMLmlY6bEfa0X1I/6FLMNp +kIRc6FHDTEHL2ebgcEGzRrkPd6Pvz0Zr0pMT8WdptliVxMcdVG109VRQlbe9GyAo +zsERBixySox/Kq+ztongfFrpqh7lTsZ4hYlE0RklJBKUVHjSx88r/xBGV0Ga/Q5d +pT/zXhWH8HZ1CGm3IBcli8QgZpwXCrGr97BHzi52fsPO2kefRGDiwjLAPLyoogWV +hDBVxNIp4qvCrsqyJ02X381ZimxDo7gJxhXF0U/CLhKgoiS/Ksjz3VAzsPiyf/Kf +pFJ4CYBTRcGuuqaU41+Pepvk+HLxSFW2zTrWIFruGcchh2fLMSSBqbri3pn7Q9lO +GJnbNJYIUBKFYamXyfT2G8+jnyrfX9QX2PGeWrn5dpmWn7SW7AVZfTIxlbuEHpw9 ++kBDT2ZD9PfDJn3MGdZh5QgKeja/66nvH4R2GSLXLQeDwpP23DeoiQIcBBMBAgAG +BQJX9TnzAAoJEBv4PF5U/IZAqLgP/0sTdI4GltFzFV36LXKuSHn3y/mavky+rXui +ouAhVYtXXJyQoANUmPun66GzlV9M4RWJJJfIlhrNisWKJ7Xim1q0knmO7FF4G1Fu +HuAxQIEtXxs8XStXVdHLN6wgdAEseNozywJqqXdq6A9EMvfg6oo2otNyHp9bjPy/ +J9xb8vc5Pr+C+fTTNiG1YmXzuqQO6eYVioJ4OIPOmWA+hD9Tp7LfE6/O+HfK/iRD +KEhf2tdEwf9As3V+K1p9q/9kX35cKrt498V7uOaPjhkq1eRbu9p7i3TP1Jy8lf0W +DEdiDX+FmlJD8dtPB9xpY/E9PxZWT54s7mP4x6JmLKOg3iFBN0lHPD3jl79eJMkJ +7DvLTT7nORyy9Pyre97ZWPEhs4y63DNjEtwgP1I2D9qLprwQy5vv+FUu/CnwZVBX +1ggltabJ5RafVF0fkRSNFhwq3Z4zN77rKhdpkjlGqbY4AQffqMcgtScQHvQDH2th +JYn0XkCGqjWhjFs8XXcIFUTuDg+o9Vz5N6LsZUzby4CSaUSue9/m3USB7X4f27KR +yIO/kQSa0AEZTiDoaN3NzEp9o12UXMEbxk/K9Qj2IO+tfE9ToshQ4baFprsqZV7O +6pzqUKvgUaJVkb1Qq16WkXfYqoFOJZBAn8FzyH95BcMLpNbAw0a9cXRT29zO47Bj +jFWf1cL1iQIcBBMBCgAGBQJY4qiWAAoJEE3gooj4qgph85QP/1Ane4eUF6Laz0t8 +AVGXW9PNDQ10K4F0+o6cKsjCjifUoAtcFB4KWpO3dEkujfYWOurnEXTDR3Ez0+ga +dtf/jgEsAdG38r18uyJLmGaHspcKARNCE4JXKXNEY0oqdvpBPh7jWOKP2Hy181G0 +xRTc1DQfeiwwwa+8szzOTtMNCY6HRzM345IS8vQRFDWhpN1Ugdmkmd7iVnjrVbCm +wb16kDG99BDyAVzWiJy//xPpPR0pJI0Gsl3jem3CejwdxH3MUzlTMcRIZrOpZPut +XYiE41kg3qOFktSa6gXtjIVaJw0CePaoDO7ttqGpx+D4L8lMLut8Mjlz52WZ3c1t +mBSSy/0Dy8ERy0GNOgP5LZ6nLCXvht2nc0EpWw3t//SN+nKKG3S/9CwIc+FJ433D +gkJmbOHowjvuRAHUXQehu8S09lpKiU6ajnub6Ib9x2p59u2UVIrIzjG5Q0QK/KNT +aicLoCXATIFhnkdkUQDNWrm8aODORSorQ+F/1gr/1lvvgf1rs4a4DCpN+foHd7Wi +82xZxLyeH5hBqFop5Y6t4hnG0nqmhnfj47/AvyxnPiHUojhkgMT4DqSig3WTET36 +Ln3TQc4cwttReNCDd5wHB9RyGGu9DOCRYBckZE/dY77RAykM7raviSVX6R19ElYz +G6pM+Dix93UMovpn9OSZuuHIIQrFiQIzBBIBCAAdFiEE6FpfY7MdJMHr8NgcyRDZ +IiUS48cFAljj8OUACgkQyRDZIiUS48doLg//WAsI1RtnR0J+MHccBy/3I5BdfHON +bsNnpOcMrROv8+at4McukNo6spiR1ltxlfAcFO0PPM3neFyxYTBB6ZU8g5J8CRSa +BckeQ+bdvycByh6MBbt5vgjtAGO+/Bp9xaIBlOFXjtkUvhbLTr8ybMjhhkoH4qRk +nJ1bgIwbAhQqHRmYRFI6U1zlpF089uU5ontUMcYMfH9gf48oX5tKnwXkkobmw3qE +lPXMC7YRnBMQmbbEEN2JVgPMD+NXrqXRYtK0P/Oe2lhu5onZmFba1sPNmU2EMUqK +Os4I2MOlkIRmLKnnf41BUeVu/Dec0rPDhAvfEW2CB4Ad4F7dBCQztTlncLMrtYSI +c4iR8qoYmDZ1IOswodXmTgZQJlkwa7TrJjvfScqH79/Ny21H4YWz9GNm6Jg1l1yA +Tnbk9BmCixr8eFk8dZR7Ttl9bH3ntsqu1XvF6CKFQCVgR2YS/OGDnhX7S+9wQewX +pKSQG9HU/nPnxcl0odDU3YpIApOGxbRoDqVeofnyMISgpEMCec4T5yP6BOPPClRh +DQITYMfhpJ7FjM5/kIAWLksbLX4gmZzfqKliGvrrvtd4fC26UU1ZZtq/qx72yOBb +3Oh4JmZKd6P9qJF3wBOFeFDwIc1hrjRtNTH41cMBEGh6wA4TjYsGOz4uWFYpZmLQ +q9/bgxiHvOZXqR2JAhwEEAEIAAYFAlonYkUACgkQfiz/2w+KINpvsA//fliK4oAk +AwCTx4jmZ9l35ZgpFKzd3pGeL+yP1k1O2laSnqobK80I0SnF0azNJDkAkCgz81aO +eMcDVbrJWS9vbRN3+O3HRLEXte2QWWErnmm9JoDm7MHG3gVMGfO26MVCKFbhc15Y +lRkJLYkHLC2L5HL08+5DPLPNNvycZFovjJK5l5ofUazZV/1ddiRIqFtTwTmkGWQS +iXLpfLieSBdWyWu3X4oh0Ajt+Kx3d+v+oBER8llhseCpIzgXrMhkgksfpkrtrPlg +RpwhykVmVE17G/LKVPPw7g5xLbjKhSY9Gh7X3gt1HO5vHZTtbM+34goYZGTt8z0M +i119fx6fHHjl3Vg62TFoPWwPmczJOINMuSI1F/Wfqfgg9w1oKd6j5LA20znCkCNL +fLR5vm5LVBA4gjsNdFSCiUw1FRjWIiIGKV4fEXCFgG7VfwcpW0giRjkP3BoTm/59 +ib2t8jxPyEWr/uZptOUt1ImCd7vMSBM491RC+Rn/Ixto8EFlZzeOugFUJQBgGMWL +W680ClMvIPGStn09xep4lAsrt3rlm6+WEVsxF5IdZxhEvolaifyw2vGNvHds3JXd +U9ed6/F6AMgKtEPJX0l+CKrIxk+JU4anLkCp+tzWlY/r1RSf9PTxsqEdtlB2/QYy +4RZYOQJj9LrQKBo7DcfJQDaALZB2fXC94+aJAhwEEAEIAAYFAlq79QAACgkQFwrw +4pVCld8zYw/+ODPwxvvpzd85zFSnFCKyfQ8+vn3+GhAQXBivarcpWCi12Vr17u3+ +7b0oNvsXjCsNUygfhwB/LBz5OyIG2818W5BxtV7GlbcI+15AiT/SUGBbhs9D+UC7 +P7cq+0U/cI9iRxmXVDp347N85abjtSU2eoTL6iiZN22RPrCGY+OquuI7YnJd5pdP +JG5UGB0LvdnhDjcYnLA+sSgPxYf/wzSyplgjdBLyPY02CZ/7Z2v998k8Nqu8tpOU +UUrJm+EyUa9dxdIGMupMSE4FL6ffUaA48Sd/Y+yBM4DUqXvzH93VIjwhzAqDfZV8 +ZtLR9IGIM0Xfd/fDNBOxRIk6H/rnmDpa+DvDRNsClcoN2StLSnpM0LfA4DDcpjZx +GKKUsZI7wqGzwtHanRpShzka4B4liLFSWRmGOQhkJa1eoAugeaUP/Iw/VotBfpuo +kFZD8XeC+/BQ8P14xdvgYd/8KRM0kt39O45+1aiHjBowYczf2vHaQm2v+JBMkmPG +OtIcfFp2K1i5M6T/ZJfzmxRT4Cbw5FGDexWOHYqF1juGdYxs2w+K4qAsUVcttICX +E6w7nR45TIbRH/8ug+AzZSe5z0aDGS5vSLHfj3n4BbBN++meUfNr4cus+8lCsDML +oQDicfi4mQZgGpbPPE+jgFRWCDSnk7P1Ka/NZNWEUoX+2ZjsGh3yOQaJAjkEEAEI +ACMWIQSrQcHGiv1mjKBF6/hnOgPkwduSHwUCWrw0EwWDA8JnAAAKCRBnOgPkwduS +H9nXD/9YtfO6iPE/PT88Pny//hlmDwQBU6uqUOraIduxKx7tsEPIjKqAg10o3JUR +gjswL5OTsvGkjQ0iJyF52VLkDwS0f3UzVPI6GdU/HcLl+XJbFIFid9qVA+9cyL8/ +1ftgI/2cwWe9iassEcOPzVrGisFKJTKixP4uERDQkpOFZN1hnAIfKs+gFozFo+ir +25u6aL9joGkahWBVitcYAuaI52L1PPFjP4V6Enmtt7r7GyHNZq39e7ah9omwMOjQ +QtYZ5PfyP419wgCnVCTEX2fS/VEnZbVdlLzRrEtSHacdXQNPCE+JuHmuWcqvmH3u +27aivOQk6HqvwcPfRcl7615EDKMu/iDSNGfX7Uaw6Hio7xGXlE4DUSAG6gpWFdZ5 +afZmKxK74fxXK/Ft3IEJDCSnw5mEX98HnFa4BECmnPQtOPZ6JlzkK9J2INDZrBFT +z6EQbLBFHKuNk4KhUxiXYH1N1dheMATa4I9uljwnijaNn+93ojXGfnGxtR5vF8/7 +SUgTAqT2JgYRSaPsYXBnkni3mpv7o1Pfss5OWI3NUShCzwIcaJiimp9Unu5HzwE3 +IqpF96una5MUR3kmDbF2792grnsI2aDfweIhKR9p+mcM/KzAI9P9PQUpd4kDex2z +0giGhEuBcdvlOgI2rGa7J3V+sn7YYyDNfxkmyq7ic6pAIpiIP7kCDQRXYIMtARAA +nczW3+KTPeCM0QspP+pTs7nWOde2YovoSkXlw7NGKmIUcAu1lXGyOAkVyQoN2Wbx +kwj2KOZl7cdC29cexjD+bX/MrW3wExDZO0O2R4PwJwVsgQOA8Yw3DD0HSgQOnW4Z +mhWsH0VWVssfsGUZVSc41/2HCdF+S/ZnueBqno4AZ1t/ZchB7C5jjW2W7At7AHqq +YrDGYENOo1/tkoUs1Q075MoVlj5AE0WnXbBoXpuZSlkjniC95c0sIZXInQ/bGlIQ +W2bJxa6QVSlSvBtg3MFniK0IOLtXL0nj+ujo1bx9dJIX8DtzOW2TB41tNo238PMA +fAHd6PRnrcRm5ZzhuzDMHaTWP5W3CdyKZCALBD6bUajRvtulfAEEgAw5OYiZr78z +Mv7t7jSa8U1bXMtptrHkaHhdaADCTLd7LimMmgQTTSqpym0EnfyuOK99bwevyuOX +nKaGaNmRUVeXgsE7jlDMp1dKdgKvAEJZCsg8H7s3WZlMqoqGF8v2c6qpKaQSOm7I +k1OAqXUvJR1jzu6CEDs7y5Vq8I7ROfNNDQcOABO4PfiMYBT2XWxVmhpMgC/5Aus1 +jJRETqIDTogx7FpjGa0l1QBibVTji5ZMSP6NIwRSjSuYQ6lc1eUvcUU2pGVVHEOw +Xne+f28/DJytzRRDijB78d9ryLbHf3IVyuV41NINqbEAEQEAAYkCPAQYAQgAJgIb +DBYhBGOxZoOEHOPcJdPG60Ia+iY4f5qOBQJdeBwxBQkH+MyEAAoJEEIa+iY4f5qO +rfcP/AlVGya8U96pr1nw7J7i0tAl6jDU+zkwBpHYJNiYf6R4xOZFrbY83JuOree0 +oWdTMtJDigsHcR+wsoR5o8pIf9+TeKmaO5j/MNOGE60EDxbQ3eqsH6YC/DfojR2D +sP1YVJqjfnN7DpRkKpyPvbUuGNt2zU0Rvtg1D4nkHLT4prFhbk47l7Go5OKt7gB7 +xT0pMweJ6wpKw8oaIxwQfAcfIwPMPgQb3DDUxUfWPySuWRW5o6Ja/2N5X7GDZ7AG +T9BLnMbwSky5H6Wj+//upfMQMjjSA5iCGrodYTxdH76ZaOPGfYqzTnFWROGNoGEK +gIYeXfdncdpl/I2wWv3w15uwPdiBWnr4ta+VdEf6dZ6P5u7rdgskk2Ycfo0/EXz2 +g0e92oUD6JSGf/7p8oM1pdISUqj7AcLcuWkeCbFL24Rjg0sh7GrQW6h/tuJR2Kic +2J+UZhytrvswhB4Hi+ulgd4/IeX9u9bGlLt5VcHxjM8V9ZzHxFgUx8GSc43vFbXS +TC5UNBo7T8Ltr1uxyYgfqaKnS+sP9tjAMAP9A128ccxvmqBzAHWuJdcoX9wvMZFv +fN7ulnarYoOjiU1oKupA9+/xXXG/mnkTJbDgQudcUVhdxC1lf4KlfHS/fPl+/i4N +vvxld/B1O2f3wUJk2EmW0nUfxtT+rSTWwUgOU8l4AYOD0IGC +=lMPX +-----END PGP PUBLIC KEY BLOCK----- + +GPG keys of Paul Eggert +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.10 (GNU/Linux) + +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 +WtkGoi8buNcby4U= +=AL6o +-----END PGP PUBLIC KEY BLOCK----- + +GPG keys of Eric Blake +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.10 (GNU/Linux) +Comment: Public key at http://people.redhat.com/eblake/eblake.gpg + +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 +=FC1k +-----END PGP PUBLIC KEY BLOCK----- + +GPG keys of Pádraig Brady +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.11 (GNU/Linux) + +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 +Nwmjme97uBlV6LYXnlGm1B0= +=BG/W +-----END PGP PUBLIC KEY BLOCK----- +GPG keys of Bernhard Voelker +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQENBFPirzMBCACyzYldTjQ4ufFOkByY5Nn5USb5GFoL48nWBwNHjd9KUbtRRNlQ +iPNKd6hKGvd3BGi5aoFKA4ytfRk6jbAbW3jVb3R8wYaV08mOy4KVEKxqN4bxsXlM +jNChXVR+rtKDmfI+oPTL+cPH2X6gW4W02IRbVw0uUhNm6zEedC/gNrY/mTlf1enZ +46jxZ7BTUZaG+kx38UMISIMBzSzLRtdkwgmHj4jS3p1fF2cwRqLclIfMjKGpbNFP +EXeXKWrCLcqHw78795eAR9q0YvrDkfInGdDBwfb3VM4NdulwIFzvYZMSXvSbbyPL +B5YkHU5aAWQHUse4WlfT5ccDpbzUYldRAvF9ABEBAAG0K0Jlcm5oYXJkIFZvZWxr +ZXIgPG1haWxAYmVybmhhcmQtdm9lbGtlci5kZT6JATkEEwECACMFAlPirzMCGwMH +CwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBGUC73lpFxle5wCACCdbs0QaJ0 +vR3Sff2cKdTk41rUq3YfWngsR///IOU0C5DdkePmCnJE/lUsUy0LRTxcUDLxQR+x +QHU8ssRT0JUO9726dI3miy36UdsgmBYaOtLvQcidGmW1R7o0PYYf04+TFtyqKgng +OUBPpMgR6o4UsQxy/OD4bN1WDqOgIjL+D/qJpkKmgp6L6+hhaBCpiOFKRmmV7YyQ +3SqVlfQNiHs5ZtkRnXpIjgZARV+GllKucI17bO0CGmTJZ1tstVy0+W3DQT1lbBkT +Tc++5LONM99D3jjn23l1ocOpfolR53F7I4cb2RNfT23v1I59RH37lB9wMOqrKj0U +jYAC2YoPGQ3BuQENBFPirzMBCADXLWWpQihBldY6reca8ZKdc3T9qXEOa3akE3DW +KztIBmNJhtYOjmpLYajQTkGa7UoJTnbmZE2Rn6ZEoNnvb0gcFNAIcY95KOI+bjOR +8HEgh4cx2REXh6L6olIgyXqt/KFusE4wtVZAFxZl+30HzN6nD+1HvrjXxPJRX6Ms +IYOYyyX9/6OofwJK6QHODYGp8WL2olHDnmsXg4AT6Wlr7qKpKrQELlcFR4xkvdmg +L/Ghw/tK0yJTxMIcewCCZWLPOXRmFRbvAadZWPAgVsJ63siNyUlVnVMSzDgTJl+s +l/DMabXpqrJQx3/1Yy6mTaDs3XZT/wmBKaTLXx/LByaPxQQ7ABEBAAGJAR8EGAEC +AAkFAlPirzMCGwwACgkQRlAu95aRcZWVPwgAqZT6iTXkoP37wYb41323RzhBcJ8J +Sk4cyBDBUXX0lMrM3qhiClKG7phpxVdu817Gwc6Hsecg7FfjQAV8MHQ0ZFeEFdk3 +b2rKBqfsStc+h49/xF3Fb+ifCzR9qeQF82fMSxkg18++7hMcHCMO/hPZ/Q0xRi+l +rSr2QKDJQuLzSyVU14TxrCkevZjEhtmaVNvcJlJzCbiBXee9Fpc5jITUXPFG8E8d +xqo1n+duOyIMgozrAnzP7X5V/Ob/Ozf/aGGX9+JdinyfCX18nWcHALKMU/36Eua/ +ylalf/2c2YkBp9KCLVmGgPkUgW52EeRPgroIsiwu+rwCSV6ZUyCJ+OymCg== +=d/K6 +-----END PGP PUBLIC KEY BLOCK----- + +GPG keys of Assaf Gordon +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +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 +sXIfn20oPsBb1eNT2ii6eOVrss3UnQL71lz13spx+0KC1zZx1BivN65BUUsjGCJr +twyHW3cWDNt6w/LYg6kRiu19daAfDf/BzAb/JCs68osdT0tfznEXroppfjENWJ5y +w5P5+8KTRwW1skqS8UsEJwvh6PgtGLCK8GLTC703rfTXAwDDsVDwABOxi8DXx2Le +OvmSc3zAOWvBIGdTTSV4Ko+LV5jTvTfK5kyx9dCVqeL9d+OhsrrybJrymzkqIH+n +3BzoOLAqIf9zLD/6W29vwrrGlYoQ7LfzcidVayDyhgh1PLXleRf4F7g3rpNplSiE +Ne6FNGpYBDw4AgQhlEhj/j7nNa7GXKI07hUkpi2qAgr/PKKS4jtYg+w23d/PPRTv +DNYd8voK7dC8Zl92JXLOvX+cIio4hoa4Mahi14DJyCAdCPN5KqgTuQiZJl/OvNS/ +QUVuvDTFo1Z1iI+zf8OA51W/zEMdP15tABEBAAGJAiUEGAEKAA8CGwwFAlqEwRwF +CQqJjJ8ACgkQKaeU/SJyvIamOA/+IPGNjvpKSxBU3jfsN4a1kGpWTbfTnsAz5n8O +d9P0t/B/ae11x5f6Qqar8exfeLdZbjIOIHBkhkLNNDieiZg9liLI+Qm3o07dyDKi +uIu/ZY8rJdIsp6TqXyG7CiXKLc1g9H6jbueDdhPArfFgk1jD4Sb4H+zFFI1E89cL +8KnyoDpZCqImRvFOCLZmtQUTtcE/bfhp0C5cq94BA//MOWLGhsF0Oeo49YjRB3pc +UrND3YNoWEewPD5jUD3uR4VLfY2hdJRqVY19TPx+bt7vhMtEIly7x3DZ0rEx4ab8 +Mb6jJ4O2qWS5KGDE5XyJx0gnNYs5WJWm6ragmKjZz/ABMOmyiXX3T7J030X5F27x +PLjqyYudtRG9rOWAu4W+1Om4Lqwe8ftP6NEI4E2fXoyWxzKyUJxGLIsBttJdgrwr +gD/JqWz81jSzt8VTFulbgjZyyfuVziPVYM8k60apxjiFN2TurW8NenRWsIFXakQf +aow9uB3N/4lWlub4PaJ2Cj6wDFbj+h5KO3hCvmdXyFGZVw2yS3Whk255fzlSCrA5 +7q40CEevoTzUW/0WOukCSWMbahagGgR42A0gI5Ni739EhPuuKiGqGZYBpghVUroZ +ekL/VrSWdZqaeWfWeT4Bcf5BlMM8vVoTpTIxgDZaER04L1KMmEsX8EwTLlzRSaC7 +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 +=FsuN +-----END PGP PUBLIC KEY BLOCK----- + diff --git a/coreutils.spec b/coreutils.spec new file mode 100644 index 0000000..4aa1117 --- /dev/null +++ b/coreutils.spec @@ -0,0 +1,321 @@ +# +# spec file for package coreutils +# +# Copyright (c) 2022-2023 ZhuningOS +# + + +%bcond_with ringdisabled + +# there are more fancy ways to define a package name using magic +# macros but OBS and the bots that rely on parser information from +# OBS can't deal with all of them +%define flavor %{nil} +%if "%{flavor}" != "" +%define name_suffix -%{flavor} +%if %{with ringdisabled} +ExclusiveArch: do_not_build +%endif +%endif + +Name: coreutils%{?name_suffix} +Summary: GNU Core Utilities +License: GPL-3.0-or-later +Group: System/Base +URL: https://www.gnu.org/software/coreutils/ +Version: 8.32 +Release: 150400.7.5 + +BuildRequires: automake +BuildRequires: gmp-devel +BuildRequires: libacl-devel +BuildRequires: libattr-devel +BuildRequires: libcap-devel +BuildRequires: libselinux-devel +BuildRequires: makeinfo +BuildRequires: perl +BuildRequires: xz +%if %{suse_version} > 1320 +BuildRequires: gcc-PIE +%endif +%if "%{name}" == "coreutils-testsuite" +BuildRequires: acl +BuildRequires: gdb +BuildRequires: perl-Expect +BuildRequires: python +BuildRequires: python3 +BuildRequires: python3-pyinotify +BuildRequires: strace +BuildRequires: timezone +# Some tests need the 'bin' user. +BuildRequires: user(bin) +%ifarch %ix86 x86_64 ppc ppc64 s390x armv7l armv7hl +BuildRequires: valgrind +%endif +%endif + +%if "%{name}" == "coreutils" || "%{name}" == "coreutils-single" +Provides: fileutils = %{version} +Provides: mktemp = %{version} +%if 0%{?usrmerged} +Provides: /bin/mktemp +%endif +Provides: sh-utils = %{version} +Provides: stat = %{version} +Provides: textutils = %{version} +%if "%{name}" == "coreutils-single" +Conflicts: coreutils +Provides: coreutils = %{version}-%{release} +%endif +%endif + +# this will create a cycle, broken up randomly - coreutils is just +# too core to have other prerequisites. +#PreReq: permissions + +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +#cgit-URL: https://git.savannah.gnu.org/cgit/coreutils.git/ +#Git-Clone: git://git.sv.gnu.org/coreutils +# For upgrading the upstream version, increase the version number (above), +# then remove the old tarball and signature files and let OSC download +# those files of the new version: +# osc rm coreutils-*.tar.xz coreutils-*.tar.xz.sig +# osc service localrun download_files +# osc addremove +# Then adjust the downstream patches (using quilt). +# Finally, add a changelog entry and commit: +# osc vc +# osc ci + +Source0: https://ftp.gnu.org/gnu/coreutils/coreutils-%{version}.tar.xz +Source1: https://ftp.gnu.org/gnu/coreutils/coreutils-%{version}.tar.xz.sig +Source2: https://savannah.gnu.org/project/memberlist-gpgkeys.php?group=coreutils&download=1&file=./coreutils.keyring +Source3: baselibs.conf + +Patch1: coreutils-remove_hostname_documentation.patch +Patch3: coreutils-remove_kill_documentation.patch +Patch4: coreutils-i18n.patch +Patch8: coreutils-sysinfo.patch +Patch16: coreutils-invalid-ids.patch + +Patch20: coreutils-df-fuse-portal-dummy.patch + +# OBS / RPMLINT require /usr/bin/timeout to be built with the -fpie option. +Patch100: coreutils-build-timeout-as-pie.patch + +# There is no network in the build root so make the test succeed +Patch112: coreutils-getaddrinfo.patch + +# Assorted fixes +Patch113: coreutils-misc.patch + +# Skip 2 valgrind'ed sort tests on ppc/ppc64 which would fail due to +# a glibc issue in mkstemp. +Patch300: coreutils-skip-some-sort-tests-on-ppc.patch + +Patch301: coreutils-skip-gnulib-test-tls.patch + +# tests: shorten extreme-expensive factor tests +Patch303: coreutils-tests-shorten-extreme-factor-tests.patch +# Stop using Python 2.x +Patch304: coreutils-use-python3.patch +Patch500: coreutils-disable_tests.patch +Patch501: coreutils-test_without_valgrind.patch + +# Upstream commits (squashed) after the release of coreutils-8.32: +# [PATCH 1/2] ls: restore 8.31 behavior on removed directories +# [PATCH 2/2] ls: improve removed-directory test +# Remove this patch with the next coreutils release. +Patch800: coreutils-ls-restore-8.31-behavior-on-removed-dirs.patch + +Patch820: coreutils-gnulib-disable-test-float.patch + +# Avoid FP error in gnulib tests 'test-perror2' and 'test-strerror_r'. +Patch840: gnulib-test-avoid-FP-perror-strerror.patch + +# ================================================ +%description +These are the GNU core utilities. This package is the union of +the GNU fileutils, sh-utils, and textutils packages. + + [ arch b2sum base32 base64 basename basenc cat chcon chgrp chmod chown chroot + cksum comm cp csplit cut date dd df dir dircolors dirname du echo env expand + expr factor false fmt fold groups head hostid id install join + link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup + nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink + realpath rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum + shred shuf sleep sort split stat stdbuf stty sum sync tac tail tee test + timeout touch tr true truncate tsort tty uname unexpand uniq unlink + uptime users vdir wc who whoami yes + +%package doc +Summary: Documentation for the GNU Core Utilities +Group: Documentation/Man +Provides: coreutils:%{_infodir}/coreutils.info.gz +Supplements: packageand(coreutils:patterns-base-documentation) +Supplements: packageand(coreutils-single:patterns-base-documentation) +BuildArch: noarch + +%description doc +This package contains the documentation for the GNU Core Utilities. + +# ================================================ +%lang_package +%prep +%setup -q -n coreutils-%{version} +%patch4 +%patch1 +%patch3 +%patch8 +%patch16 + +%patch20 -p1 + +# +%if %{suse_version} <= 1320 +%patch100 +%endif +%patch112 +%patch113 + +%patch300 + +%ifarch %ix86 x86_64 ppc ppc64 +%patch301 +%endif + +%patch303 +%patch304 +%patch500 +%patch501 + +%patch800 + +%ifarch ppc ppc64le +# Disable gnulib test 'test-float' temporarily as it fails on ppc and ppc64le. +%patch820 +%endif + +%patch840 + +# ================================================ +%build +%if 0%{suse_version} >= 1200 +AUTOPOINT=true autoreconf -fi +%endif +export CFLAGS="%optflags" +%configure --libexecdir=%{_libdir} \ + --enable-install-program=arch \ + --enable-no-install-program=kill \ +%if "%{name}" == "coreutils-single" + --enable-single-binary \ + --without-openssl \ + --without-gmp \ +%endif + DEFAULT_POSIX2_VERSION=200112 \ + alternative=199209 + +make -C po update-po + +# Regenerate manpages +touch man/*.x + +make all %{?_smp_mflags} V=1 + +# make sure that parse-datetime.{c,y} ends up in debuginfo (rh#1555079) +ln -v lib/parse-datetime.{c,y} . + +# ================================================ +%check +%if "%{name}" == "coreutils-testsuite" + # Make our multi-byte test for sort executable + chmod a+x tests/misc/sort-mb-tests.sh + # Avoid parallel make, because otherwise some timeout based tests like + # rm/ext3-perf may fail due to high CPU or IO load. + make check-very-expensive \ + && install -d -m 755 %{buildroot}%{_docdir}/%{name} \ + && xz -c tests/test-suite.log \ + > %{buildroot}%{_docdir}/%{name}/test-suite.log.xz +%else + # Run the shorter check otherwise. + make check +%endif + +# ================================================ +%install +%if "%{name}" == "coreutils" || "%{name}" == "coreutils-single" +make install DESTDIR="%buildroot" pkglibexecdir=%{_libdir}/%{name} + +#UsrMerge +%if !0%{?usrmerged} +install -d %{buildroot}/bin +for i in arch basename cat chgrp chmod chown cp date dd df echo \ + false ln ls mkdir mknod mktemp mv pwd rm rmdir sleep sort stat \ + stty sync touch true uname readlink md5sum +do + ln -sf %{_bindir}/$i %{buildroot}/bin/$i +done +%endif +#EndUsrMerge +echo '.so man1/test.1' > %{buildroot}/%{_mandir}/man1/\[.1 +%if "%{name}" == "coreutils" +%find_lang coreutils +# add LC_TIME directories to lang package +awk '/LC_TIME/ {a=$2; gsub(/\/[^\/]+\.mo/,"", a); print "%%dir", a} {print}' < coreutils.lang > tmp +mv tmp coreutils.lang +%else +rm -rf %{buildroot}%{_mandir} +rm -rf %{buildroot}%{_infodir} +rm -rf %{buildroot}%{_datadir}/locale +> coreutils.lang +%endif +%endif + +# ================================================ +%post +%if "%{name}" == "coreutils" || "%{name}" == "coreutils-single" +%{?regenerate_initrd_post} +%endif + +# ================================================ +%posttrans +%if "%{name}" == "coreutils" || "%{name}" == "coreutils-single" +%{?regenerate_initrd_posttrans} +%endif + +# ================================================ +%files +%if "%{name}" == "coreutils" || "%{name}" == "coreutils-single" + +%defattr(-,root,root) +%license COPYING +%doc NEWS README THANKS +%{_bindir}/* +#UsrMerge +%if !0%{?usrmerged} +/bin/* +%endif +#EndUsrMerge +%{_libdir}/%{name} + +%if "%{name}" == "coreutils" +%files lang -f coreutils.lang +%defattr(-,root,root) + +%files doc +%doc %{_infodir}/coreutils.info*.gz +%doc %{_mandir}/man1/*.1.gz +%endif + +%else + +# test-suite +%dir %{_docdir}/%{name} +%doc %{_docdir}/%{name}/test-suite.log.xz + +%endif + +# ================================================ + +%changelog diff --git a/gnulib-test-avoid-FP-perror-strerror.patch b/gnulib-test-avoid-FP-perror-strerror.patch new file mode 100644 index 0000000..853e84e --- /dev/null +++ b/gnulib-test-avoid-FP-perror-strerror.patch @@ -0,0 +1,101 @@ +Avoid false-positive error in gnulib tests 'test-perror2' and 'test-strerror_r'. + +On openSUSE OBS, the above gnulib tests fail on armv7l. + +Corresponding report on the gnulib mailing list: + + https://lists.gnu.org/r/bug-gnulib/2020-08/msg00220.html + + From: Florian Weimer + Date: Thu, 27 Aug 2020 09:41:34 +0200 + Subject: Use-after-free in test-perror2, test-strerror_r + + The problem is visible with glibc 2.32 under valgrind: + + ==20== Invalid read of size 1 + ==20== at 0x483DAB4: strcmp (vg_replace_strmem.c:847) + ==20== by 0x109414: main (test-perror2.c:84) + ==20== Address 0x4a1a3d0 is 0 bytes inside a block of size 17 free'd + ==20== at 0x483A9F5: free (vg_replace_malloc.c:538) + ==20== by 0x48E2134: strerror_l (in /usr/lib64/libc-2.32.so) + ==20== by 0x109328: main (test-perror2.c:72) + ==20== Block was alloc'd at + ==20== at 0x4839809: malloc (vg_replace_malloc.c:307) + ==20== by 0x48CA03F: __vasprintf_internal (in /usr/lib64/libc-2.32.so) + ==20== by 0x48A46F9: asprintf (in /usr/lib64/libc-2.32.so) + ==20== by 0x48E2184: strerror_l (in /usr/lib64/libc-2.32.so) + ==20== by 0x1092E2: main (test-perror2.c:67) + ==20== + ==20== Invalid read of size 1 + ==20== at 0x483DAC8: strcmp (vg_replace_strmem.c:847) + ==20== by 0x109414: main (test-perror2.c:84) + ==20== Address 0x4a1a3d1 is 1 bytes inside a block of size 17 free'd + ==20== at 0x483A9F5: free (vg_replace_malloc.c:538) + ==20== by 0x48E2134: strerror_l (in /usr/lib64/libc-2.32.so) + ==20== by 0x109328: main (test-perror2.c:72) + ==20== Block was alloc'd at + ==20== at 0x4839809: malloc (vg_replace_malloc.c:307) + ==20== by 0x48CA03F: __vasprintf_internal (in /usr/lib64/libc-2.32.so) + ==20== by 0x48A46F9: asprintf (in /usr/lib64/libc-2.32.so) + ==20== by 0x48E2184: strerror_l (in /usr/lib64/libc-2.32.so) + ==20== by 0x1092E2: main (test-perror2.c:67) + + I think it's the test that's invalid. + + This was reported as an actual grep test failure (without valgrind) on + 32-bit Arm, where glibc malloc happens to return a different buffer + address for the internal allocation (so that msg3 != msg4). + + test-strerror_r has the same issue. + + Thanks, + Florian + +Upstream patch: + + https://git.sv.gnu.org/cgit/gnulib.git/commit/?id=175e0bc72808 + + From 175e0bc72808d564074c4adcc72aeadb74adfcc6 Mon Sep 17 00:00:00 2001 + From: Paul Eggert + Date: Thu, 27 Aug 2020 17:52:58 -0700 + Subject: [PATCH] perror, strerror_r: remove unportable tests + + Problem reported by Florian Weimer in: + https://lists.gnu.org/r/bug-gnulib/2020-08/msg00220.html + * tests/test-perror2.c (main): + * tests/test-strerror_r.c (main): Omit unportable tests. + +This downstream patch is identical to upstream one modulo the ChangeLog entry. +--- + gnulib-tests/test-perror2.c | 3 --- + gnulib-tests/test-strerror_r.c | 3 --- + 2 files changed, 6 deletions(-) + +Index: gnulib-tests/test-perror2.c +=================================================================== +--- gnulib-tests/test-perror2.c.orig ++++ gnulib-tests/test-perror2.c +@@ -79,9 +79,6 @@ main (void) + errno = -5; + perror (""); + ASSERT (!ferror (stderr)); +- ASSERT (msg1 == msg2 || msg1 == msg4 || STREQ (msg1, str1)); +- ASSERT (msg2 == msg4 || STREQ (msg2, str2)); +- ASSERT (msg3 == msg4 || STREQ (msg3, str3)); + ASSERT (STREQ (msg4, str4)); + + free (str1); +Index: gnulib-tests/test-strerror_r.c +=================================================================== +--- gnulib-tests/test-strerror_r.c.orig ++++ gnulib-tests/test-strerror_r.c +@@ -165,9 +165,6 @@ main (void) + + strerror_r (EACCES, buf, sizeof buf); + strerror_r (-5, buf, sizeof buf); +- ASSERT (msg1 == msg2 || msg1 == msg4 || STREQ (msg1, str1)); +- ASSERT (msg2 == msg4 || STREQ (msg2, str2)); +- ASSERT (msg3 == msg4 || STREQ (msg3, str3)); + ASSERT (STREQ (msg4, str4)); + + free (str1);